@base44-preview/cli 0.1.7-pr.559.5a2a04e → 0.1.7-pr.559.78ee229

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 CHANGED
@@ -23352,15 +23352,15 @@ var require_windows = __commonJS((exports, module) => {
23352
23352
  }
23353
23353
  return false;
23354
23354
  }
23355
- function checkStat(stat, path11, options) {
23356
- if (!stat.isSymbolicLink() && !stat.isFile()) {
23355
+ function checkStat(stat3, path11, options) {
23356
+ if (!stat3.isSymbolicLink() && !stat3.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, stat) {
23363
- cb(er, er ? false : checkStat(stat, path11, options));
23362
+ fs14.stat(path11, function(er, stat3) {
23363
+ cb(er, er ? false : checkStat(stat3, 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, stat) {
23378
- cb(er, er ? false : checkStat(stat, options));
23377
+ fs14.stat(path11, function(er, stat3) {
23378
+ cb(er, er ? false : checkStat(stat3, options));
23379
23379
  });
23380
23380
  }
23381
23381
  function sync(path11, options) {
23382
23382
  return checkStat(fs14.statSync(path11), options);
23383
23383
  }
23384
- function checkStat(stat, options) {
23385
- return stat.isFile() && checkMode(stat, options);
23384
+ function checkStat(stat3, options) {
23385
+ return stat3.isFile() && checkMode(stat3, options);
23386
23386
  }
23387
- function checkMode(stat, options) {
23388
- var mod = stat.mode;
23389
- var uid = stat.uid;
23390
- var gid = stat.gid;
23387
+ function checkMode(stat3, options) {
23388
+ var mod = stat3.mode;
23389
+ var uid = stat3.uid;
23390
+ var gid = stat3.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(resolve4, reject) {
23422
+ return new Promise(function(resolve5, reject) {
23423
23423
  isexe(path11, options || {}, function(er, is) {
23424
23424
  if (er) {
23425
23425
  reject(er);
23426
23426
  } else {
23427
- resolve4(is);
23427
+ resolve5(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((resolve4, reject) => {
23489
+ const step = (i) => new Promise((resolve5, reject) => {
23490
23490
  if (i === pathEnv.length)
23491
- return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
23491
+ return opt.all && found.length ? resolve5(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
- resolve4(subStep(p, i, 0));
23496
+ resolve5(subStep(p, i, 0));
23497
23497
  });
23498
- const subStep = (p, i, ii) => new Promise((resolve4, reject) => {
23498
+ const subStep = (p, i, ii) => new Promise((resolve5, reject) => {
23499
23499
  if (ii === pathExt.length)
23500
- return resolve4(step(i + 1));
23500
+ return resolve5(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 resolve4(p + ext);
23507
+ return resolve5(p + ext);
23508
23508
  }
23509
- return resolve4(subStep(p, i, ii + 1));
23509
+ return resolve5(subStep(p, i, ii + 1));
23510
23510
  });
23511
23511
  });
23512
23512
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -27034,7 +27034,7 @@ var require_lodash8 = __commonJS((exports, module) => {
27034
27034
  }
27035
27035
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
27036
27036
  });
27037
- function join15(array2, separator) {
27037
+ function join18(array2, separator) {
27038
27038
  return array2 == null ? "" : nativeJoin.call(array2, separator);
27039
27039
  }
27040
27040
  function last(array2) {
@@ -28966,7 +28966,7 @@ __p += '`;
28966
28966
  lodash.isUndefined = isUndefined;
28967
28967
  lodash.isWeakMap = isWeakMap;
28968
28968
  lodash.isWeakSet = isWeakSet;
28969
- lodash.join = join15;
28969
+ lodash.join = join18;
28970
28970
  lodash.kebabCase = kebabCase;
28971
28971
  lodash.last = last;
28972
28972
  lodash.lastIndexOf = lastIndexOf;
@@ -31176,7 +31176,7 @@ function cleanDoc(doc2) {
31176
31176
  return mapDoc(doc2, (currentDoc) => cleanDocFn(currentDoc));
31177
31177
  }
31178
31178
  function replaceEndOfLine(doc2, replacement = literalline) {
31179
- return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ? join26(replacement, currentDoc.split(`
31179
+ return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ? join27(replacement, currentDoc.split(`
31180
31180
  `)) : currentDoc);
31181
31181
  }
31182
31182
  function canBreakFn(doc2) {
@@ -31256,7 +31256,7 @@ function indentIfBreak(contents, options) {
31256
31256
  negate: options.negate
31257
31257
  };
31258
31258
  }
31259
- function join26(separator, docs) {
31259
+ function join27(separator, docs) {
31260
31260
  assertDoc(separator);
31261
31261
  assertDocArray(docs);
31262
31262
  const parts = [];
@@ -31967,7 +31967,7 @@ var init_doc = __esm(() => {
31967
31967
  MODE_FLAT = Symbol("MODE_FLAT");
31968
31968
  DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
31969
31969
  builders = {
31970
- join: join26,
31970
+ join: join27,
31971
31971
  line,
31972
31972
  softline,
31973
31973
  hardline,
@@ -120896,7 +120896,7 @@ function parse42(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
120896
120896
  }
120897
120897
  return res;
120898
120898
  }
120899
- async function readFile6(file2) {
120899
+ async function readFile7(file2) {
120900
120900
  if (isUrlString(file2)) {
120901
120901
  file2 = new URL(file2);
120902
120902
  }
@@ -134690,7 +134690,7 @@ ${codeblock}`, options8);
134690
134690
  "\\": "\\"
134691
134691
  };
134692
134692
  KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
134693
- read_file_default = readFile6;
134693
+ read_file_default = readFile7;
134694
134694
  loadConfigFromPackageJson = process.versions.bun ? async function loadConfigFromBunPackageJson(file2) {
134695
134695
  const { prettier } = await readBunPackageJson(file2);
134696
134696
  return prettier;
@@ -136881,7 +136881,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
136881
136881
  return mapDoc2(doc2, (currentDoc) => cleanDocFn2(currentDoc));
136882
136882
  }
136883
136883
  function replaceEndOfLine2(doc2, replacement = literalline2) {
136884
- return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ? join28(replacement, currentDoc.split(`
136884
+ return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ? join29(replacement, currentDoc.split(`
136885
136885
  `)) : currentDoc);
136886
136886
  }
136887
136887
  function canBreakFn2(doc2) {
@@ -136967,7 +136967,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
136967
136967
  negate: options8.negate
136968
136968
  };
136969
136969
  }
136970
- function join28(separator, docs) {
136970
+ function join29(separator, docs) {
136971
136971
  assertDoc2(separator);
136972
136972
  assertDocArray2(docs);
136973
136973
  const parts = [];
@@ -137632,7 +137632,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
137632
137632
  }
137633
137633
  }
137634
137634
  var builders2 = {
137635
- join: join28,
137635
+ join: join29,
137636
137636
  line: line3,
137637
137637
  softline: softline2,
137638
137638
  hardline: hardline4,
@@ -138287,11 +138287,11 @@ var require_prettier = __commonJS((exports, module) => {
138287
138287
  var require_formatter = __commonJS((exports) => {
138288
138288
  var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P9, generator) {
138289
138289
  function adopt(value) {
138290
- return value instanceof P9 ? value : new P9(function(resolve16) {
138291
- resolve16(value);
138290
+ return value instanceof P9 ? value : new P9(function(resolve15) {
138291
+ resolve15(value);
138292
138292
  });
138293
138293
  }
138294
- return new (P9 || (P9 = Promise))(function(resolve16, reject) {
138294
+ return new (P9 || (P9 = Promise))(function(resolve15, reject) {
138295
138295
  function fulfilled(value) {
138296
138296
  try {
138297
138297
  step(generator.next(value));
@@ -138307,7 +138307,7 @@ var require_formatter = __commonJS((exports) => {
138307
138307
  }
138308
138308
  }
138309
138309
  function step(result) {
138310
- result.done ? resolve16(result.value) : adopt(result.value).then(fulfilled, rejected);
138310
+ result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected);
138311
138311
  }
138312
138312
  step((generator = generator.apply(thisArg, _arguments || [])).next());
138313
138313
  });
@@ -142960,7 +142960,7 @@ var require_url = __commonJS((exports) => {
142960
142960
  };
142961
142961
  Object.defineProperty(exports, "__esModule", { value: true });
142962
142962
  exports.parse = undefined;
142963
- exports.resolve = resolve16;
142963
+ exports.resolve = resolve15;
142964
142964
  exports.cwd = cwd;
142965
142965
  exports.getProtocol = getProtocol;
142966
142966
  exports.getExtension = getExtension;
@@ -142988,7 +142988,7 @@ var require_url = __commonJS((exports) => {
142988
142988
  var urlDecodePatterns = [/%23/g, "#", /%24/g, "$", /%26/g, "&", /%2C/g, ",", /%40/g, "@"];
142989
142989
  var parse11 = (u4) => new URL(u4);
142990
142990
  exports.parse = parse11;
142991
- function resolve16(from, to5) {
142991
+ function resolve15(from, to5) {
142992
142992
  const fromUrl = new URL((0, convert_path_to_posix_1.default)(from), "https://aaa.nonexistanturl.com");
142993
142993
  const resolvedUrl = new URL((0, convert_path_to_posix_1.default)(to5), fromUrl);
142994
142994
  const endSpaces = to5.match(/(\s*)$/)?.[1] || "";
@@ -143124,7 +143124,7 @@ var require_url = __commonJS((exports) => {
143124
143124
  }
143125
143125
  function relative5(from, to5) {
143126
143126
  if (!isFileSystemPath(from) || !isFileSystemPath(to5)) {
143127
- return resolve16(from, to5);
143127
+ return resolve15(from, to5);
143128
143128
  }
143129
143129
  const fromDir = path_1.default.dirname(stripHash(from));
143130
143130
  const toPath4 = stripHash(to5);
@@ -143800,7 +143800,7 @@ var require_plugins = __commonJS((exports) => {
143800
143800
  let plugin;
143801
143801
  let lastError;
143802
143802
  let index = 0;
143803
- return new Promise((resolve16, reject) => {
143803
+ return new Promise((resolve15, reject) => {
143804
143804
  runNextPlugin();
143805
143805
  function runNextPlugin() {
143806
143806
  plugin = plugins[index++];
@@ -143828,7 +143828,7 @@ var require_plugins = __commonJS((exports) => {
143828
143828
  }
143829
143829
  }
143830
143830
  function onSuccess(result) {
143831
- resolve16({
143831
+ resolve15({
143832
143832
  plugin,
143833
143833
  result
143834
143834
  });
@@ -143925,7 +143925,7 @@ var require_parse7 = __commonJS((exports) => {
143925
143925
  extension: url3.getExtension(path18)
143926
143926
  };
143927
143927
  try {
143928
- const resolver = await readFile7(file2, options8, $refs);
143928
+ const resolver = await readFile8(file2, options8, $refs);
143929
143929
  $ref.pathType = resolver.plugin.name;
143930
143930
  file2.data = resolver.result;
143931
143931
  const parser2 = await parseFile(file2, options8, $refs);
@@ -143938,7 +143938,7 @@ var require_parse7 = __commonJS((exports) => {
143938
143938
  throw err;
143939
143939
  }
143940
143940
  }
143941
- async function readFile7(file2, options8, $refs) {
143941
+ async function readFile8(file2, options8, $refs) {
143942
143942
  let resolvers = plugins.all(options8.resolve);
143943
143943
  resolvers = plugins.filter(resolvers, "canRead", file2);
143944
143944
  plugins.sort(resolvers);
@@ -145161,11 +145161,11 @@ var require_lib3 = __commonJS((exports) => {
145161
145161
  var require_resolver = __commonJS((exports) => {
145162
145162
  var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P9, generator) {
145163
145163
  function adopt(value) {
145164
- return value instanceof P9 ? value : new P9(function(resolve16) {
145165
- resolve16(value);
145164
+ return value instanceof P9 ? value : new P9(function(resolve15) {
145165
+ resolve15(value);
145166
145166
  });
145167
145167
  }
145168
- return new (P9 || (P9 = Promise))(function(resolve16, reject) {
145168
+ return new (P9 || (P9 = Promise))(function(resolve15, reject) {
145169
145169
  function fulfilled(value) {
145170
145170
  try {
145171
145171
  step(generator.next(value));
@@ -145181,7 +145181,7 @@ var require_resolver = __commonJS((exports) => {
145181
145181
  }
145182
145182
  }
145183
145183
  function step(result) {
145184
- result.done ? resolve16(result.value) : adopt(result.value).then(fulfilled, rejected);
145184
+ result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected);
145185
145185
  }
145186
145186
  step((generator = generator.apply(thisArg, _arguments || [])).next());
145187
145187
  });
@@ -145302,11 +145302,11 @@ var require_optionValidator = __commonJS((exports) => {
145302
145302
  var require_src3 = __commonJS((exports) => {
145303
145303
  var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P9, generator) {
145304
145304
  function adopt(value) {
145305
- return value instanceof P9 ? value : new P9(function(resolve16) {
145306
- resolve16(value);
145305
+ return value instanceof P9 ? value : new P9(function(resolve15) {
145306
+ resolve15(value);
145307
145307
  });
145308
145308
  }
145309
- return new (P9 || (P9 = Promise))(function(resolve16, reject) {
145309
+ return new (P9 || (P9 = Promise))(function(resolve15, reject) {
145310
145310
  function fulfilled(value) {
145311
145311
  try {
145312
145312
  step(generator.next(value));
@@ -145322,7 +145322,7 @@ var require_src3 = __commonJS((exports) => {
145322
145322
  }
145323
145323
  }
145324
145324
  function step(result) {
145325
- result.done ? resolve16(result.value) : adopt(result.value).then(fulfilled, rejected);
145325
+ result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected);
145326
145326
  }
145327
145327
  step((generator = generator.apply(thisArg, _arguments || [])).next());
145328
145328
  });
@@ -150984,11 +150984,11 @@ var require_raw_body = __commonJS((exports, module) => {
150984
150984
  if (done) {
150985
150985
  return readStream(stream, encoding, length, limit, wrap(done));
150986
150986
  }
150987
- return new Promise(function executor(resolve16, reject) {
150987
+ return new Promise(function executor(resolve15, reject) {
150988
150988
  readStream(stream, encoding, length, limit, function onRead2(err, buf) {
150989
150989
  if (err)
150990
150990
  return reject(err);
150991
- resolve16(buf);
150991
+ resolve15(buf);
150992
150992
  });
150993
150993
  });
150994
150994
  }
@@ -164112,8 +164112,8 @@ var require_view = __commonJS((exports, module) => {
164112
164112
  var dirname21 = path18.dirname;
164113
164113
  var basename6 = path18.basename;
164114
164114
  var extname3 = path18.extname;
164115
- var join29 = path18.join;
164116
- var resolve16 = path18.resolve;
164115
+ var join30 = path18.join;
164116
+ var resolve15 = path18.resolve;
164117
164117
  module.exports = View;
164118
164118
  function View(name2, options8) {
164119
164119
  var opts = options8 || {};
@@ -164147,7 +164147,7 @@ var require_view = __commonJS((exports, module) => {
164147
164147
  debug('lookup "%s"', name2);
164148
164148
  for (var i5 = 0;i5 < roots.length && !path19; i5++) {
164149
164149
  var root2 = roots[i5];
164150
- var loc = resolve16(root2, name2);
164150
+ var loc = resolve15(root2, name2);
164151
164151
  var dir = dirname21(loc);
164152
164152
  var file2 = basename6(loc);
164153
164153
  path19 = this.resolve(dir, file2);
@@ -164172,14 +164172,14 @@ var require_view = __commonJS((exports, module) => {
164172
164172
  });
164173
164173
  sync = false;
164174
164174
  };
164175
- View.prototype.resolve = function resolve17(dir, file2) {
164175
+ View.prototype.resolve = function resolve16(dir, file2) {
164176
164176
  var ext = this.ext;
164177
- var path19 = join29(dir, file2);
164177
+ var path19 = join30(dir, file2);
164178
164178
  var stat4 = tryStat(path19);
164179
164179
  if (stat4 && stat4.isFile()) {
164180
164180
  return path19;
164181
164181
  }
164182
- path19 = join29(dir, basename6(file2, ext), "index" + ext);
164182
+ path19 = join30(dir, basename6(file2, ext), "index" + ext);
164183
164183
  stat4 = tryStat(path19);
164184
164184
  if (stat4 && stat4.isFile()) {
164185
164185
  return path19;
@@ -166331,7 +166331,7 @@ var require_application = __commonJS((exports, module) => {
166331
166331
  var compileETag = require_utils10().compileETag;
166332
166332
  var compileQueryParser = require_utils10().compileQueryParser;
166333
166333
  var compileTrust = require_utils10().compileTrust;
166334
- var resolve16 = __require("node:path").resolve;
166334
+ var resolve15 = __require("node:path").resolve;
166335
166335
  var once9 = require_once();
166336
166336
  var Router = require_router();
166337
166337
  var slice = Array.prototype.slice;
@@ -166385,7 +166385,7 @@ var require_application = __commonJS((exports, module) => {
166385
166385
  this.mountpath = "/";
166386
166386
  this.locals.settings = this.settings;
166387
166387
  this.set("view", View);
166388
- this.set("views", resolve16("views"));
166388
+ this.set("views", resolve15("views"));
166389
166389
  this.set("jsonp callback name", "callback");
166390
166390
  if (env4 === "production") {
166391
166391
  this.enable("view cache");
@@ -167874,9 +167874,9 @@ var require_send = __commonJS((exports, module) => {
167874
167874
  var Stream2 = __require("stream");
167875
167875
  var util2 = __require("util");
167876
167876
  var extname3 = path18.extname;
167877
- var join29 = path18.join;
167877
+ var join30 = path18.join;
167878
167878
  var normalize2 = path18.normalize;
167879
- var resolve16 = path18.resolve;
167879
+ var resolve15 = path18.resolve;
167880
167880
  var sep2 = path18.sep;
167881
167881
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
167882
167882
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000;
@@ -167905,7 +167905,7 @@ var require_send = __commonJS((exports, module) => {
167905
167905
  this._maxage = opts.maxAge || opts.maxage;
167906
167906
  this._maxage = typeof this._maxage === "string" ? ms9(this._maxage) : Number(this._maxage);
167907
167907
  this._maxage = !isNaN(this._maxage) ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0;
167908
- this._root = opts.root ? resolve16(opts.root) : null;
167908
+ this._root = opts.root ? resolve15(opts.root) : null;
167909
167909
  }
167910
167910
  util2.inherits(SendStream, Stream2);
167911
167911
  SendStream.prototype.error = function error48(status, err) {
@@ -168046,7 +168046,7 @@ var require_send = __commonJS((exports, module) => {
168046
168046
  return res;
168047
168047
  }
168048
168048
  parts = path19.split(sep2);
168049
- path19 = normalize2(join29(root2, path19));
168049
+ path19 = normalize2(join30(root2, path19));
168050
168050
  } else {
168051
168051
  if (UP_PATH_REGEXP.test(path19)) {
168052
168052
  debug('malicious path "%s"', path19);
@@ -168054,7 +168054,7 @@ var require_send = __commonJS((exports, module) => {
168054
168054
  return res;
168055
168055
  }
168056
168056
  parts = normalize2(path19).split(sep2);
168057
- path19 = resolve16(path19);
168057
+ path19 = resolve15(path19);
168058
168058
  }
168059
168059
  if (containsDotFile(parts)) {
168060
168060
  debug('%s dotfile "%s"', this._dotfiles, path19);
@@ -168186,7 +168186,7 @@ var require_send = __commonJS((exports, module) => {
168186
168186
  return self2.onStatError(err);
168187
168187
  return self2.error(404);
168188
168188
  }
168189
- var p4 = join29(path19, self2._index[i5]);
168189
+ var p4 = join30(path19, self2._index[i5]);
168190
168190
  debug('stat "%s"', p4);
168191
168191
  fs28.stat(p4, function(err2, stat4) {
168192
168192
  if (err2)
@@ -168382,7 +168382,7 @@ var require_response = __commonJS((exports, module) => {
168382
168382
  var cookie = require_cookie();
168383
168383
  var send = require_send();
168384
168384
  var extname3 = path18.extname;
168385
- var resolve16 = path18.resolve;
168385
+ var resolve15 = path18.resolve;
168386
168386
  var vary = require_vary();
168387
168387
  var { Buffer: Buffer7 } = __require("node:buffer");
168388
168388
  var res = Object.create(http.ServerResponse.prototype);
@@ -168591,7 +168591,7 @@ var require_response = __commonJS((exports, module) => {
168591
168591
  }
168592
168592
  opts = Object.create(opts);
168593
168593
  opts.headers = headers;
168594
- var fullPath = !opts.root ? resolve16(path19) : path19;
168594
+ var fullPath = !opts.root ? resolve15(path19) : path19;
168595
168595
  return this.sendFile(fullPath, opts, done);
168596
168596
  };
168597
168597
  res.contentType = res.type = function contentType(type) {
@@ -168852,7 +168852,7 @@ var require_serve_static = __commonJS((exports, module) => {
168852
168852
  var encodeUrl = require_encodeurl();
168853
168853
  var escapeHtml = require_escape_html();
168854
168854
  var parseUrl = require_parseurl();
168855
- var resolve16 = __require("path").resolve;
168855
+ var resolve15 = __require("path").resolve;
168856
168856
  var send = require_send();
168857
168857
  var url3 = __require("url");
168858
168858
  module.exports = serveStatic;
@@ -168871,7 +168871,7 @@ var require_serve_static = __commonJS((exports, module) => {
168871
168871
  throw new TypeError("option setHeaders must be function");
168872
168872
  }
168873
168873
  opts.maxage = opts.maxage || opts.maxAge || 0;
168874
- opts.root = resolve16(root2);
168874
+ opts.root = resolve15(root2);
168875
168875
  var onDirectory = redirect ? createRedirectDirectoryListener() : createNotFoundDirectoryListener();
168876
168876
  return function serveStatic2(req, res, next) {
168877
168877
  if (req.method !== "GET" && req.method !== "HEAD") {
@@ -172245,8 +172245,8 @@ var require_executor = __commonJS((exports, module) => {
172245
172245
  }
172246
172246
  resetBuffer() {
172247
172247
  this.buffer = new Waterfall;
172248
- this.buffer.chain(new Promise((resolve16) => {
172249
- this._triggerBuffer = resolve16;
172248
+ this.buffer.chain(new Promise((resolve15) => {
172249
+ this._triggerBuffer = resolve15;
172250
172250
  }));
172251
172251
  if (this.ready)
172252
172252
  this._triggerBuffer();
@@ -173266,7 +173266,7 @@ var require_storage = __commonJS((exports, module) => {
173266
173266
  throw e8;
173267
173267
  }
173268
173268
  };
173269
- var writeFileLinesAsync = (filename, lines, mode = DEFAULT_FILE_MODE) => new Promise((resolve16, reject) => {
173269
+ var writeFileLinesAsync = (filename, lines, mode = DEFAULT_FILE_MODE) => new Promise((resolve15, reject) => {
173270
173270
  try {
173271
173271
  const stream = writeFileStream(filename, { mode });
173272
173272
  const readable2 = Readable6.from(lines);
@@ -173283,7 +173283,7 @@ var require_storage = __commonJS((exports, module) => {
173283
173283
  if (err)
173284
173284
  reject(err);
173285
173285
  else
173286
- resolve16();
173286
+ resolve15();
173287
173287
  });
173288
173288
  });
173289
173289
  readable2.on("error", (err) => {
@@ -173454,7 +173454,7 @@ var require_persistence = __commonJS((exports, module) => {
173454
173454
  return { data: tdata, indexes };
173455
173455
  }
173456
173456
  treatRawStreamAsync(rawStream) {
173457
- return new Promise((resolve16, reject) => {
173457
+ return new Promise((resolve15, reject) => {
173458
173458
  const dataById = {};
173459
173459
  const indexes = {};
173460
173460
  let corruptItems = 0;
@@ -173497,7 +173497,7 @@ var require_persistence = __commonJS((exports, module) => {
173497
173497
  }
173498
173498
  }
173499
173499
  const data = Object.values(dataById);
173500
- resolve16({ data, indexes });
173500
+ resolve15({ data, indexes });
173501
173501
  });
173502
173502
  lineStream.on("error", function(err) {
173503
173503
  reject(err, null);
@@ -199108,13 +199108,13 @@ var require_broadcast_operator = __commonJS((exports) => {
199108
199108
  return true;
199109
199109
  }
199110
199110
  emitWithAck(ev2, ...args) {
199111
- return new Promise((resolve16, reject) => {
199111
+ return new Promise((resolve15, reject) => {
199112
199112
  args.push((err, responses) => {
199113
199113
  if (err) {
199114
199114
  err.responses = responses;
199115
199115
  return reject(err);
199116
199116
  } else {
199117
- return resolve16(responses);
199117
+ return resolve15(responses);
199118
199118
  }
199119
199119
  });
199120
199120
  this.emit(ev2, ...args);
@@ -199302,12 +199302,12 @@ var require_socket2 = __commonJS((exports) => {
199302
199302
  }
199303
199303
  emitWithAck(ev2, ...args) {
199304
199304
  const withErr = this.flags.timeout !== undefined;
199305
- return new Promise((resolve16, reject) => {
199305
+ return new Promise((resolve15, reject) => {
199306
199306
  args.push((arg1, arg2) => {
199307
199307
  if (withErr) {
199308
- return arg1 ? reject(arg1) : resolve16(arg2);
199308
+ return arg1 ? reject(arg1) : resolve15(arg2);
199309
199309
  } else {
199310
- return resolve16(arg1);
199310
+ return resolve15(arg1);
199311
199311
  }
199312
199312
  });
199313
199313
  this.emit(ev2, ...args);
@@ -199762,13 +199762,13 @@ var require_namespace = __commonJS((exports) => {
199762
199762
  return true;
199763
199763
  }
199764
199764
  serverSideEmitWithAck(ev2, ...args) {
199765
- return new Promise((resolve16, reject) => {
199765
+ return new Promise((resolve15, reject) => {
199766
199766
  args.push((err, responses) => {
199767
199767
  if (err) {
199768
199768
  err.responses = responses;
199769
199769
  return reject(err);
199770
199770
  } else {
199771
- return resolve16(responses);
199771
+ return resolve15(responses);
199772
199772
  }
199773
199773
  });
199774
199774
  this.serverSideEmit(ev2, ...args);
@@ -203303,7 +203303,7 @@ var require_cluster_adapter = __commonJS((exports) => {
203303
203303
  return localSockets;
203304
203304
  }
203305
203305
  const requestId = randomId();
203306
- return new Promise((resolve16, reject) => {
203306
+ return new Promise((resolve15, reject) => {
203307
203307
  const timeout3 = setTimeout(() => {
203308
203308
  const storedRequest2 = this.requests.get(requestId);
203309
203309
  if (storedRequest2) {
@@ -203313,7 +203313,7 @@ var require_cluster_adapter = __commonJS((exports) => {
203313
203313
  }, opts.flags.timeout || DEFAULT_TIMEOUT);
203314
203314
  const storedRequest = {
203315
203315
  type: MessageType.FETCH_SOCKETS,
203316
- resolve: resolve16,
203316
+ resolve: resolve15,
203317
203317
  timeout: timeout3,
203318
203318
  current: 0,
203319
203319
  expected: expectedResponseCount,
@@ -203523,7 +203523,7 @@ var require_cluster_adapter = __commonJS((exports) => {
203523
203523
  return localSockets;
203524
203524
  }
203525
203525
  const requestId = randomId();
203526
- return new Promise((resolve16, reject) => {
203526
+ return new Promise((resolve15, reject) => {
203527
203527
  const timeout3 = setTimeout(() => {
203528
203528
  const storedRequest2 = this.customRequests.get(requestId);
203529
203529
  if (storedRequest2) {
@@ -203533,7 +203533,7 @@ var require_cluster_adapter = __commonJS((exports) => {
203533
203533
  }, opts.flags.timeout || DEFAULT_TIMEOUT);
203534
203534
  const storedRequest = {
203535
203535
  type: MessageType.FETCH_SOCKETS,
203536
- resolve: resolve16,
203536
+ resolve: resolve15,
203537
203537
  timeout: timeout3,
203538
203538
  missingUids: new Set([...this.nodesMap.keys()]),
203539
203539
  responses: localSockets
@@ -204262,13 +204262,13 @@ var require_dist4 = __commonJS((exports, module) => {
204262
204262
  this.engine.close();
204263
204263
  (0, uws_1.restoreAdapter)();
204264
204264
  if (this.httpServer) {
204265
- return new Promise((resolve16) => {
204265
+ return new Promise((resolve15) => {
204266
204266
  this.httpServer.close((err) => {
204267
204267
  fn9 && fn9(err);
204268
204268
  if (err) {
204269
204269
  debug("server was not running");
204270
204270
  }
204271
- resolve16();
204271
+ resolve15();
204272
204272
  });
204273
204273
  });
204274
204274
  } else {
@@ -217632,7 +217632,7 @@ var require_buffer_list = __commonJS((exports, module) => {
217632
217632
  }
217633
217633
  }, {
217634
217634
  key: "join",
217635
- value: function join31(s5) {
217635
+ value: function join33(s5) {
217636
217636
  if (this.length === 0)
217637
217637
  return "";
217638
217638
  var p4 = this.head;
@@ -218930,14 +218930,14 @@ var require_async_iterator = __commonJS((exports, module) => {
218930
218930
  };
218931
218931
  }
218932
218932
  function readAndResolve(iter) {
218933
- var resolve16 = iter[kLastResolve];
218934
- if (resolve16 !== null) {
218933
+ var resolve15 = iter[kLastResolve];
218934
+ if (resolve15 !== null) {
218935
218935
  var data = iter[kStream].read();
218936
218936
  if (data !== null) {
218937
218937
  iter[kLastPromise] = null;
218938
218938
  iter[kLastResolve] = null;
218939
218939
  iter[kLastReject] = null;
218940
- resolve16(createIterResult(data, false));
218940
+ resolve15(createIterResult(data, false));
218941
218941
  }
218942
218942
  }
218943
218943
  }
@@ -218945,13 +218945,13 @@ var require_async_iterator = __commonJS((exports, module) => {
218945
218945
  process.nextTick(readAndResolve, iter);
218946
218946
  }
218947
218947
  function wrapForNext(lastPromise, iter) {
218948
- return function(resolve16, reject) {
218948
+ return function(resolve15, reject) {
218949
218949
  lastPromise.then(function() {
218950
218950
  if (iter[kEnded]) {
218951
- resolve16(createIterResult(undefined, true));
218951
+ resolve15(createIterResult(undefined, true));
218952
218952
  return;
218953
218953
  }
218954
- iter[kHandlePromise](resolve16, reject);
218954
+ iter[kHandlePromise](resolve15, reject);
218955
218955
  }, reject);
218956
218956
  };
218957
218957
  }
@@ -218970,12 +218970,12 @@ var require_async_iterator = __commonJS((exports, module) => {
218970
218970
  return Promise.resolve(createIterResult(undefined, true));
218971
218971
  }
218972
218972
  if (this[kStream].destroyed) {
218973
- return new Promise(function(resolve16, reject) {
218973
+ return new Promise(function(resolve15, reject) {
218974
218974
  process.nextTick(function() {
218975
218975
  if (_this[kError]) {
218976
218976
  reject(_this[kError]);
218977
218977
  } else {
218978
- resolve16(createIterResult(undefined, true));
218978
+ resolve15(createIterResult(undefined, true));
218979
218979
  }
218980
218980
  });
218981
218981
  });
@@ -218998,13 +218998,13 @@ var require_async_iterator = __commonJS((exports, module) => {
218998
218998
  return this;
218999
218999
  }), _defineProperty(_Object$setPrototypeO, "return", function _return() {
219000
219000
  var _this2 = this;
219001
- return new Promise(function(resolve16, reject) {
219001
+ return new Promise(function(resolve15, reject) {
219002
219002
  _this2[kStream].destroy(null, function(err) {
219003
219003
  if (err) {
219004
219004
  reject(err);
219005
219005
  return;
219006
219006
  }
219007
- resolve16(createIterResult(undefined, true));
219007
+ resolve15(createIterResult(undefined, true));
219008
219008
  });
219009
219009
  });
219010
219010
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
@@ -219026,15 +219026,15 @@ var require_async_iterator = __commonJS((exports, module) => {
219026
219026
  value: stream._readableState.endEmitted,
219027
219027
  writable: true
219028
219028
  }), _defineProperty(_Object$create, kHandlePromise, {
219029
- value: function value(resolve16, reject) {
219029
+ value: function value(resolve15, reject) {
219030
219030
  var data = iterator[kStream].read();
219031
219031
  if (data) {
219032
219032
  iterator[kLastPromise] = null;
219033
219033
  iterator[kLastResolve] = null;
219034
219034
  iterator[kLastReject] = null;
219035
- resolve16(createIterResult(data, false));
219035
+ resolve15(createIterResult(data, false));
219036
219036
  } else {
219037
- iterator[kLastResolve] = resolve16;
219037
+ iterator[kLastResolve] = resolve15;
219038
219038
  iterator[kLastReject] = reject;
219039
219039
  }
219040
219040
  },
@@ -219053,12 +219053,12 @@ var require_async_iterator = __commonJS((exports, module) => {
219053
219053
  iterator[kError] = err;
219054
219054
  return;
219055
219055
  }
219056
- var resolve16 = iterator[kLastResolve];
219057
- if (resolve16 !== null) {
219056
+ var resolve15 = iterator[kLastResolve];
219057
+ if (resolve15 !== null) {
219058
219058
  iterator[kLastPromise] = null;
219059
219059
  iterator[kLastResolve] = null;
219060
219060
  iterator[kLastReject] = null;
219061
- resolve16(createIterResult(undefined, true));
219061
+ resolve15(createIterResult(undefined, true));
219062
219062
  }
219063
219063
  iterator[kEnded] = true;
219064
219064
  });
@@ -219070,7 +219070,7 @@ var require_async_iterator = __commonJS((exports, module) => {
219070
219070
 
219071
219071
  // ../../node_modules/readable-stream/lib/internal/streams/from.js
219072
219072
  var require_from = __commonJS((exports, module) => {
219073
- function asyncGeneratorStep(gen, resolve16, reject, _next, _throw, key2, arg) {
219073
+ function asyncGeneratorStep(gen, resolve15, reject, _next, _throw, key2, arg) {
219074
219074
  try {
219075
219075
  var info = gen[key2](arg);
219076
219076
  var value = info.value;
@@ -219079,7 +219079,7 @@ var require_from = __commonJS((exports, module) => {
219079
219079
  return;
219080
219080
  }
219081
219081
  if (info.done) {
219082
- resolve16(value);
219082
+ resolve15(value);
219083
219083
  } else {
219084
219084
  Promise.resolve(value).then(_next, _throw);
219085
219085
  }
@@ -219087,13 +219087,13 @@ var require_from = __commonJS((exports, module) => {
219087
219087
  function _asyncToGenerator(fn9) {
219088
219088
  return function() {
219089
219089
  var self2 = this, args = arguments;
219090
- return new Promise(function(resolve16, reject) {
219090
+ return new Promise(function(resolve15, reject) {
219091
219091
  var gen = fn9.apply(self2, args);
219092
219092
  function _next(value) {
219093
- asyncGeneratorStep(gen, resolve16, reject, _next, _throw, "next", value);
219093
+ asyncGeneratorStep(gen, resolve15, reject, _next, _throw, "next", value);
219094
219094
  }
219095
219095
  function _throw(err) {
219096
- asyncGeneratorStep(gen, resolve16, reject, _next, _throw, "throw", err);
219096
+ asyncGeneratorStep(gen, resolve15, reject, _next, _throw, "throw", err);
219097
219097
  }
219098
219098
  _next(undefined);
219099
219099
  });
@@ -221220,7 +221220,7 @@ var require_dist5 = __commonJS((exports, module) => {
221220
221220
  determineAgent: () => determineAgent
221221
221221
  });
221222
221222
  module.exports = __toCommonJS2(src_exports);
221223
- var import_promises26 = __require("node:fs/promises");
221223
+ var import_promises27 = __require("node:fs/promises");
221224
221224
  var import_node_fs24 = __require("node:fs");
221225
221225
  var DEVIN_LOCAL_PATH = "/opt/.devin";
221226
221226
  var CURSOR2 = "cursor";
@@ -221278,7 +221278,7 @@ var require_dist5 = __commonJS((exports, module) => {
221278
221278
  return { isAgent: true, agent: { name: REPLIT } };
221279
221279
  }
221280
221280
  try {
221281
- await (0, import_promises26.access)(DEVIN_LOCAL_PATH, import_node_fs24.constants.F_OK);
221281
+ await (0, import_promises27.access)(DEVIN_LOCAL_PATH, import_node_fs24.constants.F_OK);
221282
221282
  return { isAgent: true, agent: { name: DEVIN } };
221283
221283
  } catch (error48) {}
221284
221284
  return { isAgent: false, agent: undefined };
@@ -237053,7 +237053,7 @@ function normalizeBase44Env() {
237053
237053
  loadProjectEnvFiles();
237054
237054
 
237055
237055
  // src/cli/index.ts
237056
- import { dirname as dirname26, join as join36 } from "node:path";
237056
+ import { dirname as dirname26, join as join37 } from "node:path";
237057
237057
  import { fileURLToPath as fileURLToPath6 } from "node:url";
237058
237058
 
237059
237059
  // ../../node_modules/@clack/core/dist/index.mjs
@@ -238261,7 +238261,7 @@ var {
238261
238261
  } = import__.default;
238262
238262
 
238263
238263
  // src/cli/commands/agent-skills/pull.ts
238264
- import { dirname as dirname11, join as join17 } from "node:path";
238264
+ import { dirname as dirname11, join as join18 } from "node:path";
238265
238265
  // ../../node_modules/chalk/source/vendor/ansi-styles/index.js
238266
238266
  var ANSI_BACKGROUND_OFFSET = 10;
238267
238267
  var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
@@ -247443,7 +247443,7 @@ async function createProjectFilesForExistingProject(options) {
247443
247443
  };
247444
247444
  }
247445
247445
  // src/core/project/deploy.ts
247446
- import { resolve as resolve3 } from "node:path";
247446
+ import { resolve as resolve6 } from "node:path";
247447
247447
 
247448
247448
  // src/core/site/api.ts
247449
247449
  async function uploadSite(archivePath) {
@@ -247510,340 +247510,616 @@ async function createArchive(pathToArchive, targetArchivePath) {
247510
247510
  cwd: pathToArchive
247511
247511
  }, ["."]);
247512
247512
  }
247513
- // src/core/project/deploy.ts
247514
- function hasResourcesToDeploy(projectData) {
247515
- const {
247516
- project,
247517
- entities,
247518
- functions,
247519
- agents,
247520
- agentSkills,
247521
- connectors,
247522
- authConfig
247523
- } = projectData;
247524
- const hasSite = Boolean(project.site?.outputDirectory);
247525
- const hasEntities = entities.length > 0;
247526
- const hasFunctions = functions.length > 0;
247527
- const hasAgents = agents.length > 0;
247528
- const hasAgentSkills = agentSkills.length > 0;
247529
- const hasConnectors = connectors.length > 0;
247530
- const hasAuthConfig = authConfig.length > 0;
247531
- const hasVisibility = Boolean(project.visibility);
247532
- return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
247533
- }
247534
- async function deployAll(projectData, options) {
247535
- const {
247536
- project,
247537
- entities,
247538
- functions,
247539
- agents,
247540
- agentSkills,
247541
- connectors,
247542
- authConfig
247543
- } = projectData;
247544
- await setAppVisibility(project.visibility);
247545
- if (project.visibility) {
247546
- options?.onVisibilitySet?.(project.visibility);
247513
+ // src/core/site/deploy-app.ts
247514
+ import { resolve as resolve5 } from "node:path";
247515
+
247516
+ // src/core/deployments/api.ts
247517
+ import { readFile as readFile2 } from "node:fs/promises";
247518
+
247519
+ // src/core/deployments/schema.ts
247520
+ var GIT_HASH_PATTERN = /^[a-fA-F0-9]{7,64}$/;
247521
+ var CreateDeploymentResponseSchema = exports_external.object({
247522
+ deployment_id: exports_external.string(),
247523
+ asset_uploads: exports_external.discriminatedUnion("type", [
247524
+ exports_external.object({
247525
+ type: exports_external.literal("cf"),
247526
+ url: exports_external.string(),
247527
+ jwt: exports_external.string(),
247528
+ buckets: exports_external.array(exports_external.array(exports_external.string()))
247529
+ }),
247530
+ exports_external.object({
247531
+ type: exports_external.literal("s3"),
247532
+ uploads: exports_external.array(exports_external.object({
247533
+ path: exports_external.string(),
247534
+ content_type: exports_external.string(),
247535
+ content_length: exports_external.number(),
247536
+ url: exports_external.string()
247537
+ }))
247538
+ })
247539
+ ]).nullable().optional()
247540
+ }).transform((data) => ({
247541
+ deploymentId: data.deployment_id,
247542
+ assetUploads: data.asset_uploads == null ? null : data.asset_uploads.type === "cf" ? data.asset_uploads : {
247543
+ type: "s3",
247544
+ uploads: data.asset_uploads.uploads.map((upload) => ({
247545
+ path: upload.path,
247546
+ contentType: upload.content_type,
247547
+ contentLength: upload.content_length,
247548
+ url: upload.url
247549
+ }))
247547
247550
  }
247548
- await entityResource.push(entities);
247549
- await deployFunctionsSequentially(functions, {
247550
- onStart: options?.onFunctionStart,
247551
- onResult: options?.onFunctionResult
247552
- });
247553
- await agentSkillResource.push(agentSkills);
247554
- await agentResource.push(agents);
247555
- await authConfigResource.push(authConfig);
247556
- const skipConnectorSync = connectors.length === 0 && hasWorkspaceApiKeyAuth();
247557
- const connectorResults = skipConnectorSync ? [] : (await pushConnectors(connectors)).results;
247558
- if ((options?.site ?? true) && project.site?.outputDirectory) {
247559
- const outputDir = resolve3(project.root, project.site.outputDirectory);
247560
- const { appUrl } = await deploySite(outputDir);
247561
- return { appUrl, connectorResults };
247551
+ }));
247552
+ var AssetUploadResponseSchema = exports_external.looseObject({
247553
+ result: exports_external.looseObject({ jwt: exports_external.string().nullable().optional() }).nullable().optional()
247554
+ });
247555
+ var FinalizeDeploymentResponseSchema = exports_external.object({
247556
+ deployment_id: exports_external.string()
247557
+ }).transform((data) => ({
247558
+ deploymentId: data.deployment_id
247559
+ }));
247560
+
247561
+ // src/core/deployments/api.ts
247562
+ var MODULE_CONTENT_TYPES = {
247563
+ esm: "application/javascript+module",
247564
+ sourcemap: "application/source-map",
247565
+ wasm: "application/wasm",
247566
+ text: "text/plain",
247567
+ data: "application/octet-stream"
247568
+ };
247569
+ async function createDeployment(request) {
247570
+ const appClient = getAppClient();
247571
+ let response;
247572
+ try {
247573
+ response = await appClient.post("deployments", {
247574
+ json: request,
247575
+ timeout: 120000
247576
+ });
247577
+ } catch (error48) {
247578
+ throw await ApiError.fromHttpError(error48, "creating deployment");
247562
247579
  }
247563
- return { connectorResults };
247564
- }
247565
- // src/core/clients/base44-client.ts
247566
- var retriedRequests = new WeakSet;
247567
- async function captureRequestBody(request, options) {
247568
- if (request.body == null) {
247569
- return;
247580
+ const result = CreateDeploymentResponseSchema.safeParse(await response.json());
247581
+ if (!result.success) {
247582
+ throw new SchemaValidationError("Invalid response from server", result.error);
247570
247583
  }
247571
- try {
247572
- const cloned = request.clone();
247573
- const text = await cloned.text();
247574
- options.context.__requestBody = text;
247575
- } catch {}
247584
+ return result.data;
247576
247585
  }
247577
- async function handleUnauthorized(request, _options, response) {
247578
- if (response.status !== 401) {
247579
- return;
247580
- }
247581
- if (hasWorkspaceApiKeyAuth()) {
247582
- return;
247586
+ async function uploadAssetBucket(target, formData) {
247587
+ const response = await distribution_default.post(target.url, {
247588
+ searchParams: { base64: "true" },
247589
+ headers: { Authorization: `Bearer ${target.jwt}` },
247590
+ body: formData,
247591
+ timeout: 120000,
247592
+ retry: 0
247593
+ });
247594
+ const parsed = AssetUploadResponseSchema.safeParse(await response.json());
247595
+ const jwt3 = parsed.success ? parsed.data.result?.jwt : null;
247596
+ return jwt3 || null;
247597
+ }
247598
+ async function finalizeDeployment(deploymentId, completionJwt, modules) {
247599
+ const formData = new FormData;
247600
+ formData.append("payload", JSON.stringify({ completion_jwt: completionJwt }));
247601
+ for (const module of modules) {
247602
+ const content = await readFile2(module.absolutePath);
247603
+ formData.append(module.name, new File([new Uint8Array(content)], module.name, {
247604
+ type: MODULE_CONTENT_TYPES[module.type]
247605
+ }));
247583
247606
  }
247584
- if (retriedRequests.has(request)) {
247585
- return;
247607
+ return await postFinalize(deploymentId, formData);
247608
+ }
247609
+ async function finalizeStaticDeployment(deploymentId, indexHtml) {
247610
+ const formData = new FormData;
247611
+ formData.append("index.html", new File([indexHtml], "index.html", { type: "text/html" }));
247612
+ return await postFinalize(deploymentId, formData);
247613
+ }
247614
+ async function postFinalize(deploymentId, formData) {
247615
+ const appClient = getAppClient();
247616
+ let response;
247617
+ try {
247618
+ response = await appClient.post(`deployments/${encodeURIComponent(deploymentId)}/finalize`, { body: formData, timeout: 180000 });
247619
+ } catch (error48) {
247620
+ throw await ApiError.fromHttpError(error48, "finalizing deployment");
247586
247621
  }
247587
- const newAccessToken = await refreshAndSaveTokens();
247588
- if (!newAccessToken) {
247589
- return;
247622
+ const result = FinalizeDeploymentResponseSchema.safeParse(await response.json());
247623
+ if (!result.success) {
247624
+ throw new SchemaValidationError("Invalid response from server", result.error);
247590
247625
  }
247591
- retriedRequests.add(request);
247592
- const requestId = request.headers.get("X-Request-ID");
247593
- return distribution_default(request.clone(), {
247594
- headers: {
247595
- ...requestId && { "X-Request-ID": requestId },
247596
- Authorization: `Bearer ${newAccessToken}`
247597
- }
247598
- });
247626
+ return result.data;
247599
247627
  }
247600
- var base44Client = distribution_default.create({
247601
- prefixUrl: getBase44ApiUrl(),
247602
- headers: {
247603
- "User-Agent": "Base44 CLI"
247604
- },
247605
- hooks: {
247606
- beforeRequest: [
247607
- (request) => {
247608
- request.headers.set("X-Request-ID", randomUUID2());
247609
- },
247610
- captureRequestBody,
247611
- async (request) => {
247612
- const workspaceApiKey = getWorkspaceApiKeyFromEnv();
247613
- if (workspaceApiKey && isWorkspaceApiKey(workspaceApiKey)) {
247614
- request.headers.set("api_key", workspaceApiKey);
247615
- return;
247616
- }
247617
- try {
247618
- const auth = await readAuth();
247619
- if (isTokenExpired(auth)) {
247620
- const newAccessToken = await refreshAndSaveTokens();
247621
- if (newAccessToken) {
247622
- request.headers.set("Authorization", `Bearer ${newAccessToken}`);
247623
- return;
247624
- }
247625
- }
247626
- request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
247627
- } catch {}
247628
+ // src/core/deployments/manifest.ts
247629
+ import { createHash } from "node:crypto";
247630
+ import { readdir as readdir2, readFile as readFile3, stat } from "node:fs/promises";
247631
+ import { extname, join as join15 } from "node:path";
247632
+ var MAX_ASSET_SIZE_BYTES = 25 * 1024 * 1024;
247633
+ var MAX_ASSET_COUNT = 1e5;
247634
+ var ASSETS_IGNORE_FILE = ".assetsignore";
247635
+ var ALWAYS_SKIPPED_FILES = new Set([
247636
+ ASSETS_IGNORE_FILE,
247637
+ "wrangler.json",
247638
+ ".dev.vars"
247639
+ ]);
247640
+ var MIME_TYPES = {
247641
+ ".html": "text/html",
247642
+ ".htm": "text/html",
247643
+ ".css": "text/css",
247644
+ ".js": "text/javascript",
247645
+ ".mjs": "text/javascript",
247646
+ ".json": "application/json",
247647
+ ".map": "application/json",
247648
+ ".txt": "text/plain",
247649
+ ".xml": "application/xml",
247650
+ ".svg": "image/svg+xml",
247651
+ ".png": "image/png",
247652
+ ".jpg": "image/jpeg",
247653
+ ".jpeg": "image/jpeg",
247654
+ ".gif": "image/gif",
247655
+ ".webp": "image/webp",
247656
+ ".avif": "image/avif",
247657
+ ".ico": "image/x-icon",
247658
+ ".woff": "font/woff",
247659
+ ".woff2": "font/woff2",
247660
+ ".ttf": "font/ttf",
247661
+ ".otf": "font/otf",
247662
+ ".eot": "application/vnd.ms-fontobject",
247663
+ ".mp3": "audio/mpeg",
247664
+ ".mp4": "video/mp4",
247665
+ ".webm": "video/webm",
247666
+ ".pdf": "application/pdf",
247667
+ ".wasm": "application/wasm",
247668
+ ".webmanifest": "application/manifest+json"
247669
+ };
247670
+ function getAssetContentType(filePath) {
247671
+ return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
247672
+ }
247673
+ function hashAsset(appId, content) {
247674
+ return createHash("sha256").update(Buffer.from(appId, "utf8")).update(content).digest("hex").slice(0, 32);
247675
+ }
247676
+ function globToRegExp(glob) {
247677
+ let source = "";
247678
+ for (let i = 0;i < glob.length; i++) {
247679
+ const char = glob[i];
247680
+ if (char === "*") {
247681
+ if (glob[i + 1] === "*") {
247682
+ source += ".*";
247683
+ i++;
247684
+ } else {
247685
+ source += "[^/]*";
247628
247686
  }
247629
- ],
247630
- afterResponse: [handleUnauthorized]
247687
+ } else if (char === "?") {
247688
+ source += "[^/]";
247689
+ } else {
247690
+ source += char.replace(/[.+^${}()|[\]\\]/g, "\\$&");
247691
+ }
247631
247692
  }
247632
- });
247633
- function getAppClient() {
247634
- const { id } = getAppContext();
247635
- return base44Client.extend({
247636
- prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
247637
- });
247693
+ return new RegExp(`^${source}$`);
247638
247694
  }
247639
- function getSandboxClient(appId) {
247640
- return base44Client.extend({
247641
- prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
247695
+ function createIgnoreMatcher(lines) {
247696
+ const rules = lines.map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map((line) => {
247697
+ const isDirOnly = line.endsWith("/");
247698
+ let pattern = isDirOnly ? line.slice(0, -1) : line;
247699
+ const anchored = pattern.includes("/");
247700
+ pattern = pattern.replace(/^\//, "");
247701
+ return { regex: globToRegExp(pattern), anchored, isDirOnly };
247642
247702
  });
247643
- }
247644
- // src/core/clients/oauth-client.ts
247645
- import { randomUUID as randomUUID3 } from "node:crypto";
247646
- var oauthClient = distribution_default.create({
247647
- prefixUrl: getBase44ApiUrl(),
247648
- headers: {
247649
- "User-Agent": "Base44 CLI"
247650
- },
247651
- hooks: {
247652
- beforeRequest: [
247653
- (request) => {
247654
- request.headers.set("X-Request-ID", randomUUID3());
247703
+ return (relativePath, isDirectory2) => {
247704
+ const segments = relativePath.split("/");
247705
+ return rules.some((rule) => {
247706
+ if (rule.anchored) {
247707
+ if (rule.isDirOnly ? isDirectory2 : true) {
247708
+ if (rule.regex.test(relativePath))
247709
+ return true;
247710
+ }
247711
+ return false;
247655
247712
  }
247656
- ]
247713
+ const basename4 = segments[segments.length - 1];
247714
+ if (rule.isDirOnly && !isDirectory2)
247715
+ return false;
247716
+ return rule.regex.test(basename4);
247717
+ });
247718
+ };
247719
+ }
247720
+ async function loadIgnoreMatcher(assetsDir) {
247721
+ const ignorePath = join15(assetsDir, ASSETS_IGNORE_FILE);
247722
+ if (!await pathExists(ignorePath)) {
247723
+ return () => false;
247657
247724
  }
247658
- });
247659
- // src/core/auth/api.ts
247660
- async function generateDeviceCode() {
247661
- const response = await oauthClient.post("oauth/device/code", {
247662
- json: {
247663
- client_id: AUTH_CLIENT_ID,
247664
- scope: "apps:read apps:write sandbox:write"
247665
- },
247666
- throwHttpErrors: false
247667
- });
247668
- if (!response.ok) {
247669
- throw new ApiError(`Failed to generate device code: ${response.status} ${response.statusText}`, { statusCode: response.status });
247725
+ const content = await readTextFile(ignorePath);
247726
+ return createIgnoreMatcher(content.split(/\r?\n/));
247727
+ }
247728
+ async function buildAssetManifest(assetsDir, appId) {
247729
+ const isIgnored = await loadIgnoreMatcher(assetsDir);
247730
+ const manifest = {};
247731
+ const filesByHash = new Map;
247732
+ const relativeFilePaths = await collectFilePaths(assetsDir, "", isIgnored);
247733
+ if (relativeFilePaths.length > MAX_ASSET_COUNT) {
247734
+ throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
247670
247735
  }
247671
- const result = DeviceCodeResponseSchema.safeParse(await response.json());
247672
- if (!result.success) {
247673
- throw new SchemaValidationError("Invalid device code response from server", result.error);
247736
+ for (const relativePath of relativeFilePaths.sort()) {
247737
+ const absolutePath = join15(assetsDir, ...relativePath.split("/"));
247738
+ const { size } = await stat(absolutePath);
247739
+ if (size > MAX_ASSET_SIZE_BYTES) {
247740
+ throw new InvalidInputError(`Static asset "${relativePath}" is ${size} bytes, which exceeds the 25 MiB per-file limit.`);
247741
+ }
247742
+ const content = await readFile3(absolutePath);
247743
+ const hash2 = hashAsset(appId, content);
247744
+ manifest[`/${relativePath}`] = { hash: hash2, size };
247745
+ if (!filesByHash.has(hash2)) {
247746
+ filesByHash.set(hash2, {
247747
+ absolutePath,
247748
+ hash: hash2,
247749
+ size,
247750
+ contentType: getAssetContentType(absolutePath)
247751
+ });
247752
+ }
247674
247753
  }
247675
- return result.data;
247754
+ return { manifest, filesByHash };
247676
247755
  }
247677
- async function getTokenFromDeviceCode(deviceCode) {
247678
- const searchParams = new URLSearchParams;
247679
- searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
247680
- searchParams.set("device_code", deviceCode);
247681
- searchParams.set("client_id", AUTH_CLIENT_ID);
247682
- const response = await oauthClient.post("oauth/token", {
247683
- body: searchParams.toString(),
247684
- headers: {
247685
- "Content-Type": "application/x-www-form-urlencoded"
247686
- },
247687
- throwHttpErrors: false
247756
+ async function collectFilePaths(dir, relativeDir, isIgnored) {
247757
+ const entries = await readdir2(dir, { withFileTypes: true });
247758
+ const results = [];
247759
+ for (const entry of entries) {
247760
+ const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
247761
+ if (entry.isDirectory()) {
247762
+ if (isIgnored(relativePath, true))
247763
+ continue;
247764
+ results.push(...await collectFilePaths(join15(dir, entry.name), relativePath, isIgnored));
247765
+ continue;
247766
+ }
247767
+ if (!entry.isFile())
247768
+ continue;
247769
+ if (ALWAYS_SKIPPED_FILES.has(entry.name))
247770
+ continue;
247771
+ if (isIgnored(relativePath, false))
247772
+ continue;
247773
+ results.push(relativePath);
247774
+ }
247775
+ return results;
247776
+ }
247777
+
247778
+ // src/core/deployments/modules.ts
247779
+ import { stat as stat2 } from "node:fs/promises";
247780
+ import { relative as relative3, resolve as resolve3, sep } from "node:path";
247781
+ var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
247782
+ var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
247783
+ var RULE_TYPE_TO_MODULE_TYPE = {
247784
+ ESModule: "esm",
247785
+ CompiledWasm: "wasm",
247786
+ Text: "text",
247787
+ Data: "data"
247788
+ };
247789
+ function toPosix(path11) {
247790
+ return path11.split(sep).join("/");
247791
+ }
247792
+ async function collectModules(config9) {
247793
+ const entryPath = resolve3(config9.configDir, config9.main);
247794
+ if (!await pathExists(entryPath)) {
247795
+ throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config9.configPath})`, {
247796
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
247797
+ });
247798
+ }
247799
+ const modulesByName = new Map;
247800
+ const entryName = toPosix(relative3(config9.configDir, entryPath));
247801
+ modulesByName.set(entryName, {
247802
+ name: entryName,
247803
+ absolutePath: entryPath,
247804
+ size: 0,
247805
+ type: "esm"
247688
247806
  });
247689
- const json2 = await response.json();
247690
- if (!response.ok) {
247691
- const errorResult = OAuthErrorSchema.safeParse(json2);
247692
- if (!errorResult.success) {
247693
- throw new SchemaValidationError("Token request failed", errorResult.error);
247807
+ const ignore = [...MODULE_IGNORE];
247808
+ if (config9.assetsDirectory?.startsWith(config9.configDir + sep)) {
247809
+ ignore.push(`${toPosix(relative3(config9.configDir, config9.assetsDirectory))}/**`);
247810
+ }
247811
+ for (const rule of config9.rules) {
247812
+ const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
247813
+ if (!type) {
247814
+ throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config9.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
247694
247815
  }
247695
- const { error: error48, error_description } = errorResult.data;
247696
- if (error48 === "authorization_pending" || error48 === "slow_down") {
247697
- return null;
247816
+ const matches = await globby(rule.globs, {
247817
+ cwd: config9.configDir,
247818
+ onlyFiles: true,
247819
+ dot: true,
247820
+ ignore
247821
+ });
247822
+ for (const match of matches.sort()) {
247823
+ if (!modulesByName.has(match)) {
247824
+ modulesByName.set(match, {
247825
+ name: match,
247826
+ absolutePath: resolve3(config9.configDir, match),
247827
+ size: 0,
247828
+ type
247829
+ });
247830
+ }
247698
247831
  }
247699
- throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
247700
- statusCode: response.status
247832
+ }
247833
+ if (config9.uploadSourceMaps) {
247834
+ const maps = await globby("**/*.map", {
247835
+ cwd: config9.configDir,
247836
+ onlyFiles: true,
247837
+ dot: true,
247838
+ ignore
247701
247839
  });
247840
+ for (const map2 of maps.sort()) {
247841
+ addSourcemap(modulesByName, config9.configDir, map2);
247842
+ }
247843
+ } else {
247844
+ for (const name2 of [...modulesByName.keys()]) {
247845
+ const mapName = `${name2}.map`;
247846
+ if (await pathExists(resolve3(config9.configDir, mapName))) {
247847
+ addSourcemap(modulesByName, config9.configDir, mapName);
247848
+ }
247849
+ }
247702
247850
  }
247703
- const result = TokenResponseSchema.safeParse(json2);
247704
- if (!result.success) {
247705
- throw new SchemaValidationError("Invalid token response from server", result.error);
247851
+ const modules = [...modulesByName.values()];
247852
+ let totalBytes = 0;
247853
+ for (const module of modules) {
247854
+ module.size = (await stat2(module.absolutePath)).size;
247855
+ totalBytes += module.size;
247706
247856
  }
247707
- return result.data;
247857
+ if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
247858
+ throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for Base44 full-stack deploys.`);
247859
+ }
247860
+ return modules;
247708
247861
  }
247709
- async function renewAccessToken(refreshToken) {
247710
- const searchParams = new URLSearchParams;
247711
- searchParams.set("grant_type", "refresh_token");
247712
- searchParams.set("refresh_token", refreshToken);
247713
- searchParams.set("client_id", AUTH_CLIENT_ID);
247714
- const response = await oauthClient.post("oauth/token", {
247715
- body: searchParams.toString(),
247716
- headers: {
247717
- "Content-Type": "application/x-www-form-urlencoded"
247718
- },
247719
- throwHttpErrors: false
247862
+ function addSourcemap(modulesByName, configDir, name2) {
247863
+ if (modulesByName.has(name2))
247864
+ return;
247865
+ modulesByName.set(name2, {
247866
+ name: name2,
247867
+ absolutePath: resolve3(configDir, name2),
247868
+ size: 0,
247869
+ type: "sourcemap"
247720
247870
  });
247721
- const json2 = await response.json();
247722
- if (!response.ok) {
247723
- const errorResult = OAuthErrorSchema.safeParse(json2);
247724
- if (!errorResult.success) {
247725
- throw new ApiError(`Token refresh failed: ${response.statusText}`, {
247726
- statusCode: response.status
247727
- });
247871
+ }
247872
+
247873
+ // src/core/deployments/upload.ts
247874
+ import { readFile as readFile4 } from "node:fs/promises";
247875
+ var UPLOAD_CONCURRENCY = 3;
247876
+ var MAX_ATTEMPTS_PER_UPLOAD = 3;
247877
+ var RETRY_BASE_DELAY_MS = 500;
247878
+ var MAX_RATE_LIMIT_WAITS = 10;
247879
+ var RATE_LIMIT_DELAY_MS = 15000;
247880
+ async function uploadAssetBuckets(target, filesByHash, onProgress) {
247881
+ const { buckets } = target;
247882
+ const totalFiles = buckets.reduce((sum, bucket) => sum + bucket.length, 0);
247883
+ let uploadedFiles = 0;
247884
+ let completionJwt = null;
247885
+ let nextBucket = 0;
247886
+ const worker = async () => {
247887
+ while (nextBucket < buckets.length) {
247888
+ const bucket = buckets[nextBucket++];
247889
+ const jwt3 = await uploadBucketWithRetry(target, bucket, filesByHash);
247890
+ if (jwt3) {
247891
+ completionJwt = jwt3;
247892
+ }
247893
+ uploadedFiles += bucket.length;
247894
+ onProgress?.({ uploadedFiles, totalFiles });
247728
247895
  }
247729
- const { error: error48, error_description } = errorResult.data;
247730
- throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
247731
- statusCode: response.status
247732
- });
247733
- }
247734
- const result = TokenResponseSchema.safeParse(json2);
247735
- if (!result.success) {
247736
- throw new SchemaValidationError("Invalid token response from server", result.error);
247896
+ };
247897
+ await Promise.all(Array.from({ length: Math.min(UPLOAD_CONCURRENCY, buckets.length) }, worker));
247898
+ if (!completionJwt) {
247899
+ throw new ApiError("Asset upload finished but the server did not return a completion token.");
247737
247900
  }
247738
- return result.data;
247901
+ return completionJwt;
247739
247902
  }
247740
- async function getUserInfo(accessToken) {
247741
- const response = await oauthClient.get("oauth/userinfo", {
247742
- headers: { Authorization: `Bearer ${accessToken}` }
247743
- });
247744
- if (!response.ok) {
247745
- throw new ApiError(`Failed to fetch user info: ${response.status}`, {
247746
- statusCode: response.status
247747
- });
247903
+ async function uploadBucketWithRetry(target, bucket, filesByHash) {
247904
+ let lastError;
247905
+ let rateLimitWaits = 0;
247906
+ const formData = await buildBucketForm(bucket, filesByHash);
247907
+ for (let attempt = 0;attempt < MAX_ATTEMPTS_PER_UPLOAD; attempt++) {
247908
+ if (attempt > 0) {
247909
+ await sleep3(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
247910
+ }
247911
+ try {
247912
+ return await uploadAssetBucket(target, formData);
247913
+ } catch (error48) {
247914
+ if (error48 instanceof HTTPError && error48.response.status === 429 && rateLimitWaits < MAX_RATE_LIMIT_WAITS) {
247915
+ rateLimitWaits++;
247916
+ attempt--;
247917
+ await sleep3(RATE_LIMIT_DELAY_MS);
247918
+ continue;
247919
+ }
247920
+ lastError = error48;
247921
+ }
247748
247922
  }
247749
- const result = UserInfoSchema.safeParse(await response.json());
247750
- if (!result.success) {
247751
- throw new SchemaValidationError("Invalid UserInfo response from server", result.error);
247923
+ if (lastError instanceof HTTPError && (lastError.response.status === 401 || lastError.response.status === 403)) {
247924
+ throw new ApiError("This deploy's upload session has expired — rerun deploy. Already-uploaded assets are skipped on the next attempt.", { statusCode: lastError.response.status, cause: lastError });
247752
247925
  }
247753
- return result.data;
247926
+ throw await ApiError.fromHttpError(lastError, "uploading assets to Cloudflare");
247754
247927
  }
247755
- // src/cli/commands/auth/login-flow.ts
247756
- async function generateAndDisplayDeviceCode(log, runTask) {
247757
- const deviceCodeResponse = await runTask("Generating device code...", async () => {
247758
- return await generateDeviceCode();
247759
- }, {
247760
- successMessage: "Device code generated",
247761
- errorMessage: "Failed to generate device code"
247762
- });
247763
- log.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}` + `
247764
- Please confirm this code at: ${deviceCodeResponse.verificationUri}`);
247765
- return deviceCodeResponse;
247928
+ async function buildBucketForm(bucket, filesByHash) {
247929
+ const formData = new FormData;
247930
+ for (const hash2 of bucket) {
247931
+ const file2 = filesByHash.get(hash2);
247932
+ if (!file2) {
247933
+ throw new InternalError(`Server requested upload of unknown asset hash: ${hash2}`);
247934
+ }
247935
+ const content = await readFile4(file2.absolutePath);
247936
+ formData.append(hash2, new File([content.toString("base64")], hash2, { type: file2.contentType }));
247937
+ }
247938
+ return formData;
247766
247939
  }
247767
- async function waitForAuthentication(deviceCode, expiresIn, interval, runTask) {
247768
- let tokenResponse;
247769
- try {
247770
- await runTask("Waiting for authentication...", async () => {
247771
- await pWaitFor(async () => {
247772
- const result = await getTokenFromDeviceCode(deviceCode);
247773
- if (result !== null) {
247774
- tokenResponse = result;
247775
- return true;
247776
- }
247777
- return false;
247778
- }, {
247779
- interval: interval * 1000,
247780
- timeout: expiresIn * 1000
247940
+ async function uploadPresignedAssets(uploads, assets, onProgress) {
247941
+ let uploadedFiles = 0;
247942
+ let nextUpload = 0;
247943
+ const worker = async () => {
247944
+ while (nextUpload < uploads.length) {
247945
+ const upload = uploads[nextUpload++];
247946
+ await uploadPresignedAssetWithRetry(upload, assets);
247947
+ uploadedFiles++;
247948
+ onProgress?.({ uploadedFiles, totalFiles: uploads.length });
247949
+ }
247950
+ };
247951
+ await Promise.all(Array.from({ length: Math.min(UPLOAD_CONCURRENCY, uploads.length) }, worker));
247952
+ }
247953
+ async function uploadPresignedAssetWithRetry(upload, assets) {
247954
+ const entry = assets.manifest[upload.path];
247955
+ const file2 = entry && assets.filesByHash.get(entry.hash);
247956
+ if (!file2) {
247957
+ throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
247958
+ }
247959
+ const content = await readFile4(file2.absolutePath);
247960
+ let lastError;
247961
+ for (let attempt = 0;attempt < MAX_ATTEMPTS_PER_UPLOAD; attempt++) {
247962
+ if (attempt > 0) {
247963
+ await sleep3(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
247964
+ }
247965
+ try {
247966
+ await distribution_default.put(upload.url, {
247967
+ body: new Uint8Array(content),
247968
+ headers: { "Content-Type": upload.contentType },
247969
+ timeout: 120000,
247970
+ retry: 0
247781
247971
  });
247782
- }, {
247783
- successMessage: "Authentication completed!",
247784
- errorMessage: "Authentication failed"
247785
- });
247786
- } catch (error48) {
247787
- if (error48 instanceof Error && error48.message.includes("timed out")) {
247788
- throw new AuthExpiredError("Authentication timed out. Please try again.");
247972
+ return;
247973
+ } catch (error48) {
247974
+ lastError = error48;
247789
247975
  }
247790
- throw error48;
247791
247976
  }
247792
- if (tokenResponse === undefined) {
247793
- throw new InternalError("Failed to retrieve authentication token.");
247977
+ throw await ApiError.fromHttpError(lastError, "uploading static assets");
247978
+ }
247979
+ function sleep3(ms) {
247980
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
247981
+ }
247982
+
247983
+ // src/core/deployments/wrangler-config.ts
247984
+ import { dirname as dirname10, join as join16, resolve as resolve4 } from "node:path";
247985
+ var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
247986
+ var RedirectConfigSchema = exports_external.looseObject({
247987
+ configPath: exports_external.string().min(1)
247988
+ });
247989
+ var WranglerConfigSchema = exports_external.looseObject({
247990
+ main: exports_external.string().min(1, "wrangler config is missing a 'main' entry module"),
247991
+ no_bundle: exports_external.boolean().optional(),
247992
+ rules: exports_external.array(exports_external.looseObject({ type: exports_external.string(), globs: exports_external.array(exports_external.string()) })).optional(),
247993
+ assets: exports_external.looseObject({
247994
+ directory: exports_external.string().optional(),
247995
+ html_handling: exports_external.string().optional(),
247996
+ not_found_handling: exports_external.string().optional(),
247997
+ run_worker_first: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional(),
247998
+ headers: exports_external.string().optional(),
247999
+ redirects: exports_external.string().optional()
248000
+ }).optional(),
248001
+ compatibility_date: exports_external.string().optional(),
248002
+ compatibility_flags: exports_external.array(exports_external.string()).optional(),
248003
+ vars: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
248004
+ upload_source_maps: exports_external.boolean().optional()
248005
+ });
248006
+ async function detectFullStackArtifact(projectRoot) {
248007
+ const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
248008
+ return await pathExists(redirectPath) ? redirectPath : null;
248009
+ }
248010
+ async function resolveWranglerConfig(projectRoot) {
248011
+ const redirectPath = await detectFullStackArtifact(projectRoot);
248012
+ if (!redirectPath) {
248013
+ throw new InvalidInputError("No full-stack build artifact found. Expected a .wrangler/deploy/config.json redirect file.", {
248014
+ hints: [{ message: "Run your framework's build command first" }]
248015
+ });
247794
248016
  }
247795
- return tokenResponse;
248017
+ const configPath = await resolveRedirectedConfigPath(redirectPath);
248018
+ const parsed = await readJsonFile(configPath);
248019
+ const result = WranglerConfigSchema.safeParse(parsed);
248020
+ if (!result.success) {
248021
+ throw new ConfigInvalidError(`Invalid wrangler config: ${exports_external.prettifyError(result.error)}`, configPath);
248022
+ }
248023
+ const config9 = result.data;
248024
+ if (config9.no_bundle !== true) {
248025
+ throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 full-stack deploys only support pre-bundled Workers output (no_bundle: true).");
248026
+ }
248027
+ const configDir = dirname10(configPath);
248028
+ const assetsDirectory = config9.assets?.directory ? resolve4(configDir, config9.assets.directory) : null;
248029
+ return {
248030
+ configPath,
248031
+ configDir,
248032
+ main: config9.main,
248033
+ assetsDirectory,
248034
+ assetsConfig: config9.assets ? toResolvedAssetsConfig(config9.assets) : null,
248035
+ compatibilityDate: config9.compatibility_date ?? null,
248036
+ compatibilityFlags: config9.compatibility_flags ?? [],
248037
+ vars: config9.vars ?? {},
248038
+ rules: (config9.rules ?? []).map((rule) => ({
248039
+ type: rule.type,
248040
+ globs: rule.globs
248041
+ })),
248042
+ uploadSourceMaps: config9.upload_source_maps ?? false
248043
+ };
247796
248044
  }
247797
- async function saveAuthData(response, userInfo) {
247798
- const expiresAt = Date.now() + response.expiresIn * 1000;
247799
- await writeAuth({
247800
- accessToken: response.accessToken,
247801
- refreshToken: response.refreshToken,
247802
- expiresAt,
247803
- email: userInfo.email,
247804
- name: userInfo.name
247805
- });
248045
+ async function resolveRedirectedConfigPath(redirectPath) {
248046
+ const parsed = await readJsonFile(redirectPath);
248047
+ const result = RedirectConfigSchema.safeParse(parsed);
248048
+ if (!result.success) {
248049
+ throw new ConfigInvalidError(`Invalid deploy redirect file: ${exports_external.prettifyError(result.error)}`, redirectPath);
248050
+ }
248051
+ const configPath = resolve4(dirname10(redirectPath), result.data.configPath);
248052
+ if (!await pathExists(configPath)) {
248053
+ throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
248054
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
248055
+ });
248056
+ }
248057
+ return configPath;
247806
248058
  }
247807
- async function login({
247808
- log,
247809
- runTask
247810
- }) {
247811
- const deviceCodeResponse = await generateAndDisplayDeviceCode(log, runTask);
247812
- const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval, runTask);
247813
- const userInfo = await getUserInfo(token.accessToken);
247814
- await saveAuthData(token, userInfo);
248059
+ function toResolvedAssetsConfig(assets) {
247815
248060
  return {
247816
- outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}`
248061
+ htmlHandling: assets.html_handling,
248062
+ notFoundHandling: assets.not_found_handling,
248063
+ runWorkerFirst: assets.run_worker_first,
248064
+ headers: assets.headers,
248065
+ redirects: assets.redirects
247817
248066
  };
247818
248067
  }
247819
248068
 
247820
- // src/cli/utils/command/middleware.ts
247821
- async function ensureAuth(ctx) {
247822
- if (hasWorkspaceApiKeyAuth()) {
247823
- ctx.errorReporter.setContext({
247824
- user: { email: "workspace-api-key", name: "Workspace API key" }
247825
- });
247826
- return;
248069
+ // src/core/deployments/deploy.ts
248070
+ async function deployFullStack(options) {
248071
+ const { projectRoot, gitHash, progress } = options;
248072
+ const config9 = await resolveWranglerConfig(projectRoot);
248073
+ if (!config9.compatibilityFlags.includes("nodejs_compat")) {
248074
+ progress?.onWarning?.("The wrangler config has no 'nodejs_compat' compatibility flag; Node.js built-ins will be unavailable at runtime. Enable it in your framework's Cloudflare adapter settings if your server code needs Node APIs.");
247827
248075
  }
247828
- await seedAuthFromEnv();
247829
- const loggedIn = await isLoggedIn();
247830
- if (!loggedIn) {
247831
- ctx.log.info("You need to login first to continue.");
247832
- await login(ctx);
248076
+ if (config9.vars && Object.keys(config9.vars).length > 0) {
248077
+ progress?.onWarning?.("wrangler 'vars' are not supported and were ignored — a worker's environment comes from the app's secrets (base44 secrets set).");
247833
248078
  }
247834
- try {
247835
- const userInfo = await readAuth();
247836
- ctx.errorReporter.setContext({
247837
- user: { email: userInfo.email, name: userInfo.name }
247838
- });
247839
- } catch {}
248079
+ const modules = await collectModules(config9);
248080
+ let assets = { manifest: {}, filesByHash: new Map };
248081
+ if (config9.assetsDirectory && await pathExists(config9.assetsDirectory)) {
248082
+ assets = await buildAssetManifest(config9.assetsDirectory, getAppContext().id);
248083
+ }
248084
+ const created = await createDeployment({
248085
+ git_hash: gitHash,
248086
+ config: {
248087
+ main: config9.main,
248088
+ compatibility_date: config9.compatibilityDate,
248089
+ compatibility_flags: config9.compatibilityFlags,
248090
+ assets: buildAssetsConfig(config9.assetsConfig, progress)
248091
+ },
248092
+ asset_manifest: assets.manifest
248093
+ });
248094
+ if (created.assetUploads && created.assetUploads.type !== "cf") {
248095
+ throw new ApiError(`The server answered a full-stack deploy with the "${created.assetUploads.type}" upload target.`);
248096
+ }
248097
+ const totalAssets = Object.keys(assets.manifest).length;
248098
+ const newAssets = created.assetUploads ? new Set(created.assetUploads.buckets.flat()).size : 0;
248099
+ progress?.onAssets?.({ totalAssets, newAssets });
248100
+ const completionJwt = created.assetUploads ? await uploadAssetBuckets(created.assetUploads, assets.filesByHash, progress?.onAssetUpload) : null;
248101
+ progress?.onWorker?.({ moduleCount: modules.length });
248102
+ const finalized = await finalizeDeployment(created.deploymentId, completionJwt, modules);
248103
+ return { deploymentId: finalized.deploymentId, gitHash };
247840
248104
  }
247841
- async function ensureAppContext(ctx, options = {}) {
247842
- const appContext = await initAppContext(options);
247843
- ctx.app = appContext;
247844
- ctx.errorReporter.setContext({ appId: appContext.id });
248105
+ function buildAssetsConfig(assetsConfig, progress) {
248106
+ if (!assetsConfig)
248107
+ return null;
248108
+ if (assetsConfig.headers || assetsConfig.redirects) {
248109
+ progress?.onWarning?.("_headers/_redirects files are not supported yet and were ignored for this deploy.");
248110
+ }
248111
+ let runWorkerFirst;
248112
+ if (Array.isArray(assetsConfig.runWorkerFirst)) {
248113
+ progress?.onWarning?.("'run_worker_first' route patterns are not supported yet and were ignored for this deploy.");
248114
+ } else {
248115
+ runWorkerFirst = assetsConfig.runWorkerFirst;
248116
+ }
248117
+ return {
248118
+ html_handling: assetsConfig.htmlHandling,
248119
+ not_found_handling: assetsConfig.notFoundHandling,
248120
+ run_worker_first: runWorkerFirst
248121
+ };
247845
248122
  }
247846
-
247847
248123
  // ../../node_modules/is-plain-obj/index.js
247848
248124
  function isPlainObject2(value) {
247849
248125
  if (typeof value !== "object" || value === null) {
@@ -247941,13 +248217,13 @@ var getJoinLength = (uint8Arrays) => {
247941
248217
  var isTemplateString = (templates) => Array.isArray(templates) && Array.isArray(templates.raw);
247942
248218
  var parseTemplates = (templates, expressions) => {
247943
248219
  let tokens = [];
247944
- for (const [index, template2] of templates.entries()) {
248220
+ for (const [index, template] of templates.entries()) {
247945
248221
  tokens = parseTemplate({
247946
248222
  templates,
247947
248223
  expressions,
247948
248224
  tokens,
247949
248225
  index,
247950
- template: template2
248226
+ template
247951
248227
  });
247952
248228
  }
247953
248229
  if (tokens.length === 0) {
@@ -247956,11 +248232,11 @@ var parseTemplates = (templates, expressions) => {
247956
248232
  const [file2, ...commandArguments] = tokens;
247957
248233
  return [file2, commandArguments, {}];
247958
248234
  };
247959
- var parseTemplate = ({ templates, expressions, tokens, index, template: template2 }) => {
247960
- if (template2 === undefined) {
248235
+ var parseTemplate = ({ templates, expressions, tokens, index, template }) => {
248236
+ if (template === undefined) {
247961
248237
  throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`);
247962
248238
  }
247963
- const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(template2, templates.raw[index]);
248239
+ const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(template, templates.raw[index]);
247964
248240
  const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces);
247965
248241
  if (index === expressions.length) {
247966
248242
  return newTokens;
@@ -247969,18 +248245,18 @@ var parseTemplate = ({ templates, expressions, tokens, index, template: template
247969
248245
  const expressionTokens = Array.isArray(expression) ? expression.map((expression2) => parseExpression(expression2)) : [parseExpression(expression)];
247970
248246
  return concatTokens(newTokens, expressionTokens, trailingWhitespaces);
247971
248247
  };
247972
- var splitByWhitespaces = (template2, rawTemplate) => {
248248
+ var splitByWhitespaces = (template, rawTemplate) => {
247973
248249
  if (rawTemplate.length === 0) {
247974
248250
  return { nextTokens: [], leadingWhitespaces: false, trailingWhitespaces: false };
247975
248251
  }
247976
248252
  const nextTokens = [];
247977
248253
  let templateStart = 0;
247978
248254
  const leadingWhitespaces = DELIMITERS.has(rawTemplate[0]);
247979
- for (let templateIndex = 0, rawIndex = 0;templateIndex < template2.length; templateIndex += 1, rawIndex += 1) {
248255
+ for (let templateIndex = 0, rawIndex = 0;templateIndex < template.length; templateIndex += 1, rawIndex += 1) {
247980
248256
  const rawCharacter = rawTemplate[rawIndex];
247981
248257
  if (DELIMITERS.has(rawCharacter)) {
247982
248258
  if (templateStart !== templateIndex) {
247983
- nextTokens.push(template2.slice(templateStart, templateIndex));
248259
+ nextTokens.push(template.slice(templateStart, templateIndex));
247984
248260
  }
247985
248261
  templateStart = templateIndex + 1;
247986
248262
  } else if (rawCharacter === "\\") {
@@ -247996,9 +248272,9 @@ var splitByWhitespaces = (template2, rawTemplate) => {
247996
248272
  }
247997
248273
  }
247998
248274
  }
247999
- const trailingWhitespaces = templateStart === template2.length;
248275
+ const trailingWhitespaces = templateStart === template.length;
248000
248276
  if (!trailingWhitespaces) {
248001
- nextTokens.push(template2.slice(templateStart));
248277
+ nextTokens.push(template.slice(templateStart));
248002
248278
  }
248003
248279
  return { nextTokens, leadingWhitespaces, trailingWhitespaces };
248004
248280
  };
@@ -249392,8 +249668,8 @@ var disconnect = (anyProcess) => {
249392
249668
  // ../../node_modules/execa/lib/utils/deferred.js
249393
249669
  var createDeferred = () => {
249394
249670
  const methods = {};
249395
- const promise2 = new Promise((resolve4, reject) => {
249396
- Object.assign(methods, { resolve: resolve4, reject });
249671
+ const promise2 = new Promise((resolve5, reject) => {
249672
+ Object.assign(methods, { resolve: resolve5, reject });
249397
249673
  });
249398
249674
  return Object.assign(promise2, methods);
249399
249675
  };
@@ -253757,11 +254033,11 @@ var addConcurrentStream = (concurrentStreams, stream, waitName) => {
253757
254033
  const promises = weakMap.get(stream);
253758
254034
  const promise2 = createDeferred();
253759
254035
  promises.push(promise2);
253760
- const resolve4 = promise2.resolve.bind(promise2);
253761
- return { resolve: resolve4, promises };
254036
+ const resolve5 = promise2.resolve.bind(promise2);
254037
+ return { resolve: resolve5, promises };
253762
254038
  };
253763
- var waitForConcurrentStreams = async ({ resolve: resolve4, promises }, subprocess) => {
253764
- resolve4();
254039
+ var waitForConcurrentStreams = async ({ resolve: resolve5, promises }, subprocess) => {
254040
+ resolve5();
253765
254041
  const [isSubprocessExit] = await Promise.race([
253766
254042
  Promise.allSettled([true, subprocess]),
253767
254043
  Promise.all([false, ...promises])
@@ -254340,6 +254616,441 @@ var {
254340
254616
  getCancelSignal: getCancelSignal2
254341
254617
  } = getIpcExport();
254342
254618
 
254619
+ // src/core/deployments/git-hash.ts
254620
+ async function resolveGitHash(projectRoot, explicit) {
254621
+ const hash2 = explicit ?? await gitHead(projectRoot);
254622
+ if (!hash2 || !GIT_HASH_PATTERN.test(hash2)) {
254623
+ 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.", {
254624
+ hints: [
254625
+ {
254626
+ message: "Run the deploy from a git checkout, or pass the commit explicitly with --git-hash."
254627
+ }
254628
+ ]
254629
+ });
254630
+ }
254631
+ return hash2;
254632
+ }
254633
+ async function gitHead(projectRoot) {
254634
+ try {
254635
+ const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
254636
+ cwd: projectRoot
254637
+ });
254638
+ return stdout.trim();
254639
+ } catch {
254640
+ return null;
254641
+ }
254642
+ }
254643
+ // src/core/deployments/static-site.ts
254644
+ import { readFile as readFile5 } from "node:fs/promises";
254645
+ import { join as join17 } from "node:path";
254646
+ var STATIC_DEPLOYMENTS_ENV = "BASE44_STATIC_DEPLOYMENTS";
254647
+ function staticDeploymentsEnabled(env2 = process.env) {
254648
+ const value = env2[STATIC_DEPLOYMENTS_ENV];
254649
+ return value === "1" || value === "true";
254650
+ }
254651
+ async function deployStaticSite(options) {
254652
+ const { outputDir, gitHash, progress } = options;
254653
+ const assets = await buildAssetManifest(outputDir, getAppContext().id);
254654
+ if (!assets.manifest["/index.html"]) {
254655
+ throw new InvalidInputError(`No index.html found in "${outputDir}" — a static site needs one at the output directory root.`);
254656
+ }
254657
+ const created = await createDeployment({
254658
+ git_hash: gitHash,
254659
+ asset_manifest: assets.manifest
254660
+ });
254661
+ if (created.assetUploads && created.assetUploads.type !== "s3") {
254662
+ throw new ApiError(`The server answered a static-site deploy with the "${created.assetUploads.type}" upload target.`);
254663
+ }
254664
+ const totalAssets = Object.keys(assets.manifest).length;
254665
+ progress?.onAssets?.({
254666
+ totalAssets,
254667
+ newAssets: created.assetUploads?.uploads.length ?? 0
254668
+ });
254669
+ if (created.assetUploads) {
254670
+ await uploadPresignedAssets(created.assetUploads.uploads, assets, progress?.onAssetUpload);
254671
+ }
254672
+ const indexHtml = await readFile5(join17(outputDir, "index.html"));
254673
+ const finalized = await finalizeStaticDeployment(created.deploymentId, new Uint8Array(indexHtml));
254674
+ return { deploymentId: finalized.deploymentId, gitHash };
254675
+ }
254676
+ // src/core/site/deploy-app.ts
254677
+ async function planAppDeploy(target) {
254678
+ if (await detectFullStackArtifact(target.root)) {
254679
+ return { kind: "full-stack" };
254680
+ }
254681
+ const outputDirectory = target.site?.outputDirectory;
254682
+ if (!outputDirectory) {
254683
+ return { kind: "none" };
254684
+ }
254685
+ const outputDir = resolve5(target.root, outputDirectory);
254686
+ return staticDeploymentsEnabled() ? { kind: "static-deployment", outputDir } : { kind: "static", outputDir };
254687
+ }
254688
+ async function detectAppDeployKind(target) {
254689
+ return (await planAppDeploy(target)).kind;
254690
+ }
254691
+ async function deployAppSite(target, options = {}) {
254692
+ const plan = await planAppDeploy(target);
254693
+ switch (plan.kind) {
254694
+ case "full-stack": {
254695
+ const gitHash = await resolveGitHash(target.root, options.gitHash);
254696
+ const { deploymentId } = await deployFullStack({
254697
+ projectRoot: target.root,
254698
+ gitHash,
254699
+ progress: options.progress
254700
+ });
254701
+ return { kind: "full-stack", deploymentId, gitHash };
254702
+ }
254703
+ case "static-deployment": {
254704
+ const gitHash = await resolveGitHash(target.root, options.gitHash);
254705
+ const { deploymentId } = await deployStaticSite({
254706
+ outputDir: plan.outputDir,
254707
+ gitHash,
254708
+ progress: options.progress
254709
+ });
254710
+ return { kind: "static-deployment", deploymentId, gitHash };
254711
+ }
254712
+ case "static": {
254713
+ const { appUrl } = await deploySite(plan.outputDir);
254714
+ return { kind: "static", appUrl };
254715
+ }
254716
+ case "none":
254717
+ return { kind: "none" };
254718
+ }
254719
+ }
254720
+ // src/core/project/deploy.ts
254721
+ function hasResourcesToDeploy(projectData) {
254722
+ const {
254723
+ project,
254724
+ entities,
254725
+ functions,
254726
+ agents,
254727
+ agentSkills,
254728
+ connectors,
254729
+ authConfig
254730
+ } = projectData;
254731
+ const hasSite = Boolean(project.site?.outputDirectory || project.site?.buildCommand);
254732
+ const hasEntities = entities.length > 0;
254733
+ const hasFunctions = functions.length > 0;
254734
+ const hasAgents = agents.length > 0;
254735
+ const hasAgentSkills = agentSkills.length > 0;
254736
+ const hasConnectors = connectors.length > 0;
254737
+ const hasAuthConfig = authConfig.length > 0;
254738
+ const hasVisibility = Boolean(project.visibility);
254739
+ return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
254740
+ }
254741
+ async function deployAll(projectData, options) {
254742
+ const {
254743
+ project,
254744
+ entities,
254745
+ functions,
254746
+ agents,
254747
+ agentSkills,
254748
+ connectors,
254749
+ authConfig
254750
+ } = projectData;
254751
+ await setAppVisibility(project.visibility);
254752
+ if (project.visibility) {
254753
+ options?.onVisibilitySet?.(project.visibility);
254754
+ }
254755
+ await entityResource.push(entities);
254756
+ await deployFunctionsSequentially(functions, {
254757
+ onStart: options?.onFunctionStart,
254758
+ onResult: options?.onFunctionResult
254759
+ });
254760
+ await agentSkillResource.push(agentSkills);
254761
+ await agentResource.push(agents);
254762
+ await authConfigResource.push(authConfig);
254763
+ const skipConnectorSync = connectors.length === 0 && hasWorkspaceApiKeyAuth();
254764
+ const connectorResults = skipConnectorSync ? [] : (await pushConnectors(connectors)).results;
254765
+ if ((options?.site ?? true) && project.site?.outputDirectory) {
254766
+ const outputDir = resolve6(project.root, project.site.outputDirectory);
254767
+ const { appUrl } = await deploySite(outputDir);
254768
+ return { appUrl, connectorResults };
254769
+ }
254770
+ return { connectorResults };
254771
+ }
254772
+ // src/core/clients/base44-client.ts
254773
+ var retriedRequests = new WeakSet;
254774
+ async function captureRequestBody(request, options) {
254775
+ if (request.body == null) {
254776
+ return;
254777
+ }
254778
+ try {
254779
+ const cloned = request.clone();
254780
+ const text = await cloned.text();
254781
+ options.context.__requestBody = text;
254782
+ } catch {}
254783
+ }
254784
+ async function handleUnauthorized(request, _options, response) {
254785
+ if (response.status !== 401) {
254786
+ return;
254787
+ }
254788
+ if (hasWorkspaceApiKeyAuth()) {
254789
+ return;
254790
+ }
254791
+ if (retriedRequests.has(request)) {
254792
+ return;
254793
+ }
254794
+ const newAccessToken = await refreshAndSaveTokens();
254795
+ if (!newAccessToken) {
254796
+ return;
254797
+ }
254798
+ retriedRequests.add(request);
254799
+ const requestId = request.headers.get("X-Request-ID");
254800
+ return distribution_default(request.clone(), {
254801
+ headers: {
254802
+ ...requestId && { "X-Request-ID": requestId },
254803
+ Authorization: `Bearer ${newAccessToken}`
254804
+ }
254805
+ });
254806
+ }
254807
+ var base44Client = distribution_default.create({
254808
+ prefixUrl: getBase44ApiUrl(),
254809
+ headers: {
254810
+ "User-Agent": "Base44 CLI"
254811
+ },
254812
+ hooks: {
254813
+ beforeRequest: [
254814
+ (request) => {
254815
+ request.headers.set("X-Request-ID", randomUUID2());
254816
+ },
254817
+ captureRequestBody,
254818
+ async (request) => {
254819
+ const workspaceApiKey = getWorkspaceApiKeyFromEnv();
254820
+ if (workspaceApiKey && isWorkspaceApiKey(workspaceApiKey)) {
254821
+ request.headers.set("api_key", workspaceApiKey);
254822
+ return;
254823
+ }
254824
+ try {
254825
+ const auth = await readAuth();
254826
+ if (isTokenExpired(auth)) {
254827
+ const newAccessToken = await refreshAndSaveTokens();
254828
+ if (newAccessToken) {
254829
+ request.headers.set("Authorization", `Bearer ${newAccessToken}`);
254830
+ return;
254831
+ }
254832
+ }
254833
+ request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
254834
+ } catch {}
254835
+ }
254836
+ ],
254837
+ afterResponse: [handleUnauthorized]
254838
+ }
254839
+ });
254840
+ function getAppClient() {
254841
+ const { id } = getAppContext();
254842
+ return base44Client.extend({
254843
+ prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
254844
+ });
254845
+ }
254846
+ function getSandboxClient(appId) {
254847
+ return base44Client.extend({
254848
+ prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
254849
+ });
254850
+ }
254851
+ // src/core/clients/oauth-client.ts
254852
+ import { randomUUID as randomUUID3 } from "node:crypto";
254853
+ var oauthClient = distribution_default.create({
254854
+ prefixUrl: getBase44ApiUrl(),
254855
+ headers: {
254856
+ "User-Agent": "Base44 CLI"
254857
+ },
254858
+ hooks: {
254859
+ beforeRequest: [
254860
+ (request) => {
254861
+ request.headers.set("X-Request-ID", randomUUID3());
254862
+ }
254863
+ ]
254864
+ }
254865
+ });
254866
+ // src/core/auth/api.ts
254867
+ async function generateDeviceCode() {
254868
+ const response = await oauthClient.post("oauth/device/code", {
254869
+ json: {
254870
+ client_id: AUTH_CLIENT_ID,
254871
+ scope: "apps:read apps:write sandbox:write"
254872
+ },
254873
+ throwHttpErrors: false
254874
+ });
254875
+ if (!response.ok) {
254876
+ throw new ApiError(`Failed to generate device code: ${response.status} ${response.statusText}`, { statusCode: response.status });
254877
+ }
254878
+ const result = DeviceCodeResponseSchema.safeParse(await response.json());
254879
+ if (!result.success) {
254880
+ throw new SchemaValidationError("Invalid device code response from server", result.error);
254881
+ }
254882
+ return result.data;
254883
+ }
254884
+ async function getTokenFromDeviceCode(deviceCode) {
254885
+ const searchParams = new URLSearchParams;
254886
+ searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
254887
+ searchParams.set("device_code", deviceCode);
254888
+ searchParams.set("client_id", AUTH_CLIENT_ID);
254889
+ const response = await oauthClient.post("oauth/token", {
254890
+ body: searchParams.toString(),
254891
+ headers: {
254892
+ "Content-Type": "application/x-www-form-urlencoded"
254893
+ },
254894
+ throwHttpErrors: false
254895
+ });
254896
+ const json2 = await response.json();
254897
+ if (!response.ok) {
254898
+ const errorResult = OAuthErrorSchema.safeParse(json2);
254899
+ if (!errorResult.success) {
254900
+ throw new SchemaValidationError("Token request failed", errorResult.error);
254901
+ }
254902
+ const { error: error48, error_description } = errorResult.data;
254903
+ if (error48 === "authorization_pending" || error48 === "slow_down") {
254904
+ return null;
254905
+ }
254906
+ throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
254907
+ statusCode: response.status
254908
+ });
254909
+ }
254910
+ const result = TokenResponseSchema.safeParse(json2);
254911
+ if (!result.success) {
254912
+ throw new SchemaValidationError("Invalid token response from server", result.error);
254913
+ }
254914
+ return result.data;
254915
+ }
254916
+ async function renewAccessToken(refreshToken) {
254917
+ const searchParams = new URLSearchParams;
254918
+ searchParams.set("grant_type", "refresh_token");
254919
+ searchParams.set("refresh_token", refreshToken);
254920
+ searchParams.set("client_id", AUTH_CLIENT_ID);
254921
+ const response = await oauthClient.post("oauth/token", {
254922
+ body: searchParams.toString(),
254923
+ headers: {
254924
+ "Content-Type": "application/x-www-form-urlencoded"
254925
+ },
254926
+ throwHttpErrors: false
254927
+ });
254928
+ const json2 = await response.json();
254929
+ if (!response.ok) {
254930
+ const errorResult = OAuthErrorSchema.safeParse(json2);
254931
+ if (!errorResult.success) {
254932
+ throw new ApiError(`Token refresh failed: ${response.statusText}`, {
254933
+ statusCode: response.status
254934
+ });
254935
+ }
254936
+ const { error: error48, error_description } = errorResult.data;
254937
+ throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
254938
+ statusCode: response.status
254939
+ });
254940
+ }
254941
+ const result = TokenResponseSchema.safeParse(json2);
254942
+ if (!result.success) {
254943
+ throw new SchemaValidationError("Invalid token response from server", result.error);
254944
+ }
254945
+ return result.data;
254946
+ }
254947
+ async function getUserInfo(accessToken) {
254948
+ const response = await oauthClient.get("oauth/userinfo", {
254949
+ headers: { Authorization: `Bearer ${accessToken}` }
254950
+ });
254951
+ if (!response.ok) {
254952
+ throw new ApiError(`Failed to fetch user info: ${response.status}`, {
254953
+ statusCode: response.status
254954
+ });
254955
+ }
254956
+ const result = UserInfoSchema.safeParse(await response.json());
254957
+ if (!result.success) {
254958
+ throw new SchemaValidationError("Invalid UserInfo response from server", result.error);
254959
+ }
254960
+ return result.data;
254961
+ }
254962
+ // src/cli/commands/auth/login-flow.ts
254963
+ async function generateAndDisplayDeviceCode(log, runTask) {
254964
+ const deviceCodeResponse = await runTask("Generating device code...", async () => {
254965
+ return await generateDeviceCode();
254966
+ }, {
254967
+ successMessage: "Device code generated",
254968
+ errorMessage: "Failed to generate device code"
254969
+ });
254970
+ log.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}` + `
254971
+ Please confirm this code at: ${deviceCodeResponse.verificationUri}`);
254972
+ return deviceCodeResponse;
254973
+ }
254974
+ async function waitForAuthentication(deviceCode, expiresIn, interval, runTask) {
254975
+ let tokenResponse;
254976
+ try {
254977
+ await runTask("Waiting for authentication...", async () => {
254978
+ await pWaitFor(async () => {
254979
+ const result = await getTokenFromDeviceCode(deviceCode);
254980
+ if (result !== null) {
254981
+ tokenResponse = result;
254982
+ return true;
254983
+ }
254984
+ return false;
254985
+ }, {
254986
+ interval: interval * 1000,
254987
+ timeout: expiresIn * 1000
254988
+ });
254989
+ }, {
254990
+ successMessage: "Authentication completed!",
254991
+ errorMessage: "Authentication failed"
254992
+ });
254993
+ } catch (error48) {
254994
+ if (error48 instanceof Error && error48.message.includes("timed out")) {
254995
+ throw new AuthExpiredError("Authentication timed out. Please try again.");
254996
+ }
254997
+ throw error48;
254998
+ }
254999
+ if (tokenResponse === undefined) {
255000
+ throw new InternalError("Failed to retrieve authentication token.");
255001
+ }
255002
+ return tokenResponse;
255003
+ }
255004
+ async function saveAuthData(response, userInfo) {
255005
+ const expiresAt = Date.now() + response.expiresIn * 1000;
255006
+ await writeAuth({
255007
+ accessToken: response.accessToken,
255008
+ refreshToken: response.refreshToken,
255009
+ expiresAt,
255010
+ email: userInfo.email,
255011
+ name: userInfo.name
255012
+ });
255013
+ }
255014
+ async function login({
255015
+ log,
255016
+ runTask
255017
+ }) {
255018
+ const deviceCodeResponse = await generateAndDisplayDeviceCode(log, runTask);
255019
+ const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval, runTask);
255020
+ const userInfo = await getUserInfo(token.accessToken);
255021
+ await saveAuthData(token, userInfo);
255022
+ return {
255023
+ outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}`
255024
+ };
255025
+ }
255026
+
255027
+ // src/cli/utils/command/middleware.ts
255028
+ async function ensureAuth(ctx) {
255029
+ if (hasWorkspaceApiKeyAuth()) {
255030
+ ctx.errorReporter.setContext({
255031
+ user: { email: "workspace-api-key", name: "Workspace API key" }
255032
+ });
255033
+ return;
255034
+ }
255035
+ await seedAuthFromEnv();
255036
+ const loggedIn = await isLoggedIn();
255037
+ if (!loggedIn) {
255038
+ ctx.log.info("You need to login first to continue.");
255039
+ await login(ctx);
255040
+ }
255041
+ try {
255042
+ const userInfo = await readAuth();
255043
+ ctx.errorReporter.setContext({
255044
+ user: { email: userInfo.email, name: userInfo.name }
255045
+ });
255046
+ } catch {}
255047
+ }
255048
+ async function ensureAppContext(ctx, options = {}) {
255049
+ const appContext = await initAppContext(options);
255050
+ ctx.app = appContext;
255051
+ ctx.errorReporter.setContext({ appId: appContext.id });
255052
+ }
255053
+
254343
255054
  // src/cli/utils/version-check.ts
254344
255055
  async function checkForUpgrade() {
254345
255056
  const testLatestVersion = getTestOverrides()?.latestVersion;
@@ -254718,623 +255429,6 @@ function formatYaml(data, options = {}) {
254718
255429
  const replacer = stripEmpty ? stripEmptyReplacer : undefined;
254719
255430
  return $stringify(data, replacer, { indent: YAML_INDENT }).trimEnd();
254720
255431
  }
254721
- // src/core/deployments/api.ts
254722
- import { readFile as readFile2 } from "node:fs/promises";
254723
-
254724
- // src/core/deployments/schema.ts
254725
- var GIT_HASH_PATTERN = /^[a-fA-F0-9]{7,64}$/;
254726
- var CreateDeploymentResponseSchema = exports_external.object({
254727
- deployment_id: exports_external.string(),
254728
- asset_buckets: exports_external.array(exports_external.array(exports_external.string()))
254729
- }).transform((data) => ({
254730
- deploymentId: data.deployment_id,
254731
- assetBuckets: data.asset_buckets
254732
- }));
254733
- var AssetUploadResponseSchema = exports_external.looseObject({
254734
- result: exports_external.looseObject({ jwt: exports_external.string().nullable().optional() }).nullable().optional()
254735
- });
254736
- var FinalizeDeploymentResponseSchema = exports_external.object({
254737
- deployment_id: exports_external.string()
254738
- }).transform((data) => ({
254739
- deploymentId: data.deployment_id
254740
- }));
254741
-
254742
- // src/core/deployments/api.ts
254743
- var MODULE_CONTENT_TYPES = {
254744
- esm: "application/javascript+module",
254745
- sourcemap: "application/source-map",
254746
- wasm: "application/wasm",
254747
- text: "text/plain",
254748
- data: "application/octet-stream"
254749
- };
254750
- async function createDeployment(request) {
254751
- const appClient = getAppClient();
254752
- let response;
254753
- try {
254754
- response = await appClient.post("deployments", {
254755
- json: request,
254756
- timeout: 120000
254757
- });
254758
- } catch (error48) {
254759
- throw await ApiError.fromHttpError(error48, "creating deployment");
254760
- }
254761
- const result = CreateDeploymentResponseSchema.safeParse(await response.json());
254762
- if (!result.success) {
254763
- throw new SchemaValidationError("Invalid response from server", result.error);
254764
- }
254765
- return result.data;
254766
- }
254767
- async function uploadAssetBucket(deploymentId, formData) {
254768
- const appClient = getAppClient();
254769
- const response = await appClient.post(`deployments/${encodeURIComponent(deploymentId)}/assets`, {
254770
- searchParams: { base64: "true" },
254771
- body: formData,
254772
- timeout: 120000,
254773
- retry: 0
254774
- });
254775
- const parsed = AssetUploadResponseSchema.safeParse(await response.json());
254776
- const jwt3 = parsed.success ? parsed.data.result?.jwt : null;
254777
- return jwt3 || null;
254778
- }
254779
- async function finalizeDeployment(deploymentId, completionJwt, modules) {
254780
- const appClient = getAppClient();
254781
- const formData = new FormData;
254782
- formData.append("payload", JSON.stringify({ completion_jwt: completionJwt }));
254783
- for (const module of modules) {
254784
- const content = await readFile2(module.absolutePath);
254785
- formData.append(module.name, new File([new Uint8Array(content)], module.name, {
254786
- type: MODULE_CONTENT_TYPES[module.type]
254787
- }));
254788
- }
254789
- let response;
254790
- try {
254791
- response = await appClient.post(`deployments/${encodeURIComponent(deploymentId)}/finalize`, { body: formData, timeout: 180000 });
254792
- } catch (error48) {
254793
- throw await ApiError.fromHttpError(error48, "finalizing deployment");
254794
- }
254795
- const result = FinalizeDeploymentResponseSchema.safeParse(await response.json());
254796
- if (!result.success) {
254797
- throw new SchemaValidationError("Invalid response from server", result.error);
254798
- }
254799
- return result.data;
254800
- }
254801
- // src/core/deployments/manifest.ts
254802
- import { createHash } from "node:crypto";
254803
- import { readdir as readdir2, readFile as readFile3, stat } from "node:fs/promises";
254804
- import { extname, join as join15 } from "node:path";
254805
- var MAX_ASSET_SIZE_BYTES = 25 * 1024 * 1024;
254806
- var MAX_ASSET_COUNT = 1e5;
254807
- var ASSETS_IGNORE_FILE = ".assetsignore";
254808
- var ALWAYS_SKIPPED_FILES = new Set([
254809
- ASSETS_IGNORE_FILE,
254810
- "wrangler.json",
254811
- ".dev.vars"
254812
- ]);
254813
- var MIME_TYPES = {
254814
- ".html": "text/html",
254815
- ".htm": "text/html",
254816
- ".css": "text/css",
254817
- ".js": "text/javascript",
254818
- ".mjs": "text/javascript",
254819
- ".json": "application/json",
254820
- ".map": "application/json",
254821
- ".txt": "text/plain",
254822
- ".xml": "application/xml",
254823
- ".svg": "image/svg+xml",
254824
- ".png": "image/png",
254825
- ".jpg": "image/jpeg",
254826
- ".jpeg": "image/jpeg",
254827
- ".gif": "image/gif",
254828
- ".webp": "image/webp",
254829
- ".avif": "image/avif",
254830
- ".ico": "image/x-icon",
254831
- ".woff": "font/woff",
254832
- ".woff2": "font/woff2",
254833
- ".ttf": "font/ttf",
254834
- ".otf": "font/otf",
254835
- ".eot": "application/vnd.ms-fontobject",
254836
- ".mp3": "audio/mpeg",
254837
- ".mp4": "video/mp4",
254838
- ".webm": "video/webm",
254839
- ".pdf": "application/pdf",
254840
- ".wasm": "application/wasm",
254841
- ".webmanifest": "application/manifest+json"
254842
- };
254843
- function getMimeType(filePath) {
254844
- return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
254845
- }
254846
- function hashAsset(appId, content) {
254847
- return createHash("sha256").update(Buffer.from(appId, "utf8")).update(content).digest("hex").slice(0, 32);
254848
- }
254849
- function globToRegExp(glob) {
254850
- let source = "";
254851
- for (let i2 = 0;i2 < glob.length; i2++) {
254852
- const char = glob[i2];
254853
- if (char === "*") {
254854
- if (glob[i2 + 1] === "*") {
254855
- source += ".*";
254856
- i2++;
254857
- } else {
254858
- source += "[^/]*";
254859
- }
254860
- } else if (char === "?") {
254861
- source += "[^/]";
254862
- } else {
254863
- source += char.replace(/[.+^${}()|[\]\\]/g, "\\$&");
254864
- }
254865
- }
254866
- return new RegExp(`^${source}$`);
254867
- }
254868
- function createIgnoreMatcher(lines) {
254869
- const rules = lines.map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map((line) => {
254870
- const isDirOnly = line.endsWith("/");
254871
- let pattern = isDirOnly ? line.slice(0, -1) : line;
254872
- const anchored = pattern.includes("/");
254873
- pattern = pattern.replace(/^\//, "");
254874
- return { regex: globToRegExp(pattern), anchored, isDirOnly };
254875
- });
254876
- return (relativePath, isDirectory2) => {
254877
- const segments = relativePath.split("/");
254878
- return rules.some((rule) => {
254879
- if (rule.anchored) {
254880
- if (rule.isDirOnly ? isDirectory2 : true) {
254881
- if (rule.regex.test(relativePath))
254882
- return true;
254883
- }
254884
- return false;
254885
- }
254886
- const basename4 = segments[segments.length - 1];
254887
- if (rule.isDirOnly && !isDirectory2)
254888
- return false;
254889
- return rule.regex.test(basename4);
254890
- });
254891
- };
254892
- }
254893
- async function loadIgnoreMatcher(assetsDir) {
254894
- const ignorePath = join15(assetsDir, ASSETS_IGNORE_FILE);
254895
- if (!await pathExists(ignorePath)) {
254896
- return () => false;
254897
- }
254898
- const content = await readTextFile(ignorePath);
254899
- return createIgnoreMatcher(content.split(/\r?\n/));
254900
- }
254901
- async function buildAssetManifest(assetsDir, appId) {
254902
- const isIgnored = await loadIgnoreMatcher(assetsDir);
254903
- const manifest = {};
254904
- const filesByHash = new Map;
254905
- const relativeFilePaths = await collectFilePaths(assetsDir, "", isIgnored);
254906
- if (relativeFilePaths.length > MAX_ASSET_COUNT) {
254907
- throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
254908
- }
254909
- for (const relativePath of relativeFilePaths.sort()) {
254910
- const absolutePath = join15(assetsDir, ...relativePath.split("/"));
254911
- const { size } = await stat(absolutePath);
254912
- if (size > MAX_ASSET_SIZE_BYTES) {
254913
- throw new InvalidInputError(`Static asset "${relativePath}" is ${size} bytes, which exceeds the 25 MiB per-file limit.`);
254914
- }
254915
- const content = await readFile3(absolutePath);
254916
- const hash2 = hashAsset(appId, content);
254917
- manifest[`/${relativePath}`] = { hash: hash2, size };
254918
- if (!filesByHash.has(hash2)) {
254919
- filesByHash.set(hash2, {
254920
- absolutePath,
254921
- hash: hash2,
254922
- size,
254923
- contentType: getMimeType(absolutePath)
254924
- });
254925
- }
254926
- }
254927
- return { manifest, filesByHash };
254928
- }
254929
- async function collectFilePaths(dir, relativeDir, isIgnored) {
254930
- const entries = await readdir2(dir, { withFileTypes: true });
254931
- const results = [];
254932
- for (const entry of entries) {
254933
- const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
254934
- if (entry.isDirectory()) {
254935
- if (isIgnored(relativePath, true))
254936
- continue;
254937
- results.push(...await collectFilePaths(join15(dir, entry.name), relativePath, isIgnored));
254938
- continue;
254939
- }
254940
- if (!entry.isFile())
254941
- continue;
254942
- if (ALWAYS_SKIPPED_FILES.has(entry.name))
254943
- continue;
254944
- if (isIgnored(relativePath, false))
254945
- continue;
254946
- results.push(relativePath);
254947
- }
254948
- return results;
254949
- }
254950
-
254951
- // src/core/deployments/modules.ts
254952
- import { stat as stat2 } from "node:fs/promises";
254953
- import { relative as relative3, resolve as resolve4, sep } from "node:path";
254954
- var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
254955
- var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
254956
- var RULE_TYPE_TO_MODULE_TYPE = {
254957
- ESModule: "esm",
254958
- CompiledWasm: "wasm",
254959
- Text: "text",
254960
- Data: "data"
254961
- };
254962
- function toPosix(path16) {
254963
- return path16.split(sep).join("/");
254964
- }
254965
- async function collectModules(config12) {
254966
- const entryPath = resolve4(config12.configDir, config12.main);
254967
- if (!await pathExists(entryPath)) {
254968
- throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config12.configPath})`, {
254969
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
254970
- });
254971
- }
254972
- const modulesByName = new Map;
254973
- const entryName = toPosix(relative3(config12.configDir, entryPath));
254974
- modulesByName.set(entryName, {
254975
- name: entryName,
254976
- absolutePath: entryPath,
254977
- size: 0,
254978
- type: "esm"
254979
- });
254980
- const ignore = [...MODULE_IGNORE];
254981
- if (config12.assetsDirectory?.startsWith(config12.configDir + sep)) {
254982
- ignore.push(`${toPosix(relative3(config12.configDir, config12.assetsDirectory))}/**`);
254983
- }
254984
- for (const rule of config12.rules) {
254985
- const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
254986
- if (!type) {
254987
- throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config12.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
254988
- }
254989
- const matches = await globby(rule.globs, {
254990
- cwd: config12.configDir,
254991
- onlyFiles: true,
254992
- dot: true,
254993
- ignore
254994
- });
254995
- for (const match of matches.sort()) {
254996
- if (!modulesByName.has(match)) {
254997
- modulesByName.set(match, {
254998
- name: match,
254999
- absolutePath: resolve4(config12.configDir, match),
255000
- size: 0,
255001
- type
255002
- });
255003
- }
255004
- }
255005
- }
255006
- if (config12.uploadSourceMaps) {
255007
- const maps = await globby("**/*.map", {
255008
- cwd: config12.configDir,
255009
- onlyFiles: true,
255010
- dot: true,
255011
- ignore
255012
- });
255013
- for (const map2 of maps.sort()) {
255014
- addSourcemap(modulesByName, config12.configDir, map2);
255015
- }
255016
- } else {
255017
- for (const name2 of [...modulesByName.keys()]) {
255018
- const mapName = `${name2}.map`;
255019
- if (await pathExists(resolve4(config12.configDir, mapName))) {
255020
- addSourcemap(modulesByName, config12.configDir, mapName);
255021
- }
255022
- }
255023
- }
255024
- const modules = [...modulesByName.values()];
255025
- let totalBytes = 0;
255026
- for (const module of modules) {
255027
- module.size = (await stat2(module.absolutePath)).size;
255028
- totalBytes += module.size;
255029
- }
255030
- if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
255031
- throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for Base44 full-stack deploys.`);
255032
- }
255033
- return modules;
255034
- }
255035
- function addSourcemap(modulesByName, configDir, name2) {
255036
- if (modulesByName.has(name2))
255037
- return;
255038
- modulesByName.set(name2, {
255039
- name: name2,
255040
- absolutePath: resolve4(configDir, name2),
255041
- size: 0,
255042
- type: "sourcemap"
255043
- });
255044
- }
255045
-
255046
- // src/core/deployments/upload.ts
255047
- import { readFile as readFile4 } from "node:fs/promises";
255048
- var BUCKET_CONCURRENCY = 3;
255049
- var MAX_ATTEMPTS_PER_BUCKET = 3;
255050
- var RETRY_BASE_DELAY_MS = 500;
255051
- var MAX_RATE_LIMIT_WAITS = 10;
255052
- var RATE_LIMIT_DELAY_MS = 15000;
255053
- async function uploadAssetBuckets(deploymentId, buckets, filesByHash, onProgress) {
255054
- if (buckets.length === 0) {
255055
- return null;
255056
- }
255057
- const totalFiles = buckets.reduce((sum, bucket) => sum + bucket.length, 0);
255058
- let uploadedFiles = 0;
255059
- let completedBuckets = 0;
255060
- let completionJwt = null;
255061
- let nextBucket = 0;
255062
- const worker = async () => {
255063
- while (nextBucket < buckets.length) {
255064
- const bucket = buckets[nextBucket++];
255065
- const jwt3 = await uploadBucketWithRetry(deploymentId, bucket, filesByHash);
255066
- if (jwt3) {
255067
- completionJwt = jwt3;
255068
- }
255069
- uploadedFiles += bucket.length;
255070
- completedBuckets++;
255071
- onProgress?.({
255072
- uploadedFiles,
255073
- totalFiles,
255074
- completedBuckets,
255075
- totalBuckets: buckets.length
255076
- });
255077
- }
255078
- };
255079
- await Promise.all(Array.from({ length: Math.min(BUCKET_CONCURRENCY, buckets.length) }, worker));
255080
- if (!completionJwt) {
255081
- throw new ApiError("Asset upload finished but the server did not return a completion token.");
255082
- }
255083
- return completionJwt;
255084
- }
255085
- async function uploadBucketWithRetry(deploymentId, bucket, filesByHash) {
255086
- let lastError;
255087
- let rateLimitWaits = 0;
255088
- const formData = await buildBucketForm(bucket, filesByHash);
255089
- for (let attempt = 0;attempt < MAX_ATTEMPTS_PER_BUCKET; attempt++) {
255090
- if (attempt > 0) {
255091
- await sleep3(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
255092
- }
255093
- try {
255094
- return await uploadAssetBucket(deploymentId, formData);
255095
- } catch (error48) {
255096
- if (error48 instanceof HTTPError && error48.response.status === 429 && rateLimitWaits < MAX_RATE_LIMIT_WAITS) {
255097
- rateLimitWaits++;
255098
- attempt--;
255099
- await sleep3(RATE_LIMIT_DELAY_MS);
255100
- continue;
255101
- }
255102
- lastError = error48;
255103
- }
255104
- }
255105
- if (lastError instanceof HTTPError && lastError.response.status === 409) {
255106
- throw new ApiError("This deploy's upload session has expired — rerun deploy. Already-uploaded assets are skipped on the next attempt.", { statusCode: 409, cause: lastError });
255107
- }
255108
- throw await ApiError.fromHttpError(lastError, "uploading static assets");
255109
- }
255110
- async function buildBucketForm(bucket, filesByHash) {
255111
- const formData = new FormData;
255112
- for (const hash2 of bucket) {
255113
- const file2 = filesByHash.get(hash2);
255114
- if (!file2) {
255115
- throw new InternalError(`Server requested upload of unknown asset hash: ${hash2}`);
255116
- }
255117
- const content = await readFile4(file2.absolutePath);
255118
- formData.append(hash2, new File([content.toString("base64")], hash2, { type: file2.contentType }));
255119
- }
255120
- return formData;
255121
- }
255122
- function sleep3(ms) {
255123
- return new Promise((resolve5) => setTimeout(resolve5, ms));
255124
- }
255125
-
255126
- // src/core/deployments/wrangler-config.ts
255127
- import { dirname as dirname10, join as join16, resolve as resolve5 } from "node:path";
255128
- var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
255129
- var RedirectConfigSchema = exports_external.looseObject({
255130
- configPath: exports_external.string().min(1)
255131
- });
255132
- var BindingArraySchema = exports_external.array(exports_external.unknown()).optional();
255133
- var WranglerConfigSchema = exports_external.looseObject({
255134
- name: exports_external.string().optional(),
255135
- main: exports_external.string().min(1, "wrangler config is missing a 'main' entry module"),
255136
- no_bundle: exports_external.boolean().optional(),
255137
- rules: exports_external.array(exports_external.looseObject({ type: exports_external.string(), globs: exports_external.array(exports_external.string()) })).optional(),
255138
- assets: exports_external.looseObject({
255139
- directory: exports_external.string().optional(),
255140
- html_handling: exports_external.string().optional(),
255141
- not_found_handling: exports_external.string().optional(),
255142
- run_worker_first: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional(),
255143
- headers: exports_external.string().optional(),
255144
- redirects: exports_external.string().optional()
255145
- }).optional(),
255146
- compatibility_date: exports_external.string().optional(),
255147
- compatibility_flags: exports_external.array(exports_external.string()).optional(),
255148
- vars: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
255149
- upload_source_maps: exports_external.boolean().optional(),
255150
- kv_namespaces: BindingArraySchema,
255151
- d1_databases: BindingArraySchema,
255152
- r2_buckets: BindingArraySchema,
255153
- durable_objects: exports_external.looseObject({ bindings: BindingArraySchema }).optional(),
255154
- services: BindingArraySchema,
255155
- queues: exports_external.looseObject({
255156
- producers: BindingArraySchema,
255157
- consumers: BindingArraySchema
255158
- }).optional(),
255159
- hyperdrive: BindingArraySchema,
255160
- analytics_engine_datasets: BindingArraySchema,
255161
- vectorize: BindingArraySchema
255162
- });
255163
- async function detectFullStackArtifact(projectRoot) {
255164
- const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
255165
- if (await pathExists(redirectPath)) {
255166
- return { source: "redirect", path: redirectPath };
255167
- }
255168
- for (const name2 of ["wrangler.jsonc", "wrangler.json"]) {
255169
- const configPath = join16(projectRoot, name2);
255170
- if (await pathExists(configPath)) {
255171
- return { source: "root-config", path: configPath };
255172
- }
255173
- }
255174
- const tomlPath = join16(projectRoot, "wrangler.toml");
255175
- if (await pathExists(tomlPath)) {
255176
- return { source: "toml", path: tomlPath };
255177
- }
255178
- return null;
255179
- }
255180
- async function resolveWranglerConfig(projectRoot) {
255181
- const artifact = await detectFullStackArtifact(projectRoot);
255182
- if (!artifact) {
255183
- throw new InvalidInputError("No full-stack build artifact found. Expected a .wrangler/deploy/config.json redirect file or a root wrangler.jsonc.", {
255184
- hints: [{ message: "Run your framework's build command first" }]
255185
- });
255186
- }
255187
- if (artifact.source === "toml") {
255188
- throw new InvalidInputError("wrangler.toml is not supported for Base44 full-stack deploys. Convert your config to wrangler.jsonc.");
255189
- }
255190
- const configPath = artifact.source === "redirect" ? await resolveRedirectedConfigPath(artifact.path) : artifact.path;
255191
- const parsed = await readJsonFile(configPath);
255192
- const result = WranglerConfigSchema.safeParse(parsed);
255193
- if (!result.success) {
255194
- throw new ConfigInvalidError(`Invalid wrangler config: ${exports_external.prettifyError(result.error)}`, configPath);
255195
- }
255196
- const config12 = result.data;
255197
- if (config12.no_bundle !== true) {
255198
- throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 full-stack deploys only support pre-bundled Workers output (no_bundle: true).");
255199
- }
255200
- assertNoUnsupportedBindings(config12, configPath);
255201
- const configDir = dirname10(configPath);
255202
- const assetsDirectory = config12.assets?.directory ? resolve5(configDir, config12.assets.directory) : null;
255203
- return {
255204
- configPath,
255205
- configDir,
255206
- name: config12.name ?? null,
255207
- main: config12.main,
255208
- assetsDirectory,
255209
- assetsConfig: config12.assets ? toResolvedAssetsConfig(config12.assets) : null,
255210
- compatibilityDate: config12.compatibility_date ?? null,
255211
- compatibilityFlags: config12.compatibility_flags ?? [],
255212
- vars: config12.vars ?? {},
255213
- rules: (config12.rules ?? []).map((rule) => ({
255214
- type: rule.type,
255215
- globs: rule.globs
255216
- })),
255217
- uploadSourceMaps: config12.upload_source_maps ?? false
255218
- };
255219
- }
255220
- async function resolveRedirectedConfigPath(redirectPath) {
255221
- const parsed = await readJsonFile(redirectPath);
255222
- const result = RedirectConfigSchema.safeParse(parsed);
255223
- if (!result.success) {
255224
- throw new ConfigInvalidError(`Invalid deploy redirect file: ${exports_external.prettifyError(result.error)}`, redirectPath);
255225
- }
255226
- const configPath = resolve5(dirname10(redirectPath), result.data.configPath);
255227
- if (!await pathExists(configPath)) {
255228
- throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
255229
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
255230
- });
255231
- }
255232
- return configPath;
255233
- }
255234
- function toResolvedAssetsConfig(assets) {
255235
- return {
255236
- htmlHandling: assets.html_handling,
255237
- notFoundHandling: assets.not_found_handling,
255238
- runWorkerFirst: assets.run_worker_first,
255239
- headers: assets.headers,
255240
- redirects: assets.redirects
255241
- };
255242
- }
255243
- function assertNoUnsupportedBindings(config12, configPath) {
255244
- const bindingSources = {
255245
- kv_namespaces: config12.kv_namespaces,
255246
- d1_databases: config12.d1_databases,
255247
- r2_buckets: config12.r2_buckets,
255248
- "durable_objects.bindings": config12.durable_objects?.bindings,
255249
- services: config12.services,
255250
- "queues.producers": config12.queues?.producers,
255251
- "queues.consumers": config12.queues?.consumers,
255252
- hyperdrive: config12.hyperdrive,
255253
- analytics_engine_datasets: config12.analytics_engine_datasets,
255254
- vectorize: config12.vectorize
255255
- };
255256
- const used = Object.entries(bindingSources).filter(([, values]) => (values?.length ?? 0) > 0).map(([name2]) => name2);
255257
- if (used.length > 0) {
255258
- throw new InvalidInputError(`Unsupported bindings for Base44 full-stack deploys: ${used.join(", ")}. Remove them or file a feature request.`, {
255259
- hints: [{ message: `Edit the bindings in ${configPath}` }]
255260
- });
255261
- }
255262
- }
255263
-
255264
- // src/core/deployments/deploy.ts
255265
- async function resolveGitHash(projectRoot, explicit) {
255266
- const hash2 = explicit ?? await gitHead(projectRoot);
255267
- if (!hash2 || !GIT_HASH_PATTERN.test(hash2)) {
255268
- throw new InvalidInputError(explicit ? `'${explicit}' is not a git commit hash.` : "Full-stack deployments are addressed by the commit that produced the build, and no git commit was found.", {
255269
- hints: [
255270
- {
255271
- message: "Run the deploy from a git checkout, or pass the commit explicitly with --git-hash."
255272
- }
255273
- ]
255274
- });
255275
- }
255276
- return hash2;
255277
- }
255278
- async function gitHead(projectRoot) {
255279
- try {
255280
- const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
255281
- cwd: projectRoot
255282
- });
255283
- return stdout.trim();
255284
- } catch {
255285
- return null;
255286
- }
255287
- }
255288
- async function deployFullStack(options) {
255289
- const { projectRoot, gitHash, progress } = options;
255290
- const config12 = await resolveWranglerConfig(projectRoot);
255291
- if (!config12.compatibilityFlags.includes("nodejs_compat")) {
255292
- progress?.onWarning?.("The wrangler config has no 'nodejs_compat' compatibility flag; Node.js built-ins will be unavailable at runtime. Enable it in your framework's Cloudflare adapter settings if your server code needs Node APIs.");
255293
- }
255294
- if (config12.vars && Object.keys(config12.vars).length > 0) {
255295
- progress?.onWarning?.("wrangler 'vars' are not supported and were ignored — a worker's environment comes from the app's secrets (base44 secrets set).");
255296
- }
255297
- const modules = await collectModules(config12);
255298
- let assets = { manifest: {}, filesByHash: new Map };
255299
- if (config12.assetsDirectory && await pathExists(config12.assetsDirectory)) {
255300
- assets = await buildAssetManifest(config12.assetsDirectory, getAppContext().id);
255301
- }
255302
- const created = await createDeployment({
255303
- git_hash: gitHash,
255304
- config: {
255305
- main: config12.main,
255306
- compatibility_date: config12.compatibilityDate,
255307
- compatibility_flags: config12.compatibilityFlags,
255308
- assets: buildAssetsConfig(config12.assetsConfig, progress)
255309
- },
255310
- asset_manifest: assets.manifest
255311
- });
255312
- const totalAssets = Object.keys(assets.manifest).length;
255313
- const newAssets = new Set(created.assetBuckets.flat()).size;
255314
- progress?.onAssets?.({ totalAssets, newAssets });
255315
- const completionJwt = await uploadAssetBuckets(created.deploymentId, created.assetBuckets, assets.filesByHash, progress?.onAssetUpload);
255316
- progress?.onWorker?.({ moduleCount: modules.length });
255317
- const finalized = await finalizeDeployment(created.deploymentId, completionJwt, modules);
255318
- return { deploymentId: finalized.deploymentId, gitHash };
255319
- }
255320
- function buildAssetsConfig(assetsConfig, progress) {
255321
- if (!assetsConfig)
255322
- return null;
255323
- if (assetsConfig.headers || assetsConfig.redirects) {
255324
- progress?.onWarning?.("_headers/_redirects files are not supported yet and were ignored for this deploy.");
255325
- }
255326
- let runWorkerFirst;
255327
- if (Array.isArray(assetsConfig.runWorkerFirst)) {
255328
- progress?.onWarning?.("'run_worker_first' route patterns are not supported yet and were ignored for this deploy.");
255329
- } else {
255330
- runWorkerFirst = assetsConfig.runWorkerFirst;
255331
- }
255332
- return {
255333
- html_handling: assetsConfig.htmlHandling,
255334
- not_found_handling: assetsConfig.notFoundHandling,
255335
- run_worker_first: runWorkerFirst
255336
- };
255337
- }
255338
255432
  // src/core/utils/dependencies.ts
255339
255433
  import { spawnSync as spawnSync2 } from "node:child_process";
255340
255434
  function verifyDenoInstalled(context) {
@@ -255423,7 +255517,7 @@ async function pullAction({
255423
255517
  runTask: runTask2
255424
255518
  }) {
255425
255519
  const { project: project2 } = await readProjectConfig();
255426
- const dir = join17(dirname11(project2.configPath), project2.agentSkillsDir);
255520
+ const dir = join18(dirname11(project2.configPath), project2.agentSkillsDir);
255427
255521
  const remote = await runTask2("Fetching agent skills from Base44", () => fetchAgentSkills(), {
255428
255522
  successMessage: "Agent skills fetched successfully",
255429
255523
  errorMessage: "Failed to fetch agent skills"
@@ -255479,14 +255573,14 @@ function getAgentSkillsCommand() {
255479
255573
  }
255480
255574
 
255481
255575
  // src/cli/commands/agents/pull.ts
255482
- import { dirname as dirname12, join as join18 } from "node:path";
255576
+ import { dirname as dirname12, join as join19 } from "node:path";
255483
255577
  async function pullAgentsAction({
255484
255578
  log,
255485
255579
  runTask: runTask2
255486
255580
  }) {
255487
255581
  const { project: project2 } = await readProjectConfig();
255488
255582
  const configDir = dirname12(project2.configPath);
255489
- const agentsDir = join18(configDir, project2.agentsDir);
255583
+ const agentsDir = join19(configDir, project2.agentsDir);
255490
255584
  const remoteAgents = await runTask2("Fetching agents from Base44", async () => {
255491
255585
  return await fetchAgents();
255492
255586
  }, {
@@ -255556,12 +255650,12 @@ function getAgentsCommand() {
255556
255650
  }
255557
255651
 
255558
255652
  // src/cli/commands/auth/password-login.ts
255559
- import { dirname as dirname13, join as join19 } from "node:path";
255653
+ import { dirname as dirname13, join as join20 } from "node:path";
255560
255654
  async function passwordLoginAction({ log, runTask: runTask2 }, action) {
255561
255655
  const shouldEnable = action === "enable";
255562
255656
  const { project: project2 } = await readProjectConfig();
255563
255657
  const configDir = dirname13(project2.configPath);
255564
- const authDir = join19(configDir, project2.authDir);
255658
+ const authDir = join20(configDir, project2.authDir);
255565
255659
  const updated = await runTask2("Updating local auth config", async () => {
255566
255660
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
255567
255661
  const merged = { ...current, enableUsernamePassword: shouldEnable };
@@ -255581,14 +255675,14 @@ function getPasswordLoginCommand() {
255581
255675
  }
255582
255676
 
255583
255677
  // src/cli/commands/auth/pull.ts
255584
- import { dirname as dirname14, join as join20 } from "node:path";
255678
+ import { dirname as dirname14, join as join21 } from "node:path";
255585
255679
  async function pullAuthAction({
255586
255680
  log,
255587
255681
  runTask: runTask2
255588
255682
  }) {
255589
255683
  const { project: project2 } = await readProjectConfig();
255590
255684
  const configDir = dirname14(project2.configPath);
255591
- const authDir = join20(configDir, project2.authDir);
255685
+ const authDir = join21(configDir, project2.authDir);
255592
255686
  const remoteConfig = await runTask2("Fetching auth config from Base44", async () => {
255593
255687
  return await pullAuthConfig();
255594
255688
  }, {
@@ -255652,7 +255746,7 @@ function getAuthPushCommand() {
255652
255746
  }
255653
255747
 
255654
255748
  // src/cli/commands/auth/social-login.ts
255655
- import { dirname as dirname15, join as join21, resolve as resolve6 } from "node:path";
255749
+ import { dirname as dirname15, join as join22, resolve as resolve7 } from "node:path";
255656
255750
  var PROVIDER_LABELS = {
255657
255751
  google: "Google",
255658
255752
  microsoft: "Microsoft",
@@ -255692,7 +255786,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask: runTask2 }, p
255692
255786
  let clientSecret;
255693
255787
  if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
255694
255788
  if (options.envFile) {
255695
- const secrets = await parseEnvFile(resolve6(options.envFile));
255789
+ const secrets = await parseEnvFile(resolve7(options.envFile));
255696
255790
  const value = secrets[oauthCli.envVar];
255697
255791
  if (!value) {
255698
255792
  throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
@@ -255723,7 +255817,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask: runTask2 }, p
255723
255817
  }
255724
255818
  const { project: project2 } = await readProjectConfig();
255725
255819
  const configDir = dirname15(project2.configPath);
255726
- const authDir = join21(configDir, project2.authDir);
255820
+ const authDir = join22(configDir, project2.authDir);
255727
255821
  const { config: updated } = await runTask2("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
255728
255822
  if (clientSecret) {
255729
255823
  await runTask2("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
@@ -255748,7 +255842,7 @@ function getSocialLoginCommand() {
255748
255842
  }
255749
255843
 
255750
255844
  // src/cli/commands/auth/sso.ts
255751
- import { dirname as dirname16, join as join22, resolve as resolve7 } from "node:path";
255845
+ import { dirname as dirname16, join as join23, resolve as resolve8 } from "node:path";
255752
255846
  var SSOConfigFileSchema = exports_external.object({
255753
255847
  provider: exports_external.enum(Object.values(KNOWN_SSO_PROVIDERS)),
255754
255848
  clientId: exports_external.string(),
@@ -255764,7 +255858,7 @@ var SSOConfigFileSchema = exports_external.object({
255764
255858
  ssoName: exports_external.string().optional()
255765
255859
  });
255766
255860
  async function loadSSOConfigFile(filePath) {
255767
- const resolved = resolve7(filePath);
255861
+ const resolved = resolve8(filePath);
255768
255862
  const raw2 = await readJsonFile(resolved);
255769
255863
  const result = SSOConfigFileSchema.safeParse(raw2);
255770
255864
  if (!result.success) {
@@ -255852,7 +255946,7 @@ async function ssoEnableAction({ isNonInteractive, runTask: runTask2 }, options)
255852
255946
  }
255853
255947
  let clientSecret;
255854
255948
  if (merged.envFile && !merged.clientSecret) {
255855
- const secrets2 = await parseEnvFile(resolve7(merged.envFile));
255949
+ const secrets2 = await parseEnvFile(resolve8(merged.envFile));
255856
255950
  const value = secrets2.sso_client_secret;
255857
255951
  if (!value) {
255858
255952
  throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
@@ -255912,7 +256006,7 @@ async function ssoEnableAction({ isNonInteractive, runTask: runTask2 }, options)
255912
256006
  }
255913
256007
  const { project: project2 } = await readProjectConfig();
255914
256008
  const configDir = dirname16(project2.configPath);
255915
- const authDir = join22(configDir, project2.authDir);
256009
+ const authDir = join23(configDir, project2.authDir);
255916
256010
  await runTask2("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
255917
256011
  await runTask2("Saving SSO credentials", async () => pushSSOSecrets(secrets));
255918
256012
  return {
@@ -255928,7 +256022,7 @@ async function ssoDisableAction({ log, runTask: runTask2 }, options) {
255928
256022
  }
255929
256023
  const { project: project2 } = await readProjectConfig();
255930
256024
  const configDir = dirname16(project2.configPath);
255931
- const authDir = join22(configDir, project2.authDir);
256025
+ const authDir = join23(configDir, project2.authDir);
255932
256026
  const updated = await runTask2("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
255933
256027
  await runTask2("Removing SSO credentials", async () => deleteSSOSecrets());
255934
256028
  if (!hasAnyLoginMethod(updated)) {
@@ -256490,19 +256584,19 @@ var baseOpen = async (options) => {
256490
256584
  }
256491
256585
  const subprocess = childProcess3.spawn(command2, cliArguments, childProcessOptions);
256492
256586
  if (options.wait) {
256493
- return new Promise((resolve8, reject) => {
256587
+ return new Promise((resolve9, reject) => {
256494
256588
  subprocess.once("error", reject);
256495
256589
  subprocess.once("close", (exitCode) => {
256496
256590
  if (!options.allowNonzeroExitCode && exitCode !== 0) {
256497
256591
  reject(new Error(`Exited with code ${exitCode}`));
256498
256592
  return;
256499
256593
  }
256500
- resolve8(subprocess);
256594
+ resolve9(subprocess);
256501
256595
  });
256502
256596
  });
256503
256597
  }
256504
256598
  if (isFallbackAttempt) {
256505
- return new Promise((resolve8, reject) => {
256599
+ return new Promise((resolve9, reject) => {
256506
256600
  subprocess.once("error", reject);
256507
256601
  subprocess.once("spawn", () => {
256508
256602
  subprocess.once("close", (exitCode) => {
@@ -256512,17 +256606,17 @@ var baseOpen = async (options) => {
256512
256606
  return;
256513
256607
  }
256514
256608
  subprocess.unref();
256515
- resolve8(subprocess);
256609
+ resolve9(subprocess);
256516
256610
  });
256517
256611
  });
256518
256612
  });
256519
256613
  }
256520
256614
  subprocess.unref();
256521
- return new Promise((resolve8, reject) => {
256615
+ return new Promise((resolve9, reject) => {
256522
256616
  subprocess.once("error", reject);
256523
256617
  subprocess.once("spawn", () => {
256524
256618
  subprocess.off("error", reject);
256525
- resolve8(subprocess);
256619
+ resolve9(subprocess);
256526
256620
  });
256527
256621
  });
256528
256622
  };
@@ -256785,13 +256879,13 @@ function getConnectorsListAvailableCommand() {
256785
256879
  }
256786
256880
 
256787
256881
  // src/cli/commands/connectors/pull.ts
256788
- import { dirname as dirname17, join as join23, resolve as resolve8 } from "node:path";
256882
+ import { dirname as dirname17, join as join24, resolve as resolve9 } from "node:path";
256789
256883
  async function resolveConnectorsDir(options) {
256790
256884
  if (!getAppContext().projectRoot) {
256791
- return resolve8(options.dir ?? "connectors");
256885
+ return resolve9(options.dir ?? "connectors");
256792
256886
  }
256793
256887
  const { project: project2 } = await readProjectConfig();
256794
- return join23(dirname17(project2.configPath), project2.connectorsDir);
256888
+ return join24(dirname17(project2.configPath), project2.connectorsDir);
256795
256889
  }
256796
256890
  async function pullConnectorsAction({ log, runTask: runTask2, jsonMode }, options) {
256797
256891
  const connectorsDir = await resolveConnectorsDir(options);
@@ -256832,10 +256926,10 @@ function getConnectorsPullCommand() {
256832
256926
  }
256833
256927
 
256834
256928
  // src/cli/commands/connectors/push.ts
256835
- import { resolve as resolve9 } from "node:path";
256929
+ import { resolve as resolve10 } from "node:path";
256836
256930
  async function readConnectorsToPush(options) {
256837
256931
  if (!getAppContext().projectRoot) {
256838
- return readAllConnectors(resolve9(options.dir ?? "connectors"));
256932
+ return readAllConnectors(resolve10(options.dir ?? "connectors"));
256839
256933
  }
256840
256934
  const { connectors } = await readProjectConfig();
256841
256935
  return connectors;
@@ -257051,7 +257145,7 @@ async function removeDomain(hostname3) {
257051
257145
  }
257052
257146
  return result.data;
257053
257147
  }
257054
- var delay2 = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
257148
+ var delay2 = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
257055
257149
  async function waitForDomainActive(hostname3, options = {}) {
257056
257150
  const intervalMs = options.intervalMs ?? 2000;
257057
257151
  const timeoutMs = options.timeoutMs ?? 10 * 60000;
@@ -257407,11 +257501,11 @@ function getListCommand() {
257407
257501
  }
257408
257502
 
257409
257503
  // src/cli/commands/functions/pull.ts
257410
- import { dirname as dirname18, join as join24 } from "node:path";
257504
+ import { dirname as dirname18, join as join25 } from "node:path";
257411
257505
  async function pullFunctionsAction({ log, runTask: runTask2 }, name2) {
257412
257506
  const { project: project2, functions } = await readProjectConfig();
257413
257507
  const configDir = dirname18(project2.configPath);
257414
- const functionsDir = join24(configDir, project2.functionsDir);
257508
+ const functionsDir = join25(configDir, project2.functionsDir);
257415
257509
  const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
257416
257510
  const remoteFunctions = await runTask2("Fetching functions from Base44", async () => {
257417
257511
  const { functions: functions2 } = await listDeployedFunctions();
@@ -257469,12 +257563,86 @@ function getFunctionsCommand() {
257469
257563
  return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand()).addCommand(getDeleteCommand()).addCommand(getListCommand()).addCommand(getPullCommand());
257470
257564
  }
257471
257565
 
257566
+ // src/cli/commands/project/site-build.ts
257567
+ async function runSiteBuild({ runTask: runTask2 }, { root, buildCommand, appId }) {
257568
+ if (!buildCommand) {
257569
+ throw new ConfigNotFoundError("No site build command found.", {
257570
+ hints: [
257571
+ {
257572
+ message: `Add 'site.buildCommand' to your config.jsonc (e.g., "site": { "buildCommand": "npm run build" })`
257573
+ }
257574
+ ]
257575
+ });
257576
+ }
257577
+ await runTask2("Building site...", () => execa({
257578
+ cwd: root,
257579
+ shell: true,
257580
+ env: { VITE_BASE44_APP_ID: appId }
257581
+ })`${buildCommand}`, {
257582
+ successMessage: "Site built successfully",
257583
+ errorMessage: "Build failed"
257584
+ });
257585
+ }
257586
+ async function maybeBuildBeforeDeploy(ctx, project2, build) {
257587
+ if (!ctx.app) {
257588
+ return;
257589
+ }
257590
+ if (build === true) {
257591
+ await runSiteBuild(ctx, {
257592
+ root: project2.root,
257593
+ buildCommand: project2.site?.buildCommand,
257594
+ appId: ctx.app.id
257595
+ });
257596
+ return;
257597
+ }
257598
+ if (build === false || !project2.site?.outputDirectory) {
257599
+ return;
257600
+ }
257601
+ const shouldBuild = await shouldAskToBuild(ctx.isNonInteractive, project2.site.buildCommand);
257602
+ if (shouldBuild) {
257603
+ await runSiteBuild(ctx, {
257604
+ root: project2.root,
257605
+ buildCommand: project2.site.buildCommand,
257606
+ appId: ctx.app.id
257607
+ });
257608
+ }
257609
+ }
257610
+ async function shouldAskToBuild(isNonInteractive, buildCommand) {
257611
+ if (!buildCommand || isNonInteractive) {
257612
+ return false;
257613
+ }
257614
+ const answer = await Re({
257615
+ message: `Build the site first? (runs '${buildCommand}' with your app id)`
257616
+ });
257617
+ return !Ct(answer) && answer;
257618
+ }
257619
+
257620
+ // src/cli/commands/project/build.ts
257621
+ async function buildAction(ctx) {
257622
+ const { app } = ctx;
257623
+ if (!app?.projectRoot) {
257624
+ throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
257625
+ }
257626
+ const { project: project2 } = await readProjectConfig(app.projectRoot);
257627
+ await runSiteBuild(ctx, {
257628
+ root: project2.root,
257629
+ buildCommand: project2.site?.buildCommand,
257630
+ appId: app.id
257631
+ });
257632
+ return {
257633
+ outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
257634
+ };
257635
+ }
257636
+ function getBuildCommand() {
257637
+ return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
257638
+ }
257639
+
257472
257640
  // src/cli/commands/project/create.ts
257473
- import { basename as basename4, resolve as resolve10 } from "node:path";
257641
+ import { basename as basename4, resolve as resolve11 } from "node:path";
257474
257642
  var import_kebabCase = __toESM(require_kebabCase(), 1);
257475
257643
 
257476
257644
  // src/cli/commands/project/scaffold-shared.ts
257477
- import { join as join25 } from "node:path";
257645
+ import { join as join26 } from "node:path";
257478
257646
  var DEFAULT_TEMPLATE_ID = "backend-only";
257479
257647
  async function getTemplateById(templateId) {
257480
257648
  const templates = await listTemplates();
@@ -257533,7 +257701,7 @@ async function completeProjectSetup({
257533
257701
  updateMessage("Building project...");
257534
257702
  await execa({ cwd: resolvedPath, shell: true })`${buildCommand}`;
257535
257703
  updateMessage("Deploying site...");
257536
- return await deploySite(join25(resolvedPath, outputDirectory));
257704
+ return await deploySite(join26(resolvedPath, outputDirectory));
257537
257705
  }, {
257538
257706
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
257539
257707
  errorMessage: "Failed to deploy site"
@@ -257662,7 +257830,7 @@ async function createInteractive(options, ctx) {
257662
257830
  }, ctx);
257663
257831
  }
257664
257832
  async function createNonInteractive(options, ctx) {
257665
- ctx.log.info(`Creating a new project at ${resolve10(options.path)}`);
257833
+ ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
257666
257834
  const template2 = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
257667
257835
  return await executeCreate({
257668
257836
  template: template2,
@@ -257686,7 +257854,7 @@ async function executeCreate({
257686
257854
  }, ctx) {
257687
257855
  const { log, runTask: runTask2 } = ctx;
257688
257856
  const name2 = rawName.trim();
257689
- const resolvedPath = resolve10(projectPath);
257857
+ const resolvedPath = resolve11(projectPath);
257690
257858
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
257691
257859
  const { projectId } = await runTask2("Setting up your project...", async () => {
257692
257860
  return await createProjectFiles({
@@ -257736,21 +257904,72 @@ Examples:
257736
257904
  $ base44 create my-app --workspace 507f1f77bcf86cd799439011 Creates a base44 project in the given workspace`).hook("preAction", validateCreateOptions).action(createAction);
257737
257905
  }
257738
257906
 
257907
+ // src/cli/commands/site/run-app-deploy.ts
257908
+ var TASK_LABELS = {
257909
+ "full-stack": {
257910
+ start: "Deploying full-stack app...",
257911
+ success: theme.colors.base44Orange("Full-stack app deployed"),
257912
+ error: "Full-stack deploy failed"
257913
+ },
257914
+ "static-deployment": {
257915
+ start: "Deploying site...",
257916
+ success: "Site deployed",
257917
+ error: "Site deploy failed"
257918
+ },
257919
+ static: {
257920
+ start: "Creating archive and deploying site...",
257921
+ success: "Site deployed successfully",
257922
+ error: "Deployment failed"
257923
+ }
257924
+ };
257925
+ async function runAppSiteDeploy({ runTask: runTask2, log }, target, options = {}) {
257926
+ const kind = await detectAppDeployKind(target);
257927
+ if (kind === "none")
257928
+ return { kind: "none" };
257929
+ const labels = TASK_LABELS[kind];
257930
+ const progressLines = [];
257931
+ const warnings = [];
257932
+ const result = await runTask2(labels.start, async (updateMessage) => await deployAppSite(target, {
257933
+ gitHash: options.gitHash,
257934
+ progress: {
257935
+ onWarning: (message) => {
257936
+ warnings.push(message);
257937
+ },
257938
+ onAssets: ({ totalAssets, newAssets }) => {
257939
+ const line = `Found ${totalAssets} static assets (${newAssets} new)`;
257940
+ progressLines.push(line);
257941
+ updateMessage(line);
257942
+ },
257943
+ onAssetUpload: ({ uploadedFiles, totalFiles }) => {
257944
+ updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
257945
+ },
257946
+ onWorker: ({ moduleCount }) => {
257947
+ updateMessage(`Deploying worker (${moduleCount} modules)…`);
257948
+ }
257949
+ }
257950
+ }), {
257951
+ successMessage: labels.success,
257952
+ errorMessage: labels.error
257953
+ });
257954
+ for (const line of progressLines) {
257955
+ log.message(theme.styles.dim(line));
257956
+ }
257957
+ for (const warning of warnings) {
257958
+ log.warn(warning);
257959
+ }
257960
+ return result;
257961
+ }
257962
+
257739
257963
  // src/cli/commands/project/deploy.ts
257740
- import { resolve as resolve11 } from "node:path";
257741
257964
  async function deployAction(ctx, options = {}) {
257742
257965
  const { isNonInteractive, log } = ctx;
257743
257966
  if (isNonInteractive && !options.yes) {
257744
257967
  throw new InvalidInputError("--yes is required in non-interactive mode");
257745
257968
  }
257746
- if (options.build && options.prebuilt) {
257747
- throw new InvalidInputError("--build and --prebuilt cannot be combined.");
257748
- }
257749
257969
  const projectData = await readProjectConfig(options.projectRoot);
257750
257970
  const { project: project2, entities, functions, agents, connectors, authConfig } = projectData;
257751
- let fullStackArtifact = await detectFullStackArtifact(project2.root);
257752
- const isFullStackCandidate = fullStackArtifact !== null || Boolean(project2.site?.buildCommand);
257753
- if (!hasResourcesToDeploy(projectData) && !isFullStackCandidate) {
257971
+ const plannedSite = await detectAppDeployKind(project2);
257972
+ if (!hasResourcesToDeploy(projectData) && plannedSite === "none") {
257754
257973
  return {
257755
257974
  outroMessage: "No resources found to deploy"
257756
257975
  };
@@ -257774,7 +257993,7 @@ async function deployAction(ctx, options = {}) {
257774
257993
  if (project2.visibility) {
257775
257994
  summaryLines.push(` - Visibility: ${project2.visibility}`);
257776
257995
  }
257777
- if (fullStackArtifact) {
257996
+ if (plannedSite === "full-stack") {
257778
257997
  summaryLines.push(" - Full-stack app");
257779
257998
  } else if (project2.site?.outputDirectory) {
257780
257999
  summaryLines.push(` - Site from ${project2.site.outputDirectory}`);
@@ -257794,6 +258013,7 @@ ${summaryLines.join(`
257794
258013
  ${summaryLines.join(`
257795
258014
  `)}`);
257796
258015
  }
258016
+ await maybeBuildBeforeDeploy(ctx, project2, options.build);
257797
258017
  let functionCompleted = 0;
257798
258018
  const functionTotal = functions.length;
257799
258019
  const result = await deployAll(projectData, {
@@ -257810,16 +258030,9 @@ ${summaryLines.join(`
257810
258030
  formatDeployResult(r, log);
257811
258031
  }
257812
258032
  });
257813
- await buildSiteIfNeeded(ctx, projectData, options, fullStackArtifact);
257814
- fullStackArtifact = await detectFullStackArtifact(project2.root);
257815
- let appUrl;
257816
- let fullStackResult;
257817
- if (fullStackArtifact) {
257818
- fullStackResult = await runFullStackDeploy(ctx, project2.root, options);
257819
- } else if (project2.site?.outputDirectory) {
257820
- const outputDir = resolve11(project2.root, project2.site.outputDirectory);
257821
- ({ appUrl } = await deploySite(outputDir));
257822
- }
258033
+ const siteResult = await runAppSiteDeploy(ctx, project2, {
258034
+ gitHash: options.gitHash
258035
+ });
257823
258036
  const connectorResults = result.connectorResults ?? [];
257824
258037
  await handleOAuthConnectors(connectorResults, isNonInteractive, options, log);
257825
258038
  const stripeResult = connectorResults.find((r) => r.type === "stripe");
@@ -257827,80 +258040,27 @@ ${summaryLines.join(`
257827
258040
  printStripeResult(stripeResult, log);
257828
258041
  }
257829
258042
  log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
257830
- if (appUrl) {
257831
- log.message(`${theme.styles.header("App URL")}: ${theme.colors.links(appUrl)}`);
258043
+ if (siteResult.kind === "static") {
258044
+ log.message(`${theme.styles.header("App URL")}: ${theme.colors.links(siteResult.appUrl)}`);
257832
258045
  }
257833
- if (fullStackResult) {
257834
- printFullStackSummary(fullStackResult, log);
258046
+ const deployment = siteResult.kind === "full-stack" || siteResult.kind === "static-deployment" ? siteResult : undefined;
258047
+ if (deployment) {
258048
+ printDeploymentSummary(deployment, log);
257835
258049
  }
257836
258050
  return {
257837
258051
  outroMessage: "App deployed successfully",
257838
- stdout: ctx.jsonMode && fullStackResult ? `${JSON.stringify({
257839
- deploymentId: fullStackResult.deploymentId,
257840
- gitHash: fullStackResult.gitHash
258052
+ stdout: ctx.jsonMode && deployment ? `${JSON.stringify({
258053
+ deploymentId: deployment.deploymentId,
258054
+ gitHash: deployment.gitHash
257841
258055
  }, null, 2)}
257842
258056
  ` : undefined
257843
258057
  };
257844
258058
  }
257845
- async function buildSiteIfNeeded({ runTask: runTask2 }, { project: project2 }, options, fullStackArtifact) {
257846
- const site2 = project2.site;
257847
- if (!site2?.buildCommand || options.prebuilt)
257848
- return;
257849
- const artifactPresent = fullStackArtifact !== null || (site2.outputDirectory ? await pathExists(resolve11(project2.root, site2.outputDirectory)) : false);
257850
- if (artifactPresent && !options.build)
257851
- return;
257852
- const { installCommand, buildCommand } = site2;
257853
- await runTask2(installCommand ? "Installing dependencies..." : "Building project...", async (updateMessage) => {
257854
- if (installCommand) {
257855
- await execa({ cwd: project2.root, shell: true })`${installCommand}`;
257856
- updateMessage("Building project...");
257857
- }
257858
- await execa({ cwd: project2.root, shell: true })`${buildCommand}`;
257859
- }, {
257860
- successMessage: "Project built successfully",
257861
- errorMessage: "Failed to build project"
257862
- });
257863
- }
257864
- async function runFullStackDeploy({ runTask: runTask2, log }, projectRoot, options) {
257865
- const gitHash = await resolveGitHash(projectRoot, options.gitHash);
257866
- const progressLines = [];
257867
- const warnings = [];
257868
- const deployment = await runTask2("Deploying full-stack app...", async (updateMessage) => await deployFullStack({
257869
- projectRoot,
257870
- gitHash,
257871
- progress: {
257872
- onWarning: (message) => {
257873
- warnings.push(message);
257874
- },
257875
- onAssets: ({ totalAssets, newAssets }) => {
257876
- const line = `Found ${totalAssets} static assets (${newAssets} new)`;
257877
- progressLines.push(line);
257878
- updateMessage(line);
257879
- },
257880
- onAssetUpload: ({ uploadedFiles, totalFiles }) => {
257881
- updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
257882
- },
257883
- onWorker: ({ moduleCount }) => {
257884
- updateMessage(`Deploying worker (${moduleCount} modules)…`);
257885
- }
257886
- }
257887
- }), {
257888
- successMessage: theme.colors.base44Orange("Full-stack app deployed"),
257889
- errorMessage: "Full-stack deploy failed"
257890
- });
257891
- for (const line of progressLines) {
257892
- log.message(theme.styles.dim(line));
257893
- }
257894
- for (const warning of warnings) {
257895
- log.warn(warning);
257896
- }
257897
- return deployment;
257898
- }
257899
- function printFullStackSummary(deployment, log) {
258059
+ function printDeploymentSummary(deployment, log) {
257900
258060
  log.message(`${theme.styles.header("Deployment")}: ${deployment.deploymentId} ${theme.styles.dim(`(commit ${deployment.gitHash.slice(0, 12)})`)}`);
257901
258061
  }
257902
258062
  function getDeployCommand2() {
257903
- return new Base44Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").option("--git-hash <hash>", "Commit the full-stack build came from (defaults to the checkout's HEAD)").option("--build", "Run the configured install/build commands before deploying, even when a build artifact already exists").option("--prebuilt", "Skip the build step and deploy the existing artifact").action(deployAction);
258063
+ return new Base44Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").option("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)").action(deployAction);
257904
258064
  }
257905
258065
  async function handleOAuthConnectors(connectorResults, isNonInteractive, options, log) {
257906
258066
  const needsOAuth = filterPendingOAuth(connectorResults);
@@ -258493,7 +258653,7 @@ async function callTool(appId, tool, payload, schema14, context, timeout2 = 6000
258493
258653
  function listDirectory(appId, params) {
258494
258654
  return callTool(appId, "list_directory", { ...params }, ListDirectoryResponseSchema, "listing directory");
258495
258655
  }
258496
- function readFile5(appId, params) {
258656
+ function readFile6(appId, params) {
258497
258657
  return callTool(appId, "read_file", { ...params }, ReadFileResponseSchema, "reading file");
258498
258658
  }
258499
258659
  function writeFile2(appId, params) {
@@ -258623,7 +258783,7 @@ async function readFileAction({ runTask: runTask2 }, paths, options) {
258623
258783
  const { id: appId } = getAppContext();
258624
258784
  const offset = parsePositiveInt(options.offset, "--offset");
258625
258785
  const limit = parsePositiveInt(options.limit, "--limit");
258626
- const result = await runTask2("Reading file", () => readFile5(appId, { paths, offset, limit }));
258786
+ const result = await runTask2("Reading file", () => readFile6(appId, { paths, offset, limit }));
258627
258787
  return { outroMessage: "Read file", stdout: toJsonStdout(result) };
258628
258788
  }
258629
258789
  function getSandboxReadFileCommand() {
@@ -258767,40 +258927,51 @@ function getSecretsCommand() {
258767
258927
  }
258768
258928
 
258769
258929
  // src/cli/commands/site/deploy.ts
258770
- import { resolve as resolve14 } from "node:path";
258771
- async function deployAction2({ isNonInteractive, runTask: runTask2 }, options) {
258930
+ async function deployAction2(ctx, options) {
258931
+ const { isNonInteractive } = ctx;
258772
258932
  if (isNonInteractive && !options.yes) {
258773
258933
  throw new InvalidInputError("--yes is required in non-interactive mode");
258774
258934
  }
258775
258935
  const { project: project2 } = await readProjectConfig();
258776
- if (!project2.site?.outputDirectory) {
258936
+ const kind = await detectAppDeployKind(project2);
258937
+ if (kind === "none") {
258777
258938
  throw new ConfigNotFoundError("No site configuration found.", {
258778
258939
  hints: [
258779
258940
  {
258780
258941
  message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
258942
+ },
258943
+ {
258944
+ message: "Full-stack apps ship from their build artifact — run your framework's build first"
258781
258945
  }
258782
258946
  ]
258783
258947
  });
258784
258948
  }
258785
- const outputDir = resolve14(project2.root, project2.site.outputDirectory);
258786
258949
  if (!options.yes) {
258787
258950
  const shouldDeploy = await Re({
258788
- message: `Deploy site from ${project2.site.outputDirectory}?`
258951
+ message: kind === "full-stack" ? "Deploy full-stack app?" : `Deploy site from ${project2.site?.outputDirectory}?`
258789
258952
  });
258790
258953
  if (Ct(shouldDeploy) || !shouldDeploy) {
258791
258954
  return { outroMessage: "Deployment cancelled" };
258792
258955
  }
258793
258956
  }
258794
- const result = await runTask2("Creating archive and deploying site...", async () => {
258795
- return await deploySite(outputDir);
258796
- }, {
258797
- successMessage: "Site deployed successfully",
258798
- errorMessage: "Deployment failed"
258957
+ await maybeBuildBeforeDeploy(ctx, project2, options.build);
258958
+ const result = await runAppSiteDeploy(ctx, project2, {
258959
+ gitHash: options.gitHash
258799
258960
  });
258800
- return { outroMessage: `Visit your site at: ${result.appUrl}` };
258961
+ if (result.kind === "full-stack" || result.kind === "static-deployment") {
258962
+ return {
258963
+ outroMessage: `Deployment ${result.deploymentId} (commit ${result.gitHash.slice(0, 12)})`,
258964
+ stdout: ctx.jsonMode ? `${JSON.stringify({ deploymentId: result.deploymentId, gitHash: result.gitHash }, null, 2)}
258965
+ ` : undefined
258966
+ };
258967
+ }
258968
+ if (result.kind === "static") {
258969
+ return { outroMessage: `Visit your site at: ${result.appUrl}` };
258970
+ }
258971
+ return { outroMessage: "Nothing to deploy" };
258801
258972
  }
258802
258973
  function getSiteDeployCommand() {
258803
- return new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(deployAction2);
258974
+ return new Base44Command("deploy").description("Deploy the built site to Base44 hosting (full-stack apps deploy their Workers build)").option("-y, --yes", "Skip confirmation prompt").option("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)").action(deployAction2);
258804
258975
  }
258805
258976
 
258806
258977
  // src/cli/commands/site/open.ts
@@ -259037,10 +259208,10 @@ function toPascalCase(name2) {
259037
259208
  return name2.split(/[-_\s]+/).map((w8) => w8.charAt(0).toUpperCase() + w8.slice(1)).join("");
259038
259209
  }
259039
259210
  // src/core/types/update-project.ts
259040
- import { join as join28 } from "node:path";
259211
+ import { join as join29 } from "node:path";
259041
259212
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
259042
259213
  async function updateProjectConfig(projectRoot) {
259043
- const tsconfigPath = join28(projectRoot, "tsconfig.json");
259214
+ const tsconfigPath = join29(projectRoot, "tsconfig.json");
259044
259215
  if (!await pathExists(tsconfigPath)) {
259045
259216
  return false;
259046
259217
  }
@@ -259275,7 +259446,7 @@ function createDevLogger(label2, labelColor = theme.styles.dim) {
259275
259446
  // src/cli/dev/dev-server/main.ts
259276
259447
  var import_cors = __toESM(require_lib4(), 1);
259277
259448
  var import_express6 = __toESM(require_express(), 1);
259278
- import { dirname as dirname24, join as join35 } from "node:path";
259449
+ import { dirname as dirname24, join as join36 } from "node:path";
259279
259450
 
259280
259451
  // ../../node_modules/get-port/index.js
259281
259452
  import net from "node:net";
@@ -259302,14 +259473,14 @@ var getLocalHosts = () => {
259302
259473
  }
259303
259474
  return results;
259304
259475
  };
259305
- var checkAvailablePort = (options8) => new Promise((resolve16, reject) => {
259476
+ var checkAvailablePort = (options8) => new Promise((resolve15, reject) => {
259306
259477
  const server = net.createServer();
259307
259478
  server.unref();
259308
259479
  server.on("error", reject);
259309
259480
  server.listen(options8, () => {
259310
259481
  const { port } = server.address();
259311
259482
  server.close(() => {
259312
- resolve16(port);
259483
+ resolve15(port);
259313
259484
  });
259314
259485
  });
259315
259486
  });
@@ -259410,7 +259581,7 @@ var $setGracefulCleanup = tmp.setGracefulCleanup;
259410
259581
 
259411
259582
  // src/cli/dev/dev-server/function-manager.ts
259412
259583
  import { spawn as spawn2 } from "node:child_process";
259413
- import { dirname as dirname21, join as join29 } from "node:path";
259584
+ import { dirname as dirname21, join as join30 } from "node:path";
259414
259585
  import { pathToFileURL } from "node:url";
259415
259586
 
259416
259587
  // src/cli/dev/dev-server/base-function-manager.ts
@@ -259515,7 +259686,7 @@ class FunctionManager extends BaseFunctionManager {
259515
259686
  }
259516
259687
  spawnFunction(func, port) {
259517
259688
  this.logger.log(`Spawning function "${func.name}" on port ${port}`);
259518
- const importMapPath = join29(dirname21(this.wrapperPath), "import-map.json");
259689
+ const importMapPath = join30(dirname21(this.wrapperPath), "import-map.json");
259519
259690
  const process23 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
259520
259691
  env: {
259521
259692
  ...globalThis.process.env,
@@ -259554,7 +259725,7 @@ class FunctionManager extends BaseFunctionManager {
259554
259725
  });
259555
259726
  }
259556
259727
  waitForReady(name2, runningFunc) {
259557
- return new Promise((resolve16, reject) => {
259728
+ return new Promise((resolve15, reject) => {
259558
259729
  runningFunc.process.on("exit", (code2) => {
259559
259730
  if (!runningFunc.ready) {
259560
259731
  clearTimeout(timeout3);
@@ -259577,7 +259748,7 @@ class FunctionManager extends BaseFunctionManager {
259577
259748
  runningFunc.ready = true;
259578
259749
  clearTimeout(timeout3);
259579
259750
  runningFunc.process.stdout?.off("data", onData);
259580
- resolve16(runningFunc.port);
259751
+ resolve15(runningFunc.port);
259581
259752
  }
259582
259753
  };
259583
259754
  runningFunc.process.stdout?.on("data", onData);
@@ -259589,7 +259760,7 @@ class FunctionManager extends BaseFunctionManager {
259589
259760
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
259590
259761
  import { isBuiltin } from "node:module";
259591
259762
  import { homedir as homedir3 } from "node:os";
259592
- import { join as join30 } from "node:path";
259763
+ import { join as join31 } from "node:path";
259593
259764
  import { pathToFileURL as pathToFileURL6 } from "node:url";
259594
259765
  var depsPromise;
259595
259766
  function loadDeps() {
@@ -259710,9 +259881,9 @@ export default {
259710
259881
  };
259711
259882
  `;
259712
259883
  function ensureBundlerConfig() {
259713
- const dir = join30(homedir3(), ".base44", "function-bundler");
259884
+ const dir = join31(homedir3(), ".base44", "function-bundler");
259714
259885
  mkdirSync2(dir, { recursive: true });
259715
- const configPath = join30(dir, "deno.json");
259886
+ const configPath = join31(dir, "deno.json");
259716
259887
  writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
259717
259888
  `);
259718
259889
  return configPath;
@@ -262011,7 +262182,7 @@ class NodeFsHandler {
262011
262182
  this._addToNodeFs(path19, initialAdd, wh2, depth + 1);
262012
262183
  }
262013
262184
  }).on(EV.ERROR, this._boundHandleError);
262014
- return new Promise((resolve17, reject) => {
262185
+ return new Promise((resolve16, reject) => {
262015
262186
  if (!stream)
262016
262187
  return reject();
262017
262188
  stream.once(STR_END, () => {
@@ -262020,7 +262191,7 @@ class NodeFsHandler {
262020
262191
  return;
262021
262192
  }
262022
262193
  const wasThrottled = throttler ? throttler.clear() : false;
262023
- resolve17(undefined);
262194
+ resolve16(undefined);
262024
262195
  previous.getChildren().filter((item) => {
262025
262196
  return item !== directory && !current.has(item);
262026
262197
  }).forEach((item) => {
@@ -262937,7 +263108,7 @@ async function createDevServer(options8) {
262937
263108
  }
262938
263109
  remoteProxy(req, res, next);
262939
263110
  });
262940
- const server = await new Promise((resolve18, reject) => {
263111
+ const server = await new Promise((resolve17, reject) => {
262941
263112
  const s5 = app.listen(port, "127.0.0.1", (err) => {
262942
263113
  if (err) {
262943
263114
  if ("code" in err && err.code === "EADDRINUSE") {
@@ -262946,7 +263117,7 @@ async function createDevServer(options8) {
262946
263117
  reject(err);
262947
263118
  }
262948
263119
  } else {
262949
- resolve18(s5);
263120
+ resolve17(s5);
262950
263121
  }
262951
263122
  });
262952
263123
  });
@@ -262955,8 +263126,8 @@ async function createDevServer(options8) {
262955
263126
  broadcastEntityEvent(io6, appId, entityName, event);
262956
263127
  };
262957
263128
  const base44ConfigWatcher = new WatchBase44({
262958
- functions: join35(dirname24(project2.configPath), project2.functionsDir),
262959
- entities: join35(dirname24(project2.configPath), project2.entitiesDir)
263129
+ functions: join36(dirname24(project2.configPath), project2.functionsDir),
263130
+ entities: join36(dirname24(project2.configPath), project2.entitiesDir)
262960
263131
  }, devLogger);
262961
263132
  base44ConfigWatcher.on("change", async (name2) => {
262962
263133
  try {
@@ -262996,13 +263167,13 @@ async function createDevServer(options8) {
262996
263167
  if (!server.listening) {
262997
263168
  return;
262998
263169
  }
262999
- await new Promise((resolve18, reject) => {
263170
+ await new Promise((resolve17, reject) => {
263000
263171
  server.close((error48) => {
263001
263172
  if (error48) {
263002
263173
  reject(error48);
263003
263174
  return;
263004
263175
  }
263005
- resolve18();
263176
+ resolve17();
263006
263177
  });
263007
263178
  });
263008
263179
  };
@@ -263073,15 +263244,15 @@ class ServeRunner {
263073
263244
  return;
263074
263245
  }
263075
263246
  this.stopping = true;
263076
- const exited = new Promise((resolve18) => child.once("exit", () => resolve18()));
263247
+ const exited = new Promise((resolve17) => child.once("exit", () => resolve17()));
263077
263248
  if (process23.platform === "win32" && child.pid) {
263078
263249
  const taskkill = spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
263079
263250
  stdio: "ignore",
263080
263251
  windowsHide: true
263081
263252
  });
263082
- await new Promise((resolve18) => {
263083
- taskkill.once("exit", () => resolve18());
263084
- taskkill.once("error", () => resolve18());
263253
+ await new Promise((resolve17) => {
263254
+ taskkill.once("exit", () => resolve17());
263255
+ taskkill.once("error", () => resolve17());
263085
263256
  });
263086
263257
  } else if (child.pid) {
263087
263258
  try {
@@ -263251,13 +263422,13 @@ async function runScript(options8) {
263251
263422
  }
263252
263423
  // src/cli/commands/exec.ts
263253
263424
  function readStdin2() {
263254
- return new Promise((resolve18, reject) => {
263425
+ return new Promise((resolve17, reject) => {
263255
263426
  let data = "";
263256
263427
  process.stdin.setEncoding("utf-8");
263257
263428
  process.stdin.on("data", (chunk) => {
263258
263429
  data += chunk;
263259
263430
  });
263260
- process.stdin.on("end", () => resolve18(data));
263431
+ process.stdin.on("end", () => resolve17(data));
263261
263432
  process.stdin.on("error", reject);
263262
263433
  });
263263
263434
  }
@@ -263328,7 +263499,7 @@ Examples:
263328
263499
  }
263329
263500
 
263330
263501
  // src/cli/commands/project/eject.ts
263331
- import { resolve as resolve18 } from "node:path";
263502
+ import { resolve as resolve17 } from "node:path";
263332
263503
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
263333
263504
  async function eject(ctx, options8, command2) {
263334
263505
  const { log, runTask: runTask2, isNonInteractive } = ctx;
@@ -263392,7 +263563,7 @@ async function eject(ctx, options8, command2) {
263392
263563
  Ne("Operation cancelled.");
263393
263564
  throw new CLIExitError(0);
263394
263565
  }
263395
- const resolvedPath = resolve18(selectedPath);
263566
+ const resolvedPath = resolve17(selectedPath);
263396
263567
  await runTask2("Downloading your project's code...", async (updateMessage) => {
263397
263568
  await createProjectFilesForExistingProject({
263398
263569
  projectId,
@@ -263425,7 +263596,11 @@ async function eject(ctx, options8, command2) {
263425
263596
  successMessage: theme.colors.base44Orange("Project built successfully"),
263426
263597
  errorMessage: "Failed to build project"
263427
263598
  });
263428
- await deployAction(ctx, { yes: true, projectRoot: resolvedPath });
263599
+ await deployAction(ctx, {
263600
+ yes: true,
263601
+ build: false,
263602
+ projectRoot: resolvedPath
263603
+ });
263429
263604
  }
263430
263605
  }
263431
263606
  return { outroMessage: "Your new project is set and ready to use" };
@@ -263454,6 +263629,7 @@ function createProgram(context) {
263454
263629
  program2.addCommand(getCreateCommand());
263455
263630
  program2.addCommand(getScaffoldCommand());
263456
263631
  program2.addCommand(getDashboardCommand());
263632
+ program2.addCommand(getBuildCommand());
263457
263633
  program2.addCommand(getDeployCommand2());
263458
263634
  program2.addCommand(getVisibilityCommand());
263459
263635
  program2.addCommand(getLinkCommand());
@@ -265769,14 +265945,14 @@ async function addSourceContext(frames) {
265769
265945
  return frames;
265770
265946
  }
265771
265947
  function getContextLinesFromFile(path19, ranges, output) {
265772
- return new Promise((resolve19) => {
265948
+ return new Promise((resolve18) => {
265773
265949
  const stream = createReadStream2(path19);
265774
265950
  const lineReaded = createInterface2({
265775
265951
  input: stream
265776
265952
  });
265777
265953
  function destroyStreamAndResolve() {
265778
265954
  stream.destroy();
265779
- resolve19();
265955
+ resolve18();
265780
265956
  }
265781
265957
  let lineNumber = 0;
265782
265958
  let currentRangeIndex = 0;
@@ -266888,15 +267064,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
266888
267064
  return true;
266889
267065
  if (this.featureFlagsPoller === undefined)
266890
267066
  return false;
266891
- return new Promise((resolve19) => {
267067
+ return new Promise((resolve18) => {
266892
267068
  const timeout3 = setTimeout(() => {
266893
267069
  cleanup();
266894
- resolve19(false);
267070
+ resolve18(false);
266895
267071
  }, timeoutMs);
266896
267072
  const cleanup = this._events.on("localEvaluationFlagsLoaded", (count2) => {
266897
267073
  clearTimeout(timeout3);
266898
267074
  cleanup();
266899
- resolve19(count2 > 0);
267075
+ resolve18(count2 > 0);
266900
267076
  });
266901
267077
  });
266902
267078
  }
@@ -267682,7 +267858,7 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
267682
267858
  // src/cli/index.ts
267683
267859
  var __dirname4 = dirname26(fileURLToPath6(import.meta.url));
267684
267860
  async function runCLI(options8) {
267685
- ensureNpmAssets(join36(__dirname4, "../assets"));
267861
+ ensureNpmAssets(join37(__dirname4, "../assets"));
267686
267862
  const errorReporter = new ErrorReporter;
267687
267863
  errorReporter.registerProcessErrorHandlers();
267688
267864
  const jsonMode = process.argv.includes("--json");
@@ -267721,4 +267897,4 @@ export {
267721
267897
  CLIExitError
267722
267898
  };
267723
267899
 
267724
- //# debugId=8FD9B142584B37FC64756E2164756E21
267900
+ //# debugId=A9AE6B83E783C23B64756E2164756E21