@base44-preview/cli 0.1.17-pr.626.a210a49 → 0.1.17-pr.635.345b6e2

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
@@ -31177,7 +31177,7 @@ function cleanDoc(doc) {
31177
31177
  return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
31178
31178
  }
31179
31179
  function replaceEndOfLine(doc, replacement = literalline) {
31180
- return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join30(replacement, currentDoc.split(`
31180
+ return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join28(replacement, currentDoc.split(`
31181
31181
  `)) : currentDoc);
31182
31182
  }
31183
31183
  function canBreakFn(doc) {
@@ -31257,7 +31257,7 @@ function indentIfBreak(contents, options) {
31257
31257
  negate: options.negate
31258
31258
  };
31259
31259
  }
31260
- function join30(separator, docs) {
31260
+ function join28(separator, docs) {
31261
31261
  assertDoc(separator);
31262
31262
  assertDocArray(docs);
31263
31263
  const parts = [];
@@ -31968,7 +31968,7 @@ var init_doc = __esm(() => {
31968
31968
  MODE_FLAT = Symbol("MODE_FLAT");
31969
31969
  DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
31970
31970
  builders = {
31971
- join: join30,
31971
+ join: join28,
31972
31972
  line,
31973
31973
  softline,
31974
31974
  hardline,
@@ -119090,7 +119090,7 @@ import path52 from "path";
119090
119090
  import * as path42 from "path";
119091
119091
  import * as fs26 from "fs/promises";
119092
119092
  import * as path22 from "path";
119093
- import process22 from "process";
119093
+ import process23 from "process";
119094
119094
  import * as path32 from "path";
119095
119095
  import process32 from "process";
119096
119096
  import path92 from "path";
@@ -119622,7 +119622,7 @@ function partition2(array2, predicate) {
119622
119622
  return result;
119623
119623
  }
119624
119624
  async function findInDirectory(nameOrNames, { typeCheck, cwd, allowSymlinks = true, filter: filter2 }) {
119625
- const directory = toAbsolutePath(cwd) ?? process22.cwd();
119625
+ const directory = toAbsolutePath(cwd) ?? process23.cwd();
119626
119626
  const names = Array.isArray(nameOrNames) ? nameOrNames : [nameOrNames];
119627
119627
  for (const name of names) {
119628
119628
  const fileOrDirectory = path22.join(directory, name);
@@ -146002,10 +146002,10 @@ __export(exports_supports_color, {
146002
146002
  createSupportsColor: () => createSupportsColor2,
146003
146003
  default: () => supports_color_default2
146004
146004
  });
146005
- import process21 from "node:process";
146005
+ import process24 from "node:process";
146006
146006
  import os9 from "node:os";
146007
146007
  import tty4 from "node:tty";
146008
- function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process21.argv) {
146008
+ function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process24.argv) {
146009
146009
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
146010
146010
  const position = argv.indexOf(prefix + flag);
146011
146011
  const terminatorPosition = argv.indexOf("--");
@@ -146068,7 +146068,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
146068
146068
  if (env3.TERM === "dumb") {
146069
146069
  return min;
146070
146070
  }
146071
- if (process21.platform === "win32") {
146071
+ if (process24.platform === "win32") {
146072
146072
  const osRelease = os9.release().split(".");
146073
146073
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
146074
146074
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
@@ -146130,7 +146130,7 @@ function createSupportsColor2(stream, options = {}) {
146130
146130
  }
146131
146131
  var env3, flagForceColor2, supportsColor2, supports_color_default2;
146132
146132
  var init_supports_color = __esm(() => {
146133
- ({ env: env3 } = process21);
146133
+ ({ env: env3 } = process24);
146134
146134
  if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) {
146135
146135
  flagForceColor2 = 0;
146136
146136
  } else if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) {
@@ -228670,20 +228670,6 @@ function isCLIError(error) {
228670
228670
  function isUserError(error) {
228671
228671
  return error instanceof UserError;
228672
228672
  }
228673
- var STEP = Symbol.for("base44.commandStep");
228674
- async function tagStep(step, run) {
228675
- try {
228676
- return await run();
228677
- } catch (error) {
228678
- if (error !== null && typeof error === "object" && !(STEP in error) && Object.isExtensible(error)) {
228679
- Object.defineProperty(error, STEP, { value: step, enumerable: false });
228680
- }
228681
- throw error;
228682
- }
228683
- }
228684
- function stepOf(error) {
228685
- return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
228686
- }
228687
228673
 
228688
228674
  // src/core/utils/fs.ts
228689
228675
  async function pathExists(path) {
@@ -228810,7 +228796,7 @@ function normalizeBase44Env() {
228810
228796
  loadProjectEnvFiles();
228811
228797
 
228812
228798
  // src/cli/index.ts
228813
- import { dirname as dirname29, join as join39 } from "node:path";
228799
+ import { dirname as dirname28, join as join37 } from "node:path";
228814
228800
  import { fileURLToPath as fileURLToPath6 } from "node:url";
228815
228801
 
228816
228802
  // ../../node_modules/@clack/core/dist/index.mjs
@@ -230735,7 +230721,10 @@ var SiteConfigSchema = object({
230735
230721
  buildCommand: string2().default("npm run build"),
230736
230722
  serveCommand: string2().optional(),
230737
230723
  outputDirectory: string2().optional(),
230738
- installCommand: string2().default("npm install")
230724
+ installCommand: string2().default("npm install"),
230725
+ devHostFlag: string2().default("--host"),
230726
+ devHost: string2().default("0.0.0.0"),
230727
+ devPort: number2().int().min(1).max(65535).default(5173)
230739
230728
  });
230740
230729
  var PluginMetadataSchema = object({
230741
230730
  namespace: string2().min(1, "Plugin namespace cannot be empty").regex(/^[a-zA-Z0-9_-]+$/, "Plugin namespace can only contain letters, numbers, underscores, and dashes")
@@ -239619,325 +239608,11 @@ async function createArchive(pathToArchive, targetArchivePath) {
239619
239608
  import { readFile as readFile3 } from "node:fs/promises";
239620
239609
  import { join as join18 } from "node:path";
239621
239610
 
239622
- // src/core/site/modules.ts
239623
- import { stat } from "node:fs/promises";
239624
- import { relative as relative5, resolve as resolve3, sep } from "node:path";
239625
- var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
239626
- var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
239627
- var RULE_TYPE_TO_MODULE_TYPE = {
239628
- ESModule: "esm",
239629
- CompiledWasm: "wasm",
239630
- Text: "text",
239631
- Data: "data"
239632
- };
239633
- function toPosix(path) {
239634
- return path.split(sep).join("/");
239635
- }
239636
- async function collectModules(config) {
239637
- const entryPath = resolve3(config.configDir, config.main);
239638
- if (!await pathExists(entryPath)) {
239639
- throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config.configPath})`, {
239640
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
239641
- });
239642
- }
239643
- const modulesByName = new Map;
239644
- const entryName = toPosix(relative5(config.configDir, entryPath));
239645
- modulesByName.set(entryName, {
239646
- name: entryName,
239647
- absolutePath: entryPath,
239648
- size: 0,
239649
- type: "esm"
239650
- });
239651
- const ignore = [...MODULE_IGNORE];
239652
- if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
239653
- ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
239654
- }
239655
- for (const rule of config.rules) {
239656
- const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
239657
- if (!type) {
239658
- throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
239659
- }
239660
- const matches = await globby(rule.globs, {
239661
- cwd: config.configDir,
239662
- onlyFiles: true,
239663
- dot: true,
239664
- ignore
239665
- });
239666
- for (const match of matches.sort()) {
239667
- if (!modulesByName.has(match)) {
239668
- modulesByName.set(match, {
239669
- name: match,
239670
- absolutePath: resolve3(config.configDir, match),
239671
- size: 0,
239672
- type
239673
- });
239674
- }
239675
- }
239676
- }
239677
- if (config.uploadSourceMaps) {
239678
- const maps = await globby("**/*.map", {
239679
- cwd: config.configDir,
239680
- onlyFiles: true,
239681
- dot: true,
239682
- ignore
239683
- });
239684
- for (const map of maps.sort()) {
239685
- addSourcemap(modulesByName, config.configDir, map);
239686
- }
239687
- } else {
239688
- for (const name of [...modulesByName.keys()]) {
239689
- const mapName = `${name}.map`;
239690
- if (await pathExists(resolve3(config.configDir, mapName))) {
239691
- addSourcemap(modulesByName, config.configDir, mapName);
239692
- }
239693
- }
239694
- }
239695
- const modules = [...modulesByName.values()];
239696
- let totalBytes = 0;
239697
- for (const module of modules) {
239698
- module.size = (await stat(module.absolutePath)).size;
239699
- totalBytes += module.size;
239700
- }
239701
- if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
239702
- throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for a Base44 deploy.`);
239703
- }
239704
- return modules;
239705
- }
239706
- function addSourcemap(modulesByName, configDir, name) {
239707
- if (modulesByName.has(name))
239708
- return;
239709
- modulesByName.set(name, {
239710
- name,
239711
- absolutePath: resolve3(configDir, name),
239712
- size: 0,
239713
- type: "sourcemap"
239714
- });
239715
- }
239716
-
239717
- // src/core/site/wrangler-config.ts
239718
- import { dirname as dirname12, join as join16, resolve as resolve4 } from "node:path";
239719
- var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
239720
- var RedirectConfigSchema = looseObject({
239721
- configPath: string2().min(1)
239722
- });
239723
- var WranglerConfigSchema = looseObject({
239724
- main: string2().min(1, "wrangler config is missing a 'main' entry module"),
239725
- no_bundle: boolean2().optional(),
239726
- rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
239727
- assets: looseObject({
239728
- directory: string2().optional(),
239729
- html_handling: string2().optional(),
239730
- not_found_handling: string2().optional(),
239731
- run_worker_first: union([boolean2(), array(string2())]).optional(),
239732
- headers: string2().optional(),
239733
- redirects: string2().optional()
239734
- }).optional(),
239735
- compatibility_date: string2().optional(),
239736
- compatibility_flags: array(string2()).optional(),
239737
- vars: record(string2(), unknown()).optional(),
239738
- upload_source_maps: boolean2().optional()
239739
- });
239740
- async function detectFullStackArtifact(projectRoot) {
239741
- const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
239742
- return await pathExists(redirectPath) ? redirectPath : null;
239743
- }
239744
- async function resolveWranglerConfig(redirectPath) {
239745
- const configPath = await resolveRedirectedConfigPath(redirectPath);
239746
- const parsed = await readJsonFile(configPath);
239747
- const result = WranglerConfigSchema.safeParse(parsed);
239748
- if (!result.success) {
239749
- throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
239750
- }
239751
- const config = result.data;
239752
- if (config.no_bundle !== true) {
239753
- throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
239754
- }
239755
- const configDir = dirname12(configPath);
239756
- const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
239757
- return {
239758
- configPath,
239759
- configDir,
239760
- main: config.main,
239761
- assetsDirectory,
239762
- assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
239763
- compatibilityDate: config.compatibility_date ?? null,
239764
- compatibilityFlags: config.compatibility_flags ?? [],
239765
- rules: (config.rules ?? []).map((rule) => ({
239766
- type: rule.type,
239767
- globs: rule.globs
239768
- })),
239769
- uploadSourceMaps: config.upload_source_maps ?? false
239770
- };
239771
- }
239772
- async function resolveRedirectedConfigPath(redirectPath) {
239773
- const parsed = await readJsonFile(redirectPath);
239774
- const result = RedirectConfigSchema.safeParse(parsed);
239775
- if (!result.success) {
239776
- throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
239777
- }
239778
- const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
239779
- if (!await pathExists(configPath)) {
239780
- throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
239781
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
239782
- });
239783
- }
239784
- return configPath;
239785
- }
239786
- function toResolvedAssetsConfig(assets) {
239787
- return {
239788
- htmlHandling: assets.html_handling,
239789
- notFoundHandling: assets.not_found_handling,
239790
- runWorkerFirst: assets.run_worker_first,
239791
- headers: assets.headers,
239792
- redirects: assets.redirects
239793
- };
239794
- }
239795
-
239796
- // src/core/site/full-stack.ts
239797
- async function resolveFullStackBuild(projectRoot) {
239798
- const redirectPath = await detectFullStackArtifact(projectRoot);
239799
- if (!redirectPath) {
239800
- return null;
239801
- }
239802
- const config = await resolveWranglerConfig(redirectPath);
239803
- return {
239804
- config,
239805
- modules: await collectModules(config),
239806
- assetsDir: config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null
239807
- };
239808
- }
239809
-
239810
239611
  // src/core/site/manifest.ts
239811
239612
  import { createHash } from "node:crypto";
239812
239613
  import { createReadStream } from "node:fs";
239813
- import { stat as stat2 } from "node:fs/promises";
239814
- import { basename as basename5, extname, join as join17 } from "node:path";
239815
-
239816
- // ../../node_modules/p-map/index.js
239817
- async function pMap(iterable, mapper, {
239818
- concurrency = Number.POSITIVE_INFINITY,
239819
- stopOnError = true,
239820
- signal
239821
- } = {}) {
239822
- return new Promise((resolve_, reject_) => {
239823
- if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
239824
- throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
239825
- }
239826
- if (typeof mapper !== "function") {
239827
- throw new TypeError("Mapper function is required");
239828
- }
239829
- if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
239830
- throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
239831
- }
239832
- const result = [];
239833
- const errors = [];
239834
- const skippedIndexesMap = new Map;
239835
- let isRejected = false;
239836
- let isResolved = false;
239837
- let isIterableDone = false;
239838
- let resolvingCount = 0;
239839
- let currentIndex = 0;
239840
- const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
239841
- const signalListener = () => {
239842
- reject(signal.reason);
239843
- };
239844
- const cleanup = () => {
239845
- signal?.removeEventListener("abort", signalListener);
239846
- };
239847
- const resolve = (value) => {
239848
- resolve_(value);
239849
- cleanup();
239850
- };
239851
- const reject = (reason) => {
239852
- isRejected = true;
239853
- isResolved = true;
239854
- reject_(reason);
239855
- cleanup();
239856
- };
239857
- if (signal) {
239858
- if (signal.aborted) {
239859
- reject(signal.reason);
239860
- return;
239861
- }
239862
- signal.addEventListener("abort", signalListener, { once: true });
239863
- }
239864
- const next = async () => {
239865
- if (isResolved) {
239866
- return;
239867
- }
239868
- const nextItem = await iterator.next();
239869
- const index = currentIndex;
239870
- currentIndex++;
239871
- if (nextItem.done) {
239872
- isIterableDone = true;
239873
- if (resolvingCount === 0 && !isResolved) {
239874
- if (!stopOnError && errors.length > 0) {
239875
- reject(new AggregateError(errors));
239876
- return;
239877
- }
239878
- isResolved = true;
239879
- if (skippedIndexesMap.size === 0) {
239880
- resolve(result);
239881
- return;
239882
- }
239883
- const pureResult = [];
239884
- for (const [index, value] of result.entries()) {
239885
- if (skippedIndexesMap.get(index) === pMapSkip) {
239886
- continue;
239887
- }
239888
- pureResult.push(value);
239889
- }
239890
- resolve(pureResult);
239891
- }
239892
- return;
239893
- }
239894
- resolvingCount++;
239895
- (async () => {
239896
- try {
239897
- const element = await nextItem.value;
239898
- if (isResolved) {
239899
- return;
239900
- }
239901
- const value = await mapper(element, index);
239902
- if (value === pMapSkip) {
239903
- skippedIndexesMap.set(index, value);
239904
- }
239905
- result[index] = value;
239906
- resolvingCount--;
239907
- await next();
239908
- } catch (error) {
239909
- if (stopOnError) {
239910
- reject(error);
239911
- } else {
239912
- errors.push(error);
239913
- resolvingCount--;
239914
- try {
239915
- await next();
239916
- } catch (error) {
239917
- reject(error);
239918
- }
239919
- }
239920
- }
239921
- })();
239922
- };
239923
- (async () => {
239924
- for (let index = 0;index < concurrency; index++) {
239925
- try {
239926
- await next();
239927
- } catch (error) {
239928
- reject(error);
239929
- break;
239930
- }
239931
- if (isIterableDone || isRejected) {
239932
- break;
239933
- }
239934
- }
239935
- })();
239936
- });
239937
- }
239938
- var pMapSkip = Symbol("skip");
239939
-
239940
- // src/core/site/manifest.ts
239614
+ import { stat } from "node:fs/promises";
239615
+ import { basename as basename5, extname, join as join16 } from "node:path";
239941
239616
  var MAX_ASSET_COUNT = 1e5;
239942
239617
  var ASSETS_IGNORE_FILE = ".assetsignore";
239943
239618
  var ALWAYS_IGNORED = new Set([
@@ -239978,42 +239653,30 @@ var MIME_TYPES = {
239978
239653
  function getAssetContentType(filePath) {
239979
239654
  return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
239980
239655
  }
239981
- async function walkBuildOutput(outputDir) {
239982
- const found = await globby("**/*", {
239983
- cwd: outputDir,
239984
- dot: true,
239985
- onlyFiles: true,
239986
- followSymbolicLinks: false,
239987
- ignoreFiles: [ASSETS_IGNORE_FILE]
239988
- });
239989
- return found.filter((path) => !ALWAYS_IGNORED.has(basename5(path))).sort();
239990
- }
239991
- var STAT_CONCURRENCY = 32;
239992
- async function describeBuildOutput(outputDir) {
239993
- const relativePaths = await walkBuildOutput(outputDir);
239994
- return await pMap(relativePaths, async (path) => {
239995
- const absolutePath = join17(outputDir, ...path.split("/"));
239996
- return { path, absolutePath, size: (await stat2(absolutePath)).size };
239997
- }, { concurrency: STAT_CONCURRENCY });
239998
- }
239999
- async function hashFileInto(hash, absolutePath) {
239656
+ async function hashAssetFile(appId, absolutePath) {
239657
+ const hash = createHash("sha256").update(Buffer.from(appId, "utf8"));
240000
239658
  for await (const chunk of createReadStream(absolutePath)) {
240001
239659
  hash.update(chunk);
240002
239660
  }
240003
- return hash;
240004
- }
240005
- async function hashAssetFile(appId, absolutePath) {
240006
- const hash = await hashFileInto(createHash("sha256").update(Buffer.from(appId, "utf8")), absolutePath);
240007
239661
  return hash.digest("hex").slice(0, 32);
240008
239662
  }
240009
239663
  async function buildAssetManifest(assetsDir, appId) {
240010
239664
  const manifest = {};
240011
239665
  const filesByHash = new Map;
240012
- const files = await describeBuildOutput(assetsDir);
240013
- if (files.length > MAX_ASSET_COUNT) {
240014
- throw new InvalidInputError(`Too many static assets: found ${files.length}, the limit is ${MAX_ASSET_COUNT} files.`);
239666
+ const found = await globby("**/*", {
239667
+ cwd: assetsDir,
239668
+ dot: true,
239669
+ onlyFiles: true,
239670
+ followSymbolicLinks: false,
239671
+ ignoreFiles: [ASSETS_IGNORE_FILE]
239672
+ });
239673
+ const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
239674
+ if (relativeFilePaths.length > MAX_ASSET_COUNT) {
239675
+ throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
240015
239676
  }
240016
- for (const { path: relativePath, absolutePath, size } of files) {
239677
+ for (const relativePath of relativeFilePaths.sort()) {
239678
+ const absolutePath = join16(assetsDir, ...relativePath.split("/"));
239679
+ const { size } = await stat(absolutePath);
240017
239680
  const hash = await hashAssetFile(appId, absolutePath);
240018
239681
  manifest[`/${relativePath}`] = { hash, size };
240019
239682
  if (!filesByHash.has(hash)) {
@@ -240028,8 +239691,229 @@ async function buildAssetManifest(assetsDir, appId) {
240028
239691
  return { manifest, filesByHash };
240029
239692
  }
240030
239693
 
239694
+ // src/core/site/modules.ts
239695
+ import { stat as stat2 } from "node:fs/promises";
239696
+ import { relative as relative5, resolve as resolve3, sep } from "node:path";
239697
+ var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
239698
+ var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
239699
+ var RULE_TYPE_TO_MODULE_TYPE = {
239700
+ ESModule: "esm",
239701
+ CompiledWasm: "wasm",
239702
+ Text: "text",
239703
+ Data: "data"
239704
+ };
239705
+ function toPosix(path) {
239706
+ return path.split(sep).join("/");
239707
+ }
239708
+ async function collectModules(config) {
239709
+ const entryPath = resolve3(config.configDir, config.main);
239710
+ if (!await pathExists(entryPath)) {
239711
+ throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config.configPath})`, {
239712
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
239713
+ });
239714
+ }
239715
+ const modulesByName = new Map;
239716
+ const entryName = toPosix(relative5(config.configDir, entryPath));
239717
+ modulesByName.set(entryName, {
239718
+ name: entryName,
239719
+ absolutePath: entryPath,
239720
+ size: 0,
239721
+ type: "esm"
239722
+ });
239723
+ const ignore = [...MODULE_IGNORE];
239724
+ if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
239725
+ ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
239726
+ }
239727
+ for (const rule of config.rules) {
239728
+ const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
239729
+ if (!type) {
239730
+ throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
239731
+ }
239732
+ const matches = await globby(rule.globs, {
239733
+ cwd: config.configDir,
239734
+ onlyFiles: true,
239735
+ dot: true,
239736
+ ignore
239737
+ });
239738
+ for (const match of matches.sort()) {
239739
+ if (!modulesByName.has(match)) {
239740
+ modulesByName.set(match, {
239741
+ name: match,
239742
+ absolutePath: resolve3(config.configDir, match),
239743
+ size: 0,
239744
+ type
239745
+ });
239746
+ }
239747
+ }
239748
+ }
239749
+ if (config.uploadSourceMaps) {
239750
+ const maps = await globby("**/*.map", {
239751
+ cwd: config.configDir,
239752
+ onlyFiles: true,
239753
+ dot: true,
239754
+ ignore
239755
+ });
239756
+ for (const map of maps.sort()) {
239757
+ addSourcemap(modulesByName, config.configDir, map);
239758
+ }
239759
+ } else {
239760
+ for (const name of [...modulesByName.keys()]) {
239761
+ const mapName = `${name}.map`;
239762
+ if (await pathExists(resolve3(config.configDir, mapName))) {
239763
+ addSourcemap(modulesByName, config.configDir, mapName);
239764
+ }
239765
+ }
239766
+ }
239767
+ const modules = [...modulesByName.values()];
239768
+ let totalBytes = 0;
239769
+ for (const module of modules) {
239770
+ module.size = (await stat2(module.absolutePath)).size;
239771
+ totalBytes += module.size;
239772
+ }
239773
+ if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
239774
+ throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for a Base44 deploy.`);
239775
+ }
239776
+ return modules;
239777
+ }
239778
+ function addSourcemap(modulesByName, configDir, name) {
239779
+ if (modulesByName.has(name))
239780
+ return;
239781
+ modulesByName.set(name, {
239782
+ name,
239783
+ absolutePath: resolve3(configDir, name),
239784
+ size: 0,
239785
+ type: "sourcemap"
239786
+ });
239787
+ }
239788
+
240031
239789
  // src/core/site/upload.ts
240032
239790
  import { readFile as readFile2 } from "node:fs/promises";
239791
+
239792
+ // ../../node_modules/p-map/index.js
239793
+ async function pMap(iterable, mapper, {
239794
+ concurrency = Number.POSITIVE_INFINITY,
239795
+ stopOnError = true,
239796
+ signal
239797
+ } = {}) {
239798
+ return new Promise((resolve_, reject_) => {
239799
+ if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
239800
+ throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
239801
+ }
239802
+ if (typeof mapper !== "function") {
239803
+ throw new TypeError("Mapper function is required");
239804
+ }
239805
+ if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
239806
+ throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
239807
+ }
239808
+ const result = [];
239809
+ const errors = [];
239810
+ const skippedIndexesMap = new Map;
239811
+ let isRejected = false;
239812
+ let isResolved = false;
239813
+ let isIterableDone = false;
239814
+ let resolvingCount = 0;
239815
+ let currentIndex = 0;
239816
+ const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
239817
+ const signalListener = () => {
239818
+ reject(signal.reason);
239819
+ };
239820
+ const cleanup = () => {
239821
+ signal?.removeEventListener("abort", signalListener);
239822
+ };
239823
+ const resolve = (value) => {
239824
+ resolve_(value);
239825
+ cleanup();
239826
+ };
239827
+ const reject = (reason) => {
239828
+ isRejected = true;
239829
+ isResolved = true;
239830
+ reject_(reason);
239831
+ cleanup();
239832
+ };
239833
+ if (signal) {
239834
+ if (signal.aborted) {
239835
+ reject(signal.reason);
239836
+ return;
239837
+ }
239838
+ signal.addEventListener("abort", signalListener, { once: true });
239839
+ }
239840
+ const next = async () => {
239841
+ if (isResolved) {
239842
+ return;
239843
+ }
239844
+ const nextItem = await iterator.next();
239845
+ const index = currentIndex;
239846
+ currentIndex++;
239847
+ if (nextItem.done) {
239848
+ isIterableDone = true;
239849
+ if (resolvingCount === 0 && !isResolved) {
239850
+ if (!stopOnError && errors.length > 0) {
239851
+ reject(new AggregateError(errors));
239852
+ return;
239853
+ }
239854
+ isResolved = true;
239855
+ if (skippedIndexesMap.size === 0) {
239856
+ resolve(result);
239857
+ return;
239858
+ }
239859
+ const pureResult = [];
239860
+ for (const [index, value] of result.entries()) {
239861
+ if (skippedIndexesMap.get(index) === pMapSkip) {
239862
+ continue;
239863
+ }
239864
+ pureResult.push(value);
239865
+ }
239866
+ resolve(pureResult);
239867
+ }
239868
+ return;
239869
+ }
239870
+ resolvingCount++;
239871
+ (async () => {
239872
+ try {
239873
+ const element = await nextItem.value;
239874
+ if (isResolved) {
239875
+ return;
239876
+ }
239877
+ const value = await mapper(element, index);
239878
+ if (value === pMapSkip) {
239879
+ skippedIndexesMap.set(index, value);
239880
+ }
239881
+ result[index] = value;
239882
+ resolvingCount--;
239883
+ await next();
239884
+ } catch (error) {
239885
+ if (stopOnError) {
239886
+ reject(error);
239887
+ } else {
239888
+ errors.push(error);
239889
+ resolvingCount--;
239890
+ try {
239891
+ await next();
239892
+ } catch (error) {
239893
+ reject(error);
239894
+ }
239895
+ }
239896
+ }
239897
+ })();
239898
+ };
239899
+ (async () => {
239900
+ for (let index = 0;index < concurrency; index++) {
239901
+ try {
239902
+ await next();
239903
+ } catch (error) {
239904
+ reject(error);
239905
+ break;
239906
+ }
239907
+ if (isIterableDone || isRejected) {
239908
+ break;
239909
+ }
239910
+ }
239911
+ })();
239912
+ });
239913
+ }
239914
+ var pMapSkip = Symbol("skip");
239915
+
239916
+ // src/core/site/upload.ts
240033
239917
  var DEFAULT_UPLOAD_CONCURRENCY = 3;
240034
239918
  var MAX_UPLOAD_CONCURRENCY = 50;
240035
239919
  var MAX_UPLOAD_ATTEMPTS = 3;
@@ -240128,17 +240012,11 @@ async function uploadPresignedAsset(upload, assets) {
240128
240012
  if (!file) {
240129
240013
  throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
240130
240014
  }
240131
- await putPresigned(upload, file.absolutePath);
240132
- }
240133
- async function putPresigned(upload, absolutePath) {
240134
- const content = await readFile2(absolutePath);
240015
+ const content = await readFile2(file.absolutePath);
240135
240016
  try {
240136
240017
  await distribution_default.put(upload.url, {
240137
240018
  body: new Uint8Array(content),
240138
- headers: {
240139
- "Content-Type": upload.contentType,
240140
- ...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
240141
- },
240019
+ headers: { "Content-Type": upload.contentType },
240142
240020
  timeout: 120000,
240143
240021
  retry: UPLOAD_RETRY
240144
240022
  });
@@ -240147,6 +240025,85 @@ async function putPresigned(upload, absolutePath) {
240147
240025
  }
240148
240026
  }
240149
240027
 
240028
+ // src/core/site/wrangler-config.ts
240029
+ import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
240030
+ var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
240031
+ var RedirectConfigSchema = looseObject({
240032
+ configPath: string2().min(1)
240033
+ });
240034
+ var WranglerConfigSchema = looseObject({
240035
+ main: string2().min(1, "wrangler config is missing a 'main' entry module"),
240036
+ no_bundle: boolean2().optional(),
240037
+ rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
240038
+ assets: looseObject({
240039
+ directory: string2().optional(),
240040
+ html_handling: string2().optional(),
240041
+ not_found_handling: string2().optional(),
240042
+ run_worker_first: union([boolean2(), array(string2())]).optional(),
240043
+ headers: string2().optional(),
240044
+ redirects: string2().optional()
240045
+ }).optional(),
240046
+ compatibility_date: string2().optional(),
240047
+ compatibility_flags: array(string2()).optional(),
240048
+ vars: record(string2(), unknown()).optional(),
240049
+ upload_source_maps: boolean2().optional()
240050
+ });
240051
+ async function detectFullStackArtifact(projectRoot) {
240052
+ const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
240053
+ return await pathExists(redirectPath) ? redirectPath : null;
240054
+ }
240055
+ async function resolveWranglerConfig(redirectPath) {
240056
+ const configPath = await resolveRedirectedConfigPath(redirectPath);
240057
+ const parsed = await readJsonFile(configPath);
240058
+ const result = WranglerConfigSchema.safeParse(parsed);
240059
+ if (!result.success) {
240060
+ throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
240061
+ }
240062
+ const config = result.data;
240063
+ if (config.no_bundle !== true) {
240064
+ throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
240065
+ }
240066
+ const configDir = dirname12(configPath);
240067
+ const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
240068
+ return {
240069
+ configPath,
240070
+ configDir,
240071
+ main: config.main,
240072
+ assetsDirectory,
240073
+ assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
240074
+ compatibilityDate: config.compatibility_date ?? null,
240075
+ compatibilityFlags: config.compatibility_flags ?? [],
240076
+ rules: (config.rules ?? []).map((rule) => ({
240077
+ type: rule.type,
240078
+ globs: rule.globs
240079
+ })),
240080
+ uploadSourceMaps: config.upload_source_maps ?? false
240081
+ };
240082
+ }
240083
+ async function resolveRedirectedConfigPath(redirectPath) {
240084
+ const parsed = await readJsonFile(redirectPath);
240085
+ const result = RedirectConfigSchema.safeParse(parsed);
240086
+ if (!result.success) {
240087
+ throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
240088
+ }
240089
+ const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
240090
+ if (!await pathExists(configPath)) {
240091
+ throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
240092
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
240093
+ });
240094
+ }
240095
+ return configPath;
240096
+ }
240097
+ function toResolvedAssetsConfig(assets) {
240098
+ return {
240099
+ htmlHandling: assets.html_handling,
240100
+ notFoundHandling: assets.not_found_handling,
240101
+ runWorkerFirst: assets.run_worker_first,
240102
+ headers: assets.headers,
240103
+ redirects: assets.redirects
240104
+ };
240105
+ }
240106
+
240150
240107
  // src/core/site/deployment.ts
240151
240108
  var NO_ASSETS = { manifest: {}, filesByHash: new Map };
240152
240109
  var DEPLOYMENTS_API_ENV = "BASE44_DEPLOYMENTS_API";
@@ -240176,11 +240133,12 @@ async function deployToDeployments(options) {
240176
240133
  return { deploymentId: finalized.deploymentId, gitHash };
240177
240134
  }
240178
240135
  async function resolveWorkerBuild(projectRoot, progress) {
240179
- const built = await resolveFullStackBuild(projectRoot);
240180
- if (!built) {
240136
+ const redirectPath = await detectFullStackArtifact(projectRoot);
240137
+ if (!redirectPath) {
240181
240138
  return null;
240182
240139
  }
240183
- const { config, modules, assetsDir } = built;
240140
+ const config = await resolveWranglerConfig(redirectPath);
240141
+ const assetsDir = config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null;
240184
240142
  return {
240185
240143
  config: {
240186
240144
  main: config.main,
@@ -240188,7 +240146,7 @@ async function resolveWorkerBuild(projectRoot, progress) {
240188
240146
  compatibility_flags: config.compatibilityFlags,
240189
240147
  assets: buildAssetsConfig(config.assetsConfig, progress)
240190
240148
  },
240191
- modules,
240149
+ modules: await collectModules(config),
240192
240150
  assetsDir
240193
240151
  };
240194
240152
  }
@@ -246741,13 +246699,6 @@ async function resolveGitHash(projectRoot, explicit) {
246741
246699
  }
246742
246700
  return hash;
246743
246701
  }
246744
- async function resolveProvenanceCommit(projectRoot, explicit) {
246745
- if (explicit) {
246746
- return await resolveGitHash(projectRoot, explicit);
246747
- }
246748
- const hash = await gitHead(projectRoot);
246749
- return hash && isGitCommitHash(hash) ? hash : undefined;
246750
- }
246751
246702
  async function gitHead(projectRoot) {
246752
246703
  try {
246753
246704
  const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
@@ -246758,6 +246709,41 @@ async function gitHead(projectRoot) {
246758
246709
  return null;
246759
246710
  }
246760
246711
  }
246712
+ // src/core/site/serve-command.ts
246713
+ var DEFAULT_SERVE_COMMAND = "npm run dev";
246714
+ var SCRIPT = "[A-Za-z0-9:_.-]+";
246715
+ var PREFIX2 = "[A-Za-z0-9._/-]+";
246716
+ var SCRIPT_RUNNERS = [
246717
+ {
246718
+ pattern: new RegExp(String.raw`^npm(\s+--prefix\s+${PREFIX2})?\s+run\s+${SCRIPT}$`),
246719
+ separator: " -- "
246720
+ },
246721
+ {
246722
+ pattern: new RegExp(String.raw`^(?:pnpm|yarn|bun)(\s+run)?\s+${SCRIPT}$`),
246723
+ separator: " "
246724
+ }
246725
+ ];
246726
+ function runnerFor(serveCommand) {
246727
+ return SCRIPT_RUNNERS.find((runner) => runner.pattern.test(serveCommand));
246728
+ }
246729
+ function withServeAddress(serveCommand, { host, port, hostFlag }) {
246730
+ const command = serveCommand.trim();
246731
+ const args = [
246732
+ ...host ? [hostFlag, host] : [],
246733
+ ...port === undefined ? [] : ["--port", String(port)]
246734
+ ];
246735
+ if (args.length === 0) {
246736
+ return { command, droppedAddress: false };
246737
+ }
246738
+ const runner = runnerFor(command);
246739
+ if (!runner) {
246740
+ return { command, droppedAddress: true };
246741
+ }
246742
+ return {
246743
+ command: `${command}${runner.separator}${args.join(" ")}`,
246744
+ droppedAddress: false
246745
+ };
246746
+ }
246761
246747
  // src/core/project/deploy.ts
246762
246748
  function hasResourcesToDeploy(projectData) {
246763
246749
  const {
@@ -246836,49 +246822,6 @@ async function deployAll(projectData, options) {
246836
246822
  }
246837
246823
  return { connectorResults };
246838
246824
  }
246839
- // src/core/project/target.ts
246840
- import { dirname as dirname13, join as join19, resolve as resolve6 } from "node:path";
246841
- var DEFAULT_BUILD_COMMAND = "npm run build";
246842
- var DEFAULT_OUTPUT_DIRECTORY = "dist";
246843
- async function resolveBuildTarget(projectRoot, overrides = {}) {
246844
- const project = await readSettingsIfPresent(projectRoot);
246845
- const root = project?.root ?? projectRoot ?? process.cwd();
246846
- return {
246847
- root,
246848
- configDir: project ? dirname13(project.configPath) : join19(root, PROJECT_SUBDIR),
246849
- buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
246850
- outputDir: outputDirectory(project, root, overrides.outputDir),
246851
- entitiesDir: project?.entitiesDir ?? "entities",
246852
- agentsDir: project?.agentsDir ?? "agents"
246853
- };
246854
- }
246855
- function outputDirectory(project, root, override) {
246856
- const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
246857
- return configured ? resolve6(root, configured) : null;
246858
- }
246859
- function requireOutputDir(target) {
246860
- if (target.outputDir === null) {
246861
- throw new ConfigNotFoundError("No site configuration found.", {
246862
- hints: [
246863
- {
246864
- message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
246865
- },
246866
- { message: `Or pass --output-dir <dir>, relative to ${target.root}` }
246867
- ]
246868
- });
246869
- }
246870
- return target.outputDir;
246871
- }
246872
- async function readSettingsIfPresent(projectRoot) {
246873
- try {
246874
- return await readProjectSettings(projectRoot);
246875
- } catch (error) {
246876
- if (error instanceof ConfigNotFoundError) {
246877
- return null;
246878
- }
246879
- throw error;
246880
- }
246881
- }
246882
246825
  // src/core/clients/base44-client.ts
246883
246826
  var retriedRequests = new WeakSet;
246884
246827
  async function captureRequestBody(request, options) {
@@ -247160,12 +247103,6 @@ async function ensureAppContext(ctx, options = {}) {
247160
247103
  ctx.app = appContext;
247161
247104
  ctx.errorReporter.setContext({ appId: appContext.id });
247162
247105
  }
247163
- function requireApp(ctx) {
247164
- if (!ctx.app) {
247165
- throw new InternalError("This command read an app context it never resolved — it is declared with requireAppContext: false.");
247166
- }
247167
- return ctx.app;
247168
- }
247169
247106
 
247170
247107
  // src/cli/utils/version-check.ts
247171
247108
  async function checkForUpgrade() {
@@ -247349,10 +247286,6 @@ function writeJsonError(error) {
247349
247286
  const envelope = {
247350
247287
  error: error instanceof Error ? error.message : String(error)
247351
247288
  };
247352
- const step = stepOf(error);
247353
- if (step !== undefined) {
247354
- envelope.step = step;
247355
- }
247356
247289
  if (isCLIError(error)) {
247357
247290
  envelope.code = error.code;
247358
247291
  if (error.details.length > 0) {
@@ -247722,7 +247655,7 @@ function getActorsCommand() {
247722
247655
  }
247723
247656
 
247724
247657
  // src/cli/commands/agent-skills/pull.ts
247725
- import { dirname as dirname14, join as join20 } from "node:path";
247658
+ import { dirname as dirname13, join as join19 } from "node:path";
247726
247659
  // src/core/utils/dependencies.ts
247727
247660
  import { spawnSync as spawnSync2 } from "node:child_process";
247728
247661
  function verifyDenoInstalled(context) {
@@ -247811,7 +247744,7 @@ async function pullAction({
247811
247744
  runTask
247812
247745
  }) {
247813
247746
  const { project } = await readProjectConfig();
247814
- const dir = join20(dirname14(project.configPath), project.agentSkillsDir);
247747
+ const dir = join19(dirname13(project.configPath), project.agentSkillsDir);
247815
247748
  const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
247816
247749
  successMessage: "Agent skills fetched successfully",
247817
247750
  errorMessage: "Failed to fetch agent skills"
@@ -247867,14 +247800,14 @@ function getAgentSkillsCommand() {
247867
247800
  }
247868
247801
 
247869
247802
  // src/cli/commands/agents/pull.ts
247870
- import { dirname as dirname15, join as join21 } from "node:path";
247803
+ import { dirname as dirname14, join as join20 } from "node:path";
247871
247804
  async function pullAgentsAction({
247872
247805
  log,
247873
247806
  runTask
247874
247807
  }) {
247875
247808
  const { project } = await readProjectConfig();
247876
- const configDir = dirname15(project.configPath);
247877
- const agentsDir = join21(configDir, project.agentsDir);
247809
+ const configDir = dirname14(project.configPath);
247810
+ const agentsDir = join20(configDir, project.agentsDir);
247878
247811
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
247879
247812
  return await fetchAgents();
247880
247813
  }, {
@@ -247944,12 +247877,12 @@ function getAgentsCommand() {
247944
247877
  }
247945
247878
 
247946
247879
  // src/cli/commands/auth/password-login.ts
247947
- import { dirname as dirname16, join as join22 } from "node:path";
247880
+ import { dirname as dirname15, join as join21 } from "node:path";
247948
247881
  async function passwordLoginAction({ log, runTask }, action) {
247949
247882
  const shouldEnable = action === "enable";
247950
247883
  const { project } = await readProjectConfig();
247951
- const configDir = dirname16(project.configPath);
247952
- const authDir = join22(configDir, project.authDir);
247884
+ const configDir = dirname15(project.configPath);
247885
+ const authDir = join21(configDir, project.authDir);
247953
247886
  const updated = await runTask("Updating local auth config", async () => {
247954
247887
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
247955
247888
  const merged = { ...current, enableUsernamePassword: shouldEnable };
@@ -247969,14 +247902,14 @@ function getPasswordLoginCommand() {
247969
247902
  }
247970
247903
 
247971
247904
  // src/cli/commands/auth/pull.ts
247972
- import { dirname as dirname17, join as join23 } from "node:path";
247905
+ import { dirname as dirname16, join as join22 } from "node:path";
247973
247906
  async function pullAuthAction({
247974
247907
  log,
247975
247908
  runTask
247976
247909
  }) {
247977
247910
  const { project } = await readProjectConfig();
247978
- const configDir = dirname17(project.configPath);
247979
- const authDir = join23(configDir, project.authDir);
247911
+ const configDir = dirname16(project.configPath);
247912
+ const authDir = join22(configDir, project.authDir);
247980
247913
  const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
247981
247914
  return await pullAuthConfig();
247982
247915
  }, {
@@ -248040,7 +247973,7 @@ function getAuthPushCommand() {
248040
247973
  }
248041
247974
 
248042
247975
  // src/cli/commands/auth/social-login.ts
248043
- import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
247976
+ import { dirname as dirname17, join as join23, resolve as resolve6 } from "node:path";
248044
247977
  var PROVIDER_LABELS = {
248045
247978
  google: "Google",
248046
247979
  microsoft: "Microsoft",
@@ -248080,7 +248013,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
248080
248013
  let clientSecret;
248081
248014
  if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
248082
248015
  if (options.envFile) {
248083
- const secrets = await parseEnvFile(resolve7(options.envFile));
248016
+ const secrets = await parseEnvFile(resolve6(options.envFile));
248084
248017
  const value = secrets[oauthCli.envVar];
248085
248018
  if (!value) {
248086
248019
  throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
@@ -248110,8 +248043,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
248110
248043
  }
248111
248044
  }
248112
248045
  const { project } = await readProjectConfig();
248113
- const configDir = dirname18(project.configPath);
248114
- const authDir = join24(configDir, project.authDir);
248046
+ const configDir = dirname17(project.configPath);
248047
+ const authDir = join23(configDir, project.authDir);
248115
248048
  const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
248116
248049
  if (clientSecret) {
248117
248050
  await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
@@ -248136,7 +248069,7 @@ function getSocialLoginCommand() {
248136
248069
  }
248137
248070
 
248138
248071
  // src/cli/commands/auth/sso.ts
248139
- import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
248072
+ import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
248140
248073
  var SSOConfigFileSchema = object({
248141
248074
  provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
248142
248075
  clientId: string2(),
@@ -248152,7 +248085,7 @@ var SSOConfigFileSchema = object({
248152
248085
  ssoName: string2().optional()
248153
248086
  });
248154
248087
  async function loadSSOConfigFile(filePath) {
248155
- const resolved = resolve8(filePath);
248088
+ const resolved = resolve7(filePath);
248156
248089
  const raw = await readJsonFile(resolved);
248157
248090
  const result = SSOConfigFileSchema.safeParse(raw);
248158
248091
  if (!result.success) {
@@ -248240,7 +248173,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
248240
248173
  }
248241
248174
  let clientSecret;
248242
248175
  if (merged.envFile && !merged.clientSecret) {
248243
- const secrets = await parseEnvFile(resolve8(merged.envFile));
248176
+ const secrets = await parseEnvFile(resolve7(merged.envFile));
248244
248177
  const value = secrets.sso_client_secret;
248245
248178
  if (!value) {
248246
248179
  throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
@@ -248299,8 +248232,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
248299
248232
  throw error;
248300
248233
  }
248301
248234
  const { project } = await readProjectConfig();
248302
- const configDir = dirname19(project.configPath);
248303
- const authDir = join25(configDir, project.authDir);
248235
+ const configDir = dirname18(project.configPath);
248236
+ const authDir = join24(configDir, project.authDir);
248304
248237
  await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
248305
248238
  await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
248306
248239
  return {
@@ -248315,8 +248248,8 @@ async function ssoDisableAction({ log, runTask }, options) {
248315
248248
  throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
248316
248249
  }
248317
248250
  const { project } = await readProjectConfig();
248318
- const configDir = dirname19(project.configPath);
248319
- const authDir = join25(configDir, project.authDir);
248251
+ const configDir = dirname18(project.configPath);
248252
+ const authDir = join24(configDir, project.authDir);
248320
248253
  const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
248321
248254
  await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
248322
248255
  if (!hasAnyLoginMethod(updated)) {
@@ -249198,13 +249131,13 @@ function getConnectorsListAvailableCommand() {
249198
249131
  }
249199
249132
 
249200
249133
  // src/cli/commands/connectors/pull.ts
249201
- import { dirname as dirname20, join as join26, resolve as resolve9 } from "node:path";
249134
+ import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
249202
249135
  async function resolveConnectorsDir(options) {
249203
249136
  if (!getAppContext().projectRoot) {
249204
- return resolve9(options.dir ?? "connectors");
249137
+ return resolve8(options.dir ?? "connectors");
249205
249138
  }
249206
249139
  const { project } = await readProjectConfig();
249207
- return join26(dirname20(project.configPath), project.connectorsDir);
249140
+ return join25(dirname19(project.configPath), project.connectorsDir);
249208
249141
  }
249209
249142
  async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
249210
249143
  const connectorsDir = await resolveConnectorsDir(options);
@@ -249245,10 +249178,10 @@ function getConnectorsPullCommand() {
249245
249178
  }
249246
249179
 
249247
249180
  // src/cli/commands/connectors/push.ts
249248
- import { resolve as resolve10 } from "node:path";
249181
+ import { resolve as resolve9 } from "node:path";
249249
249182
  async function readConnectorsToPush(options) {
249250
249183
  if (!getAppContext().projectRoot) {
249251
- return readAllConnectors(resolve10(options.dir ?? "connectors"));
249184
+ return readAllConnectors(resolve9(options.dir ?? "connectors"));
249252
249185
  }
249253
249186
  const { connectors } = await readProjectConfig();
249254
249187
  return connectors;
@@ -249591,11 +249524,11 @@ function getListCommand() {
249591
249524
  }
249592
249525
 
249593
249526
  // src/cli/commands/functions/pull.ts
249594
- import { dirname as dirname21, join as join27 } from "node:path";
249527
+ import { dirname as dirname20, join as join26 } from "node:path";
249595
249528
  async function pullFunctionsAction({ log, runTask }, name) {
249596
249529
  const { project, functions } = await readProjectConfig();
249597
- const configDir = dirname21(project.configPath);
249598
- const functionsDir = join27(configDir, project.functionsDir);
249530
+ const configDir = dirname20(project.configPath);
249531
+ const functionsDir = join26(configDir, project.functionsDir);
249599
249532
  const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
249600
249533
  const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
249601
249534
  const { functions } = await listDeployedFunctions();
@@ -249698,11 +249631,14 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
249698
249631
 
249699
249632
  // src/cli/commands/project/build.ts
249700
249633
  async function buildAction(ctx) {
249701
- const app = requireApp(ctx);
249702
- const target = await resolveBuildTarget(app.projectRoot);
249634
+ const { app } = ctx;
249635
+ if (!app?.projectRoot) {
249636
+ throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
249637
+ }
249638
+ const { project } = await readProjectConfig(app.projectRoot);
249703
249639
  await runSiteBuild(ctx, {
249704
- root: target.root,
249705
- buildCommand: target.buildCommand,
249640
+ root: project.root,
249641
+ buildCommand: project.site?.buildCommand,
249706
249642
  appId: app.id
249707
249643
  });
249708
249644
  return {
@@ -249714,11 +249650,11 @@ function getBuildCommand() {
249714
249650
  }
249715
249651
 
249716
249652
  // src/cli/commands/project/create.ts
249717
- import { basename as basename6, resolve as resolve11 } from "node:path";
249653
+ import { basename as basename6, resolve as resolve10 } from "node:path";
249718
249654
  var import_kebabCase = __toESM(require_kebabCase(), 1);
249719
249655
 
249720
249656
  // src/cli/commands/project/scaffold-shared.ts
249721
- import { join as join28 } from "node:path";
249657
+ import { join as join27 } from "node:path";
249722
249658
  var DEFAULT_TEMPLATE_ID = "backend-only";
249723
249659
  async function getTemplateById(templateId) {
249724
249660
  const templates = await listTemplates();
@@ -249781,7 +249717,7 @@ async function completeProjectSetup({
249781
249717
  env: { VITE_BASE44_APP_ID: projectId }
249782
249718
  })`${buildCommand}`;
249783
249719
  updateMessage("Deploying site...");
249784
- return await deploySite(join28(resolvedPath, outputDirectory));
249720
+ return await deploySite(join27(resolvedPath, outputDirectory));
249785
249721
  }, {
249786
249722
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
249787
249723
  errorMessage: "Failed to deploy site"
@@ -249910,7 +249846,7 @@ async function createInteractive(options, ctx) {
249910
249846
  }, ctx);
249911
249847
  }
249912
249848
  async function createNonInteractive(options, ctx) {
249913
- ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
249849
+ ctx.log.info(`Creating a new project at ${resolve10(options.path)}`);
249914
249850
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
249915
249851
  return await executeCreate({
249916
249852
  template,
@@ -249934,7 +249870,7 @@ async function executeCreate({
249934
249870
  }, ctx) {
249935
249871
  const { log, runTask } = ctx;
249936
249872
  const name = rawName.trim();
249937
- const resolvedPath = resolve11(projectPath);
249873
+ const resolvedPath = resolve10(projectPath);
249938
249874
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
249939
249875
  const { projectId } = await runTask("Setting up your project...", async () => {
249940
249876
  return await createProjectFiles({
@@ -250107,6 +250043,36 @@ function printStripeResult(r, log) {
250107
250043
  log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
250108
250044
  }
250109
250045
 
250046
+ // src/cli/commands/project/install.ts
250047
+ async function installAction({
250048
+ runTask
250049
+ }) {
250050
+ const { project } = await readProjectConfig();
250051
+ const installCommand = project.site?.installCommand;
250052
+ if (!installCommand) {
250053
+ throw new ConfigNotFoundError("No site install command found.", {
250054
+ hints: [
250055
+ {
250056
+ message: `Add a 'site' block to your config.jsonc (e.g., "site": { "installCommand": "npm ci" }). Inside one, installCommand defaults to "npm install".`
250057
+ }
250058
+ ]
250059
+ });
250060
+ }
250061
+ await runTask("Installing site dependencies...", () => execa({ cwd: project.root, shell: true })`${installCommand}`, {
250062
+ successMessage: "Dependencies installed",
250063
+ errorMessage: "Install failed"
250064
+ });
250065
+ return {
250066
+ outroMessage: `Installed with ${theme.styles.bold(installCommand)}`
250067
+ };
250068
+ }
250069
+ function getInstallCommand() {
250070
+ return new Base44Command("install", {
250071
+ requireAuth: false,
250072
+ requireAppContext: false
250073
+ }).description("Install the site's dependencies with its configured command").action(installAction);
250074
+ }
250075
+
250110
250076
  // src/cli/commands/project/app-id-options.ts
250111
250077
  function readExplicitAppId(command) {
250112
250078
  const { appId } = command.optsWithGlobals();
@@ -250575,7 +250541,7 @@ function getLogsCommand() {
250575
250541
  }
250576
250542
 
250577
250543
  // src/cli/commands/project/scaffold.ts
250578
- import { basename as basename7, resolve as resolve12 } from "node:path";
250544
+ import { basename as basename7, resolve as resolve11 } from "node:path";
250579
250545
  function resolveAppId(options) {
250580
250546
  const appId = options.appId;
250581
250547
  if (!appId) {
@@ -250591,7 +250557,7 @@ function resolveAppId(options) {
250591
250557
  async function scaffoldAction(ctx, name, options, command) {
250592
250558
  const { log, runTask } = ctx;
250593
250559
  const appId = resolveAppId(command.optsWithGlobals());
250594
- const resolvedPath = resolve12("./");
250560
+ const resolvedPath = resolve11("./");
250595
250561
  const projectName = (name ?? basename7(resolvedPath)).trim();
250596
250562
  const template = await getTemplateById("backend-only");
250597
250563
  log.info(`Scaffolding project at ${resolvedPath}`);
@@ -250639,315 +250605,6 @@ function getVisibilityCommand() {
250639
250605
  ])).action(setVisibility);
250640
250606
  }
250641
250607
 
250642
- // src/core/version/schema.ts
250643
- var DeclareVersionResponseSchema = object({
250644
- session_id: string2(),
250645
- uploads: array(object({
250646
- path: string2(),
250647
- url: string2(),
250648
- content_type: string2(),
250649
- content_length: number2(),
250650
- checksum_sha256: string2()
250651
- }))
250652
- }).transform((data) => ({
250653
- sessionId: data.session_id,
250654
- uploads: data.uploads.map((upload) => ({
250655
- path: upload.path,
250656
- url: upload.url,
250657
- contentType: upload.content_type,
250658
- contentLength: upload.content_length,
250659
- checksumSha256: upload.checksum_sha256
250660
- }))
250661
- }));
250662
- var CreateVersionResponseSchema = object({
250663
- version_id: string2(),
250664
- manifest_hash: string2()
250665
- }).transform((data) => ({
250666
- versionId: data.version_id,
250667
- manifestHash: data.manifest_hash
250668
- }));
250669
- var EnvironmentResponseSchema = object({
250670
- name: string2(),
250671
- version_id: string2(),
250672
- manifest_hash: string2(),
250673
- deployment_id: string2()
250674
- }).transform((data) => ({
250675
- name: data.name,
250676
- versionId: data.version_id,
250677
- manifestHash: data.manifest_hash,
250678
- deploymentId: data.deployment_id
250679
- }));
250680
-
250681
- // src/core/version/api.ts
250682
- var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
250683
- var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
250684
- function declaredFile({ path, size, digest }) {
250685
- return { path, size, digest };
250686
- }
250687
- function declaredModule(module) {
250688
- return { ...declaredFile(module), type: module.type };
250689
- }
250690
- function declaredServingConfig(config) {
250691
- const stated = {
250692
- html_handling: config?.htmlHandling ?? null,
250693
- not_found_handling: config?.notFoundHandling ?? null,
250694
- run_worker_first: config?.runWorkerFirst ?? null,
250695
- headers: config?.headers ?? null,
250696
- redirects: config?.redirects ?? null
250697
- };
250698
- return Object.values(stated).every((v) => v === null) ? null : stated;
250699
- }
250700
- async function post(path, json, doing) {
250701
- try {
250702
- return await getAppClient().post(path, { json, timeout: 180000 });
250703
- } catch (error) {
250704
- throw await ApiError.fromHttpError(error, doing);
250705
- }
250706
- }
250707
- var KEYED_RETRY = {
250708
- limit: 3,
250709
- methods: ["patch"],
250710
- statusCodes: [408, 500, 502, 503, 504],
250711
- retryOnTimeout: true
250712
- };
250713
- async function patch(path, json, doing, retry) {
250714
- try {
250715
- return await getAppClient().patch(path, {
250716
- json,
250717
- timeout: 180000,
250718
- ...retry ? { retry } : {}
250719
- });
250720
- } catch (error) {
250721
- throw await ApiError.fromHttpError(error, doing);
250722
- }
250723
- }
250724
- function parse10(schema, body, what) {
250725
- const result = schema.safeParse(body);
250726
- if (!result.success) {
250727
- throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
250728
- }
250729
- return result.data;
250730
- }
250731
- async function createVersion(artifacts, options = {}) {
250732
- const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
250733
- assets: artifacts.assets.map(declaredFile),
250734
- ...artifacts.siteWorker ? {
250735
- site_worker: {
250736
- main: artifacts.siteWorker.main,
250737
- modules: artifacts.siteWorker.modules.map(declaredModule),
250738
- compatibility_date: artifacts.siteWorker.compatibilityDate,
250739
- compatibility_flags: artifacts.siteWorker.compatibilityFlags,
250740
- serving_config: declaredServingConfig(artifacts.siteWorker.servingConfig)
250741
- }
250742
- } : {},
250743
- entities: artifacts.entities,
250744
- agents: artifacts.agents,
250745
- source_commit: options.sourceCommit
250746
- }, "declaring a version")).json(), "declare");
250747
- const declaredFiles = [
250748
- ...artifacts.assets,
250749
- ...artifacts.siteWorker?.modules ?? []
250750
- ];
250751
- options.progress?.onDeclared?.({ fileCount: declaredFiles.length });
250752
- if (declared.uploads.length !== declaredFiles.length) {
250753
- throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
250754
- }
250755
- const drifted = declared.uploads.findIndex((upload, index) => upload.path !== declaredFiles[index].path);
250756
- if (drifted !== -1) {
250757
- throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
250758
- }
250759
- let uploadedFiles = 0;
250760
- await pMap(declared.uploads, async (upload, index) => {
250761
- await putPresigned(upload, declaredFiles[index].absolutePath);
250762
- uploadedFiles++;
250763
- options.progress?.onUpload?.({
250764
- uploadedFiles,
250765
- totalFiles: declared.uploads.length
250766
- });
250767
- }, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
250768
- return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
250769
- }
250770
- async function setEnvironmentVersion(environment, versionId, options = {}) {
250771
- return parse10(EnvironmentResponseSchema, await (await patch(`environments/${encodeURIComponent(environment)}`, {
250772
- version_id: versionId,
250773
- ...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
250774
- }, "setting the environment's version", options.idempotencyKey ? KEYED_RETRY : undefined)).json(), "environment");
250775
- }
250776
- // src/core/version/artifacts.ts
250777
- import { createHash as createHash2 } from "node:crypto";
250778
- import { join as join29, resolve as resolve13 } from "node:path";
250779
- var MAX_FILE_COUNT = 50000;
250780
- var HASH_CONCURRENCY = 32;
250781
- var ENTRY2 = "index.html";
250782
- async function digestFile(absolutePath) {
250783
- const hash = await hashFileInto(createHash2("sha256"), absolutePath);
250784
- return `sha256:${hash.digest("hex")}`;
250785
- }
250786
- async function collectBuildOutput(outputDir, options = {}) {
250787
- const found = await describeBuildOutput(outputDir);
250788
- if (found.length > MAX_FILE_COUNT) {
250789
- throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
250790
- }
250791
- if (options.entryFile) {
250792
- if (found.length === 0) {
250793
- throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
250794
- hints: [
250795
- { message: "Run 'base44 build' first", command: "base44 build" }
250796
- ]
250797
- });
250798
- }
250799
- if (!found.some((f) => f.path === options.entryFile)) {
250800
- throw new InvalidInputError(`${outputDir} has no ${options.entryFile}, so nothing could enter the site.`);
250801
- }
250802
- }
250803
- return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
250804
- }
250805
- async function describeSiteWorker(built) {
250806
- const { config, modules } = built;
250807
- const entry = resolve13(config.configDir, config.main);
250808
- const main = modules.find((m) => m.absolutePath === entry)?.name;
250809
- if (!main) {
250810
- throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
250811
- }
250812
- return {
250813
- main,
250814
- modules: await pMap(modules, async ({ name, absolutePath, size, type }) => ({
250815
- path: name,
250816
- absolutePath,
250817
- size,
250818
- digest: await digestFile(absolutePath),
250819
- type
250820
- }), { concurrency: HASH_CONCURRENCY }),
250821
- compatibilityDate: config.compatibilityDate,
250822
- compatibilityFlags: config.compatibilityFlags,
250823
- servingConfig: config.assetsConfig
250824
- };
250825
- }
250826
- async function readRawResources(dir) {
250827
- if (!await pathExists(dir)) {
250828
- return {};
250829
- }
250830
- const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
250831
- cwd: dir,
250832
- onlyFiles: true,
250833
- followSymbolicLinks: false
250834
- });
250835
- const payloads = {};
250836
- for (const relativePath of files.sort()) {
250837
- const name = relativePath.replace(/\.jsonc?$/, "");
250838
- payloads[name] = await readJsonFile(join29(dir, ...relativePath.split("/")));
250839
- }
250840
- return payloads;
250841
- }
250842
- async function collectResources(configDir, dirs) {
250843
- const [entities, agents] = await Promise.all([
250844
- readRawResources(join29(configDir, dirs.entitiesDir)),
250845
- readRawResources(join29(configDir, dirs.agentsDir))
250846
- ]);
250847
- return { entities, agents };
250848
- }
250849
- async function collectArtifacts(target) {
250850
- const built = await resolveFullStackBuild(target.root);
250851
- const siteWorker = built ? await describeSiteWorker(built) : null;
250852
- return {
250853
- assets: built ? built.assetsDir ? await collectBuildOutput(built.assetsDir) : [] : await collectBuildOutput(requireOutputDir(target), {
250854
- entryFile: ENTRY2
250855
- }),
250856
- ...siteWorker ? { siteWorker } : {},
250857
- ...await collectResources(target.configDir, target)
250858
- };
250859
- }
250860
- // src/core/version/gate.ts
250861
- var VERSIONS_API_ENV = "BASE44_VERSIONS_API";
250862
- function versionsApiEnabled(env = process.env) {
250863
- const value = env[VERSIONS_API_ENV];
250864
- return value === "1" || value === "true";
250865
- }
250866
- // src/core/version/publish.ts
250867
- import { randomUUID as randomUUID4 } from "node:crypto";
250868
- var DEFAULT_ENVIRONMENT = "production";
250869
- async function tagStep2(step, run) {
250870
- return await tagStep(step, run);
250871
- }
250872
- async function publishVersion(artifacts, options = {}) {
250873
- const version = await tagStep2("create_version", () => createVersion(artifacts, {
250874
- sourceCommit: options.sourceCommit,
250875
- concurrency: options.concurrency,
250876
- progress: options.progress
250877
- }));
250878
- const environment = await tagStep2("deploy", () => setEnvironmentVersion(options.target ?? DEFAULT_ENVIRONMENT, version.versionId, {
250879
- idempotencyKey: randomUUID4()
250880
- }));
250881
- return {
250882
- environment: environment.name,
250883
- versionId: environment.versionId,
250884
- manifestHash: environment.manifestHash,
250885
- deploymentId: environment.deploymentId
250886
- };
250887
- }
250888
- // src/cli/commands/versions/options.ts
250889
- function outputDirOption() {
250890
- return new Option2("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)");
250891
- }
250892
- function targetOption() {
250893
- return new Option2("--target <name>", "Environment to serve the version at");
250894
- }
250895
- function gitHashOption() {
250896
- return new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser((value) => {
250897
- if (!isGitCommitHash(value)) {
250898
- throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
250899
- }
250900
- return value;
250901
- });
250902
- }
250903
- function concurrencyOption() {
250904
- return new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser((value) => {
250905
- const parsed = Number(value);
250906
- if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
250907
- throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
250908
- }
250909
- return parsed;
250910
- });
250911
- }
250912
-
250913
- // src/cli/commands/publish.ts
250914
- async function publishAction(ctx, options) {
250915
- const { runTask, log, jsonMode } = ctx;
250916
- const app = requireApp(ctx);
250917
- const target = await tagStep2("create_version", () => resolveBuildTarget(app.projectRoot, { outputDir: options.outputDir }));
250918
- if (options.build !== false) {
250919
- await tagStep2("build", () => runSiteBuild(ctx, {
250920
- root: target.root,
250921
- buildCommand: target.buildCommand,
250922
- appId: app.id
250923
- }));
250924
- }
250925
- const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
250926
- const result = await runTask("Publishing...", async (updateMessage) => {
250927
- const artifacts = await tagStep2("create_version", () => collectArtifacts(target));
250928
- return await publishVersion(artifacts, {
250929
- sourceCommit: gitHash,
250930
- target: options.target,
250931
- concurrency: options.concurrency,
250932
- progress: {
250933
- onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
250934
- onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
250935
- }
250936
- });
250937
- }, { successMessage: "Published", errorMessage: "Publish failed" });
250938
- if (!jsonMode) {
250939
- log.message(theme.styles.dim(`version ${result.versionId}`));
250940
- }
250941
- return {
250942
- outroMessage: `${result.environment} now serves ${result.versionId}`,
250943
- stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
250944
- ` : undefined
250945
- };
250946
- }
250947
- function getPublishCommand() {
250948
- return new Base44Command("publish").description("Build the app, record it as a version, and serve that version").option("--no-build", "Publish the existing build output without rebuilding").addOption(outputDirOption()).addOption(targetOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(publishAction);
250949
- }
250950
-
250951
250608
  // src/core/resources/sandbox/schema.ts
250952
250609
  var FileErrorSchema = object({
250953
250610
  code: string2(),
@@ -251333,7 +250990,7 @@ function getSecretsListCommand() {
251333
250990
  }
251334
250991
 
251335
250992
  // src/cli/commands/secrets/set.ts
251336
- import { resolve as resolve14 } from "node:path";
250993
+ import { resolve as resolve12 } from "node:path";
251337
250994
  function parseEntries(entries) {
251338
250995
  const secrets = {};
251339
250996
  for (const entry of entries) {
@@ -251364,7 +251021,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
251364
251021
  validateInput(entries, options);
251365
251022
  let secrets;
251366
251023
  if (options.envFile) {
251367
- secrets = await parseEnvFile(resolve14(options.envFile));
251024
+ secrets = await parseEnvFile(resolve12(options.envFile));
251368
251025
  if (Object.keys(secrets).length === 0) {
251369
251026
  throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
251370
251027
  }
@@ -251393,7 +251050,7 @@ function getSecretsCommand() {
251393
251050
  }
251394
251051
 
251395
251052
  // src/cli/commands/site/deploy.ts
251396
- import { resolve as resolve15 } from "node:path";
251053
+ import { resolve as resolve13 } from "node:path";
251397
251054
  async function deployAction2(ctx, options) {
251398
251055
  const { isNonInteractive } = ctx;
251399
251056
  if (isNonInteractive && !options.yes) {
@@ -251471,7 +251128,7 @@ async function deployTarball({ runTask }, project) {
251471
251128
  }
251472
251129
  function siteOutputDir(project) {
251473
251130
  const outputDirectory = project.site?.outputDirectory;
251474
- return outputDirectory ? resolve15(project.root, outputDirectory) : null;
251131
+ return outputDirectory ? resolve13(project.root, outputDirectory) : null;
251475
251132
  }
251476
251133
  function getSiteDeployCommand() {
251477
251134
  const command = new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)");
@@ -251495,6 +251152,219 @@ function parseConcurrency(value) {
251495
251152
  return parsed;
251496
251153
  }
251497
251154
 
251155
+ // src/cli/dev/createDevLogger.ts
251156
+ var colorByType = {
251157
+ error: theme.styles.error,
251158
+ warn: theme.styles.warn,
251159
+ log: (input) => input
251160
+ };
251161
+ var stringify = (item) => {
251162
+ if (typeof item === "string") {
251163
+ return item;
251164
+ }
251165
+ if (item instanceof Error) {
251166
+ return item.toString();
251167
+ }
251168
+ try {
251169
+ return JSON.stringify(item, null, 2) ?? String(item);
251170
+ } catch {
251171
+ return String(item);
251172
+ }
251173
+ };
251174
+ function createDevLogger(label, labelColor = theme.styles.dim) {
251175
+ const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
251176
+ const print = (type, ...args) => {
251177
+ const colorize = colorByType[type];
251178
+ console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
251179
+ };
251180
+ return {
251181
+ log: (...args) => print("log", ...args),
251182
+ error: (msg, err) => {
251183
+ print("error", msg);
251184
+ if (err) {
251185
+ print("error", err);
251186
+ }
251187
+ },
251188
+ warn: (...args) => print("warn", ...args)
251189
+ };
251190
+ }
251191
+
251192
+ // src/cli/dev/dev-server/serve-runner.ts
251193
+ import { spawn as spawn2 } from "node:child_process";
251194
+ import process21 from "node:process";
251195
+
251196
+ class ServeRunner {
251197
+ command;
251198
+ cwd;
251199
+ env;
251200
+ logger;
251201
+ child;
251202
+ stopping = false;
251203
+ stopPromise;
251204
+ exitListeners = [];
251205
+ constructor(options) {
251206
+ this.command = options.command;
251207
+ this.cwd = options.cwd;
251208
+ this.env = options.env;
251209
+ this.logger = options.logger;
251210
+ }
251211
+ start() {
251212
+ if (this.child) {
251213
+ return;
251214
+ }
251215
+ const stdin = process21.platform === "win32" ? "ignore" : "inherit";
251216
+ const child = spawn2(this.command, {
251217
+ cwd: this.cwd,
251218
+ shell: true,
251219
+ detached: process21.platform !== "win32",
251220
+ env: { ...process21.env, ...this.env },
251221
+ stdio: [stdin, "pipe", "pipe"],
251222
+ windowsHide: true
251223
+ });
251224
+ this.child = child;
251225
+ this.setupHandlers(child);
251226
+ }
251227
+ onExit(listener) {
251228
+ this.exitListeners.push(listener);
251229
+ }
251230
+ async stop() {
251231
+ if (this.stopPromise) {
251232
+ return this.stopPromise;
251233
+ }
251234
+ this.stopPromise = this.stopChild();
251235
+ return this.stopPromise;
251236
+ }
251237
+ async stopChild() {
251238
+ const child = this.child;
251239
+ if (!child || child.exitCode !== null) {
251240
+ return;
251241
+ }
251242
+ this.stopping = true;
251243
+ const exited = new Promise((resolve) => child.once("exit", () => resolve()));
251244
+ if (process21.platform === "win32" && child.pid) {
251245
+ const taskkill = spawn2("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
251246
+ stdio: "ignore",
251247
+ windowsHide: true
251248
+ });
251249
+ await new Promise((resolve) => {
251250
+ taskkill.once("exit", () => resolve());
251251
+ taskkill.once("error", () => resolve());
251252
+ });
251253
+ } else if (child.pid) {
251254
+ try {
251255
+ process21.kill(-child.pid, "SIGTERM");
251256
+ } catch {
251257
+ child.kill();
251258
+ }
251259
+ }
251260
+ await exited;
251261
+ }
251262
+ setupHandlers(child) {
251263
+ child.stdout?.on("data", (data) => this.emitLines(data, "log"));
251264
+ child.stderr?.on("data", (data) => this.emitLines(data, "error"));
251265
+ child.on("error", (error) => {
251266
+ this.logger.error("Frontend dev server failed to start:", error);
251267
+ this.notifyExit(null);
251268
+ });
251269
+ child.on("exit", (code) => {
251270
+ if (this.stopping) {
251271
+ return;
251272
+ }
251273
+ this.logger.error(`Frontend dev server exited with code ${code}`);
251274
+ this.notifyExit(code);
251275
+ });
251276
+ }
251277
+ notifyExit(code) {
251278
+ for (const listener of this.exitListeners) {
251279
+ listener(code);
251280
+ }
251281
+ }
251282
+ emitLines(data, type) {
251283
+ const lines = data.toString().trimEnd().split(`
251284
+ `);
251285
+ for (const line of lines) {
251286
+ if (type === "error") {
251287
+ this.logger.error(line);
251288
+ } else {
251289
+ this.logger.log(line);
251290
+ }
251291
+ }
251292
+ }
251293
+ }
251294
+
251295
+ // src/cli/dev/serve-command-runner.ts
251296
+ function createServeCommandRunner({
251297
+ serveCommand,
251298
+ projectRoot,
251299
+ appId,
251300
+ appBaseUrl
251301
+ }) {
251302
+ return new ServeRunner({
251303
+ command: serveCommand,
251304
+ cwd: projectRoot,
251305
+ env: {
251306
+ VITE_BASE44_APP_ID: appId,
251307
+ ...appBaseUrl ? { VITE_BASE44_APP_BASE_URL: appBaseUrl } : {}
251308
+ },
251309
+ logger: createDevLogger("frontend", theme.colors.base44Orange)
251310
+ });
251311
+ }
251312
+
251313
+ // src/cli/dev/stop-runner-on-signals.ts
251314
+ import process22 from "node:process";
251315
+ function stopRunnerOnProcessSignals(runner) {
251316
+ const stop = () => void runner.stop();
251317
+ process22.on("SIGINT", stop);
251318
+ process22.on("SIGTERM", stop);
251319
+ }
251320
+
251321
+ // src/cli/commands/site/dev.ts
251322
+ function parsePort(value) {
251323
+ if (!/^\d+$/.test(value)) {
251324
+ throw new InvalidArgumentError2("must be a whole number");
251325
+ }
251326
+ const port = Number(value);
251327
+ if (port < 1 || port > 65535) {
251328
+ throw new InvalidArgumentError2("must be between 1 and 65535");
251329
+ }
251330
+ return port;
251331
+ }
251332
+ async function siteDevAction(ctx, options) {
251333
+ const { app } = ctx;
251334
+ if (!app?.projectRoot) {
251335
+ throw new ConfigInvalidError("base44 site dev requires a linked local project. Run it from a project with base44/.app.jsonc.");
251336
+ }
251337
+ const { project } = await readProjectConfig(app.projectRoot);
251338
+ const site = project.site;
251339
+ if (!site) {
251340
+ throw new InvalidInputError(`This project has no 'site' block in base44/config.jsonc, so there is no frontend to serve. Add one naming its serveCommand; site dev falls back to "npm run dev".`);
251341
+ }
251342
+ const serveCommand = site.serveCommand ?? DEFAULT_SERVE_COMMAND;
251343
+ const { command, droppedAddress } = withServeAddress(serveCommand, {
251344
+ host: options.host ?? site.devHost,
251345
+ port: options.port ?? site.devPort,
251346
+ hostFlag: site.devHostFlag
251347
+ });
251348
+ if (droppedAddress) {
251349
+ throw new InvalidInputError(`serveCommand '${serveCommand}' takes no forwarded arguments, so the bind address cannot be passed to it. Bind it inside serveCommand itself, or use an 'npm run', 'pnpm', 'yarn' or 'bun run' script.`);
251350
+ }
251351
+ const runner = createServeCommandRunner({
251352
+ serveCommand: command,
251353
+ projectRoot: project.root,
251354
+ appId: app.id,
251355
+ appBaseUrl: options.backendUrl
251356
+ });
251357
+ stopRunnerOnProcessSignals(runner);
251358
+ runner.onExit((code) => process.exit(code ?? 1));
251359
+ runner.start();
251360
+ return {
251361
+ outroMessage: options.backendUrl ? `Frontend dev server running '${command}' against ${theme.styles.bold(options.backendUrl)}` : `Frontend dev server running '${command}'`
251362
+ };
251363
+ }
251364
+ function getSiteDevCommand() {
251365
+ return new Base44Command("dev", { requireAuth: false }).description("Run the site's dev server against a given backend (no local backend)").option("--backend-url <url>", "Backend the frontend should call, injected as VITE_BASE44_APP_BASE_URL. Omit for a frontend that reaches its backend same-origin.").option("--host <address>", "Address to bind, overriding site.devHost").option("--port <number>", "Port to bind, overriding site.devPort", parsePort).action(siteDevAction);
251366
+ }
251367
+
251498
251368
  // src/cli/commands/site/open.ts
251499
251369
  async function openAction({
251500
251370
  isNonInteractive
@@ -251511,7 +251381,7 @@ function getSiteOpenCommand() {
251511
251381
 
251512
251382
  // src/cli/commands/site/index.ts
251513
251383
  function getSiteCommand() {
251514
- return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteOpenCommand());
251384
+ return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteDevCommand()).addCommand(getSiteOpenCommand());
251515
251385
  }
251516
251386
 
251517
251387
  // src/core/types/generator.ts
@@ -251603,10 +251473,10 @@ function toPascalCase(name) {
251603
251473
  return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
251604
251474
  }
251605
251475
  // src/core/types/update-project.ts
251606
- import { join as join33 } from "node:path";
251476
+ import { join as join30 } from "node:path";
251607
251477
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
251608
251478
  async function updateProjectConfig(projectRoot) {
251609
- const tsconfigPath = join33(projectRoot, "tsconfig.json");
251479
+ const tsconfigPath = join30(projectRoot, "tsconfig.json");
251610
251480
  if (!await pathExists(tsconfigPath)) {
251611
251481
  return false;
251612
251482
  }
@@ -251655,59 +251525,6 @@ function getTypesCommand() {
251655
251525
  return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
251656
251526
  }
251657
251527
 
251658
- // src/cli/commands/versions/create.ts
251659
- async function createAction2(ctx, options) {
251660
- const { runTask, jsonMode } = ctx;
251661
- const target = await resolveBuildTarget(requireApp(ctx).projectRoot, {
251662
- outputDir: options.outputDir
251663
- });
251664
- const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
251665
- const version = await runTask("Creating version...", async (updateMessage) => await createVersion(await collectArtifacts(target), {
251666
- sourceCommit: gitHash,
251667
- concurrency: options.concurrency,
251668
- progress: {
251669
- onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
251670
- onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
251671
- }
251672
- }), {
251673
- successMessage: "Version created",
251674
- errorMessage: "Create version failed"
251675
- });
251676
- return {
251677
- outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
251678
- stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
251679
- ` : undefined
251680
- };
251681
- }
251682
- function getVersionCreateCommand() {
251683
- return new Base44Command("create").description("Record the built output as a version, without deploying it").addOption(outputDirOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(createAction2);
251684
- }
251685
-
251686
- // src/cli/commands/versions/deploy.ts
251687
- import { randomUUID as randomUUID5 } from "node:crypto";
251688
- async function deployAction3({ runTask, jsonMode }, versionId, options) {
251689
- const environment = options.target ?? DEFAULT_ENVIRONMENT;
251690
- const result = await runTask(`Pointing ${environment} at ${versionId}...`, async () => await setEnvironmentVersion(environment, versionId, {
251691
- idempotencyKey: randomUUID5()
251692
- }), {
251693
- successMessage: "Environment updated",
251694
- errorMessage: "Could not update the environment"
251695
- });
251696
- return {
251697
- outroMessage: `${result.name} now serves ${result.versionId}`,
251698
- stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
251699
- ` : undefined
251700
- };
251701
- }
251702
- function getVersionDeployCommand() {
251703
- return new Base44Command("deploy").description("Point an environment at an already-recorded version (also the rollback)").argument("<version-id>", "The version to serve").addOption(targetOption()).action(deployAction3);
251704
- }
251705
-
251706
- // src/cli/commands/versions/index.ts
251707
- function getVersionsCommand() {
251708
- return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
251709
- }
251710
-
251711
251528
  // src/core/resources/workflow/schema.ts
251712
251529
  var WorkflowRunStatusSchema = _enum([
251713
251530
  "running",
@@ -252084,47 +251901,10 @@ function getWorkspaceCommand() {
252084
251901
  return new Command2("workspace").description("List workspaces, inspect one, and move apps between them").addCommand(getWorkspaceListCommand()).addCommand(getWorkspaceGetCommand()).addCommand(getWorkspaceMoveCommand());
252085
251902
  }
252086
251903
 
252087
- // src/cli/dev/createDevLogger.ts
252088
- var colorByType = {
252089
- error: theme.styles.error,
252090
- warn: theme.styles.warn,
252091
- log: (input) => input
252092
- };
252093
- var stringify = (item) => {
252094
- if (typeof item === "string") {
252095
- return item;
252096
- }
252097
- if (item instanceof Error) {
252098
- return item.toString();
252099
- }
252100
- try {
252101
- return JSON.stringify(item, null, 2) ?? String(item);
252102
- } catch {
252103
- return String(item);
252104
- }
252105
- };
252106
- function createDevLogger(label, labelColor = theme.styles.dim) {
252107
- const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
252108
- const print = (type, ...args) => {
252109
- const colorize = colorByType[type];
252110
- console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
252111
- };
252112
- return {
252113
- log: (...args) => print("log", ...args),
252114
- error: (msg, err) => {
252115
- print("error", msg);
252116
- if (err) {
252117
- print("error", err);
252118
- }
252119
- },
252120
- warn: (...args) => print("warn", ...args)
252121
- };
252122
- }
252123
-
252124
251904
  // src/cli/dev/dev-server/main.ts
252125
251905
  var import_cors = __toESM(require_lib4(), 1);
252126
251906
  var import_express6 = __toESM(require_express(), 1);
252127
- import { dirname as dirname27, join as join38 } from "node:path";
251907
+ import { dirname as dirname26, join as join36 } from "node:path";
252128
251908
 
252129
251909
  // ../../node_modules/get-port/index.js
252130
251910
  import net from "node:net";
@@ -252253,8 +252033,8 @@ var $dir = async (options) => dirWithOptions(options);
252253
252033
  var $tmpName = promisify11(tmp.tmpName);
252254
252034
 
252255
252035
  // src/cli/dev/dev-server/function-manager.ts
252256
- import { spawn as spawn2 } from "node:child_process";
252257
- import { dirname as dirname24, join as join34 } from "node:path";
252036
+ import { spawn as spawn3 } from "node:child_process";
252037
+ import { dirname as dirname23, join as join31 } from "node:path";
252258
252038
  import { pathToFileURL } from "node:url";
252259
252039
 
252260
252040
  // src/cli/dev/dev-server/base-function-manager.ts
@@ -252351,7 +252131,7 @@ class FunctionManager extends BaseFunctionManager {
252351
252131
  async stopFunction(_name, { process: proc }) {
252352
252132
  const exited = new Promise((r) => proc.once("exit", () => r()));
252353
252133
  if (process.platform === "win32" && proc.pid) {
252354
- spawn2("taskkill", ["/pid", String(proc.pid), "/T", "/F"]);
252134
+ spawn3("taskkill", ["/pid", String(proc.pid), "/T", "/F"]);
252355
252135
  } else {
252356
252136
  proc.kill();
252357
252137
  }
@@ -252359,8 +252139,8 @@ class FunctionManager extends BaseFunctionManager {
252359
252139
  }
252360
252140
  spawnFunction(func, port) {
252361
252141
  this.logger.log(`Spawning function "${func.name}" on port ${port}`);
252362
- const importMapPath = join34(dirname24(this.wrapperPath), "import-map.json");
252363
- const process2 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
252142
+ const importMapPath = join31(dirname23(this.wrapperPath), "import-map.json");
252143
+ const process2 = spawn3("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
252364
252144
  env: {
252365
252145
  ...globalThis.process.env,
252366
252146
  FUNCTION_PATH: pathToFileURL(func.entryPath).href,
@@ -252433,7 +252213,7 @@ class FunctionManager extends BaseFunctionManager {
252433
252213
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
252434
252214
  import { isBuiltin } from "node:module";
252435
252215
  import { homedir as homedir3 } from "node:os";
252436
- import { join as join35 } from "node:path";
252216
+ import { join as join33 } from "node:path";
252437
252217
  import { pathToFileURL as pathToFileURL6 } from "node:url";
252438
252218
  var depsPromise;
252439
252219
  function loadDeps() {
@@ -252554,9 +252334,9 @@ export default {
252554
252334
  };
252555
252335
  `;
252556
252336
  function ensureBundlerConfig() {
252557
- const dir = join35(homedir3(), ".base44", "function-bundler");
252337
+ const dir = join33(homedir3(), ".base44", "function-bundler");
252558
252338
  mkdirSync2(dir, { recursive: true });
252559
- const configPath = join35(dir, "deno.json");
252339
+ const configPath = join33(dir, "deno.json");
252560
252340
  writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
252561
252341
  `);
252562
252342
  return configPath;
@@ -253937,11 +253717,11 @@ async function createEntityRoutes(db, logger, broadcast) {
253937
253717
  // src/cli/dev/dev-server/routes/integrations.ts
253938
253718
  var import_express5 = __toESM(require_express(), 1);
253939
253719
  var import_multer = __toESM(require_multer(), 1);
253940
- import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
253720
+ import { createHash as createHash2, randomUUID as randomUUID4 } from "node:crypto";
253941
253721
  import fs28 from "node:fs";
253942
253722
  import path18 from "node:path";
253943
253723
  function createFileToken(fileUri) {
253944
- return createHash3("sha256").update(fileUri).digest("hex");
253724
+ return createHash2("sha256").update(fileUri).digest("hex");
253945
253725
  }
253946
253726
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253947
253727
  const router = import_express5.Router({ mergeParams: true });
@@ -253954,14 +253734,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253954
253734
  destination: mediaFilesDir,
253955
253735
  filename: (_req, file, cb) => {
253956
253736
  const ext = path18.extname(file.originalname);
253957
- cb(null, `${randomUUID6()}${ext}`);
253737
+ cb(null, `${randomUUID4()}${ext}`);
253958
253738
  }
253959
253739
  });
253960
253740
  const privateStorage = import_multer.default.diskStorage({
253961
253741
  destination: privateFilesDir,
253962
253742
  filename: (_req, file, cb) => {
253963
253743
  const ext = path18.extname(file.originalname);
253964
- cb(null, `${randomUUID6()}${ext}`);
253744
+ cb(null, `${randomUUID4()}${ext}`);
253965
253745
  }
253966
253746
  });
253967
253747
  const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
@@ -255823,8 +255603,8 @@ async function createDevServer(options) {
255823
255603
  broadcastEntityEvent(io, appId, entityName, event);
255824
255604
  };
255825
255605
  const base44ConfigWatcher = new WatchBase44({
255826
- functions: join38(dirname27(project.configPath), project.functionsDir),
255827
- entities: join38(dirname27(project.configPath), project.entitiesDir)
255606
+ functions: join36(dirname26(project.configPath), project.functionsDir),
255607
+ entities: join36(dirname26(project.configPath), project.entitiesDir)
255828
255608
  }, devLogger);
255829
255609
  base44ConfigWatcher.on("change", async (name) => {
255830
255610
  try {
@@ -255890,127 +255670,6 @@ async function createDevServer(options) {
255890
255670
  return { port, server, shutdown };
255891
255671
  }
255892
255672
 
255893
- // src/cli/dev/dev-server/serve-runner.ts
255894
- import { spawn as spawn3 } from "node:child_process";
255895
- import process23 from "node:process";
255896
-
255897
- class ServeRunner {
255898
- command;
255899
- cwd;
255900
- env;
255901
- logger;
255902
- child;
255903
- stopping = false;
255904
- stopPromise;
255905
- exitListeners = [];
255906
- constructor(options) {
255907
- this.command = options.command;
255908
- this.cwd = options.cwd;
255909
- this.env = options.env;
255910
- this.logger = options.logger;
255911
- }
255912
- start() {
255913
- if (this.child) {
255914
- return;
255915
- }
255916
- const stdin = process23.platform === "win32" ? "ignore" : "inherit";
255917
- const child = spawn3(this.command, {
255918
- cwd: this.cwd,
255919
- shell: true,
255920
- detached: process23.platform !== "win32",
255921
- env: { ...process23.env, ...this.env },
255922
- stdio: [stdin, "pipe", "pipe"],
255923
- windowsHide: true
255924
- });
255925
- this.child = child;
255926
- this.setupHandlers(child);
255927
- }
255928
- onExit(listener) {
255929
- this.exitListeners.push(listener);
255930
- }
255931
- async stop() {
255932
- if (this.stopPromise) {
255933
- return this.stopPromise;
255934
- }
255935
- this.stopPromise = this.stopChild();
255936
- return this.stopPromise;
255937
- }
255938
- async stopChild() {
255939
- const child = this.child;
255940
- if (!child || child.exitCode !== null) {
255941
- return;
255942
- }
255943
- this.stopping = true;
255944
- const exited = new Promise((resolve) => child.once("exit", () => resolve()));
255945
- if (process23.platform === "win32" && child.pid) {
255946
- const taskkill = spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
255947
- stdio: "ignore",
255948
- windowsHide: true
255949
- });
255950
- await new Promise((resolve) => {
255951
- taskkill.once("exit", () => resolve());
255952
- taskkill.once("error", () => resolve());
255953
- });
255954
- } else if (child.pid) {
255955
- try {
255956
- process23.kill(-child.pid, "SIGTERM");
255957
- } catch {
255958
- child.kill();
255959
- }
255960
- }
255961
- await exited;
255962
- }
255963
- setupHandlers(child) {
255964
- child.stdout?.on("data", (data) => this.emitLines(data, "log"));
255965
- child.stderr?.on("data", (data) => this.emitLines(data, "error"));
255966
- child.on("error", (error) => {
255967
- this.logger.error("Frontend dev server failed to start:", error);
255968
- this.notifyExit(null);
255969
- });
255970
- child.on("exit", (code) => {
255971
- if (this.stopping) {
255972
- return;
255973
- }
255974
- this.logger.error(`Frontend dev server exited with code ${code}`);
255975
- this.notifyExit(code);
255976
- });
255977
- }
255978
- notifyExit(code) {
255979
- for (const listener of this.exitListeners) {
255980
- listener(code);
255981
- }
255982
- }
255983
- emitLines(data, type) {
255984
- const lines = data.toString().trimEnd().split(`
255985
- `);
255986
- for (const line of lines) {
255987
- if (type === "error") {
255988
- this.logger.error(line);
255989
- } else {
255990
- this.logger.log(line);
255991
- }
255992
- }
255993
- }
255994
- }
255995
-
255996
- // src/cli/dev/serve-command-runner.ts
255997
- function createServeCommandRunner({
255998
- serveCommand,
255999
- projectRoot,
256000
- appId,
256001
- appBaseUrl
256002
- }) {
256003
- return new ServeRunner({
256004
- command: serveCommand,
256005
- cwd: projectRoot,
256006
- env: {
256007
- VITE_BASE44_APP_ID: appId,
256008
- VITE_BASE44_APP_BASE_URL: appBaseUrl
256009
- },
256010
- logger: createDevLogger("frontend", theme.colors.base44Orange)
256011
- });
256012
- }
256013
-
256014
255673
  // src/cli/commands/dev.ts
256015
255674
  function localServerUrl(port) {
256016
255675
  return `http://localhost:${port}`;
@@ -256036,11 +255695,6 @@ async function resolveConfiguredSite(app) {
256036
255695
  const serveCommand = project.site?.serveCommand;
256037
255696
  return serveCommand ? { serveCommand, projectRoot: project.root } : undefined;
256038
255697
  }
256039
- function stopRunnerOnProcessSignals(runner) {
256040
- const stop = () => void runner.stop();
256041
- process.on("SIGINT", stop);
256042
- process.on("SIGTERM", stop);
256043
- }
256044
255698
  function startServeCommand(runner, backend) {
256045
255699
  stopRunnerOnProcessSignals(runner);
256046
255700
  runner.onExit(() => {
@@ -256154,7 +255808,7 @@ function readStdin2() {
256154
255808
  process.stdin.on("error", reject);
256155
255809
  });
256156
255810
  }
256157
- function parsePort(value) {
255811
+ function parsePort2(value) {
256158
255812
  const port = Number(value);
256159
255813
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
256160
255814
  throw new InvalidInputError(`Invalid --port value: "${value}".`, {
@@ -256191,7 +255845,7 @@ async function execAction({ app, isNonInteractive }, options) {
256191
255845
  if (!code.trim()) {
256192
255846
  throw noInputError;
256193
255847
  }
256194
- const local = options.local ? await resolveLocalTarget(options.port !== undefined ? parsePort(options.port) : DEFAULT_DEV_SERVER_PORT) : undefined;
255848
+ const local = options.local ? await resolveLocalTarget(options.port !== undefined ? parsePort2(options.port) : DEFAULT_DEV_SERVER_PORT) : undefined;
256195
255849
  const { exitCode } = await runScript({
256196
255850
  appId: app.id,
256197
255851
  code,
@@ -256221,7 +255875,7 @@ Examples:
256221
255875
  }
256222
255876
 
256223
255877
  // src/cli/commands/project/eject.ts
256224
- import { resolve as resolve19 } from "node:path";
255878
+ import { resolve as resolve17 } from "node:path";
256225
255879
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
256226
255880
  async function eject(ctx, options, command) {
256227
255881
  const { log, runTask, isNonInteractive } = ctx;
@@ -256285,7 +255939,7 @@ async function eject(ctx, options, command) {
256285
255939
  Ne("Operation cancelled.");
256286
255940
  throw new CLIExitError(0);
256287
255941
  }
256288
- const resolvedPath = resolve19(selectedPath);
255942
+ const resolvedPath = resolve17(selectedPath);
256289
255943
  await runTask("Downloading your project's code...", async (updateMessage) => {
256290
255944
  await createProjectFilesForExistingProject({
256291
255945
  projectId,
@@ -256356,6 +256010,7 @@ function createProgram(context) {
256356
256010
  program.addCommand(getCreateCommand());
256357
256011
  program.addCommand(getScaffoldCommand());
256358
256012
  program.addCommand(getDashboardCommand());
256013
+ program.addCommand(getInstallCommand());
256359
256014
  program.addCommand(getBuildCommand());
256360
256015
  program.addCommand(getDeployCommand3());
256361
256016
  program.addCommand(getVisibilityCommand());
@@ -256374,10 +256029,6 @@ function createProgram(context) {
256374
256029
  program.addCommand(getBranchesCommand());
256375
256030
  program.addCommand(getAuthCommand());
256376
256031
  program.addCommand(getSiteCommand());
256377
- if (versionsApiEnabled()) {
256378
- program.addCommand(getPublishCommand());
256379
- program.addCommand(getVersionsCommand());
256380
- }
256381
256032
  program.addCommand(getTypesCommand());
256382
256033
  program.addCommand(getExecCommand());
256383
256034
  program.addCommand(getDevCommand());
@@ -256390,7 +256041,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
256390
256041
  import { release, type } from "node:os";
256391
256042
 
256392
256043
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
256393
- import { dirname as dirname28, posix, sep as sep2 } from "path";
256044
+ import { dirname as dirname27, posix, sep as sep2 } from "path";
256394
256045
  function createModulerModifier() {
256395
256046
  const getModuleFromFileName = createGetModuleFromFilename();
256396
256047
  return async (frames) => {
@@ -256399,7 +256050,7 @@ function createModulerModifier() {
256399
256050
  return frames;
256400
256051
  };
256401
256052
  }
256402
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname28(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
256053
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname27(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
256403
256054
  const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
256404
256055
  return (filename) => {
256405
256056
  if (!filename)
@@ -260388,9 +260039,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
260388
260039
  });
260389
260040
  }
260390
260041
  // src/cli/index.ts
260391
- var __dirname4 = dirname29(fileURLToPath6(import.meta.url));
260042
+ var __dirname4 = dirname28(fileURLToPath6(import.meta.url));
260392
260043
  async function runCLI(options) {
260393
- ensureNpmAssets(join39(__dirname4, "../assets"));
260044
+ ensureNpmAssets(join37(__dirname4, "../assets"));
260394
260045
  const errorReporter = new ErrorReporter;
260395
260046
  errorReporter.registerProcessErrorHandlers();
260396
260047
  const jsonMode = process.argv.includes("--json");
@@ -260429,4 +260080,4 @@ export {
260429
260080
  runCLI
260430
260081
  };
260431
260082
 
260432
- //# debugId=53FA3E8A10325F7E64756E2164756E21
260083
+ //# debugId=E803849EB8B019CA64756E2164756E21