@base44-preview/cli 0.1.12-pr.584.81e385d → 0.1.12-pr.584.d15e5fc

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
@@ -248211,19 +248211,23 @@ async function createDeployment(request) {
248211
248211
  }
248212
248212
  return result.data;
248213
248213
  }
248214
- async function finalizeDeployment(deploymentId, sessionId, payload) {
248214
+ async function finalizeDeployment(deploymentId, completionJwt, modules, sessionId) {
248215
248215
  const formData = new FormData;
248216
- if ("indexHtml" in payload) {
248217
- formData.append("index.html", new File([payload.indexHtml], "index.html", { type: "text/html" }));
248218
- } else {
248219
- formData.append("payload", JSON.stringify({ completion_jwt: payload.completionJwt }));
248220
- for (const module of payload.modules) {
248221
- const content = await readFile(module.absolutePath);
248222
- formData.append(module.name, new File([new Uint8Array(content)], module.name, {
248223
- type: MODULE_CONTENT_TYPES[module.type]
248224
- }));
248225
- }
248216
+ formData.append("payload", JSON.stringify({ completion_jwt: completionJwt }));
248217
+ for (const module of modules) {
248218
+ const content = await readFile(module.absolutePath);
248219
+ formData.append(module.name, new File([new Uint8Array(content)], module.name, {
248220
+ type: MODULE_CONTENT_TYPES[module.type]
248221
+ }));
248226
248222
  }
248223
+ return await postFinalize(deploymentId, formData, sessionId);
248224
+ }
248225
+ async function finalizeStaticDeployment(deploymentId, indexHtml, sessionId) {
248226
+ const formData = new FormData;
248227
+ formData.append("index.html", new File([indexHtml], "index.html", { type: "text/html" }));
248228
+ return await postFinalize(deploymentId, formData, sessionId);
248229
+ }
248230
+ async function postFinalize(deploymentId, formData, sessionId) {
248227
248231
  const appClient = getAppClient();
248228
248232
  let response;
248229
248233
  try {
@@ -248291,117 +248295,14 @@ async function createArchive(pathToArchive, targetArchivePath) {
248291
248295
  // src/core/site/deploy-app.ts
248292
248296
  import { resolve as resolve4 } from "node:path";
248293
248297
 
248294
- // src/core/site/wrangler-config.ts
248295
- import { dirname as dirname10, join as join15, resolve as resolve3 } from "node:path";
248296
- var WRANGLER_REDIRECT_PATH = join15(".wrangler", "deploy", "config.json");
248297
- var RedirectConfigSchema = exports_external.looseObject({
248298
- configPath: exports_external.string().min(1)
248299
- });
248300
- var WranglerConfigSchema = exports_external.looseObject({
248301
- main: exports_external.string().min(1, "wrangler config is missing a 'main' entry module"),
248302
- no_bundle: exports_external.boolean().optional(),
248303
- rules: exports_external.array(exports_external.looseObject({ type: exports_external.string(), globs: exports_external.array(exports_external.string()) })).optional(),
248304
- assets: exports_external.looseObject({
248305
- directory: exports_external.string().optional(),
248306
- html_handling: exports_external.string().optional(),
248307
- not_found_handling: exports_external.string().optional(),
248308
- run_worker_first: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional(),
248309
- headers: exports_external.string().optional(),
248310
- redirects: exports_external.string().optional()
248311
- }).optional(),
248312
- compatibility_date: exports_external.string().optional(),
248313
- compatibility_flags: exports_external.array(exports_external.string()).optional(),
248314
- vars: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
248315
- upload_source_maps: exports_external.boolean().optional()
248316
- });
248317
- async function detectFullStackArtifact(projectRoot) {
248318
- const redirectPath = join15(projectRoot, WRANGLER_REDIRECT_PATH);
248319
- return await pathExists(redirectPath) ? redirectPath : null;
248320
- }
248321
- async function resolveWranglerConfig(projectRoot) {
248322
- const redirectPath = await detectFullStackArtifact(projectRoot);
248323
- if (!redirectPath) {
248324
- throw new InvalidInputError("No Workers build artifact found. Expected a .wrangler/deploy/config.json redirect file.", {
248325
- hints: [{ message: "Run your framework's build command first" }]
248326
- });
248327
- }
248328
- const configPath = await resolveRedirectedConfigPath(redirectPath);
248329
- const parsed = await readJsonFile(configPath);
248330
- const result = WranglerConfigSchema.safeParse(parsed);
248331
- if (!result.success) {
248332
- throw new ConfigInvalidError(`Invalid wrangler config: ${exports_external.prettifyError(result.error)}`, configPath);
248333
- }
248334
- const config9 = result.data;
248335
- if (config9.no_bundle !== true) {
248336
- throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
248337
- }
248338
- const configDir = dirname10(configPath);
248339
- const assetsDirectory = config9.assets?.directory ? resolve3(configDir, config9.assets.directory) : null;
248340
- return {
248341
- configPath,
248342
- configDir,
248343
- main: config9.main,
248344
- assetsDirectory,
248345
- assetsConfig: config9.assets ? toResolvedAssetsConfig(config9.assets) : null,
248346
- compatibilityDate: config9.compatibility_date ?? null,
248347
- compatibilityFlags: config9.compatibility_flags ?? [],
248348
- vars: config9.vars ?? {},
248349
- rules: (config9.rules ?? []).map((rule) => ({
248350
- type: rule.type,
248351
- globs: rule.globs
248352
- })),
248353
- uploadSourceMaps: config9.upload_source_maps ?? false
248354
- };
248355
- }
248356
- async function resolveRedirectedConfigPath(redirectPath) {
248357
- const parsed = await readJsonFile(redirectPath);
248358
- const result = RedirectConfigSchema.safeParse(parsed);
248359
- if (!result.success) {
248360
- throw new ConfigInvalidError(`Invalid deploy redirect file: ${exports_external.prettifyError(result.error)}`, redirectPath);
248361
- }
248362
- const configPath = resolve3(dirname10(redirectPath), result.data.configPath);
248363
- if (!await pathExists(configPath)) {
248364
- throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
248365
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
248366
- });
248367
- }
248368
- return configPath;
248369
- }
248370
- function toResolvedAssetsConfig(assets) {
248371
- return {
248372
- htmlHandling: assets.html_handling,
248373
- notFoundHandling: assets.not_found_handling,
248374
- runWorkerFirst: assets.run_worker_first,
248375
- headers: assets.headers,
248376
- redirects: assets.redirects
248377
- };
248378
- }
248379
-
248380
- // src/core/site/deploy-app.ts
248381
- var STATIC_DEPLOYMENTS_ENV = "BASE44_STATIC_DEPLOYMENTS";
248382
- function staticDeploymentsEnabled(env2 = process.env) {
248383
- const value = env2[STATIC_DEPLOYMENTS_ENV];
248384
- return value === "1" || value === "true";
248385
- }
248386
- async function planAppDeploy(target) {
248387
- const outputDirectory = target.site?.outputDirectory;
248388
- const outputDir = outputDirectory ? resolve4(target.root, outputDirectory) : null;
248389
- if (await detectFullStackArtifact(target.root)) {
248390
- return { kind: "deployment", outputDir };
248391
- }
248392
- if (!outputDir) {
248393
- return { kind: "none" };
248394
- }
248395
- return staticDeploymentsEnabled() ? { kind: "deployment", outputDir } : { kind: "tarball", outputDir };
248396
- }
248397
- // src/core/site/deployment.ts
248298
+ // src/core/site/static-site.ts
248398
248299
  import { readFile as readFile4 } from "node:fs/promises";
248399
- import { join as join17 } from "node:path";
248300
+ import { join as join16 } from "node:path";
248400
248301
 
248401
248302
  // src/core/site/manifest.ts
248402
248303
  import { createHash } from "node:crypto";
248403
248304
  import { readFile as readFile2, stat } from "node:fs/promises";
248404
- import { basename as basename4, extname, join as join16 } from "node:path";
248305
+ import { basename as basename4, extname, join as join15 } from "node:path";
248405
248306
  var MAX_ASSET_SIZE_BYTES = 25 * 1024 * 1024;
248406
248307
  var MAX_ASSET_COUNT = 1e5;
248407
248308
  var ASSETS_IGNORE_FILE = ".assetsignore";
@@ -248461,7 +248362,7 @@ async function buildAssetManifest(assetsDir, appId) {
248461
248362
  throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
248462
248363
  }
248463
248364
  for (const relativePath of relativeFilePaths.sort()) {
248464
- const absolutePath = join16(assetsDir, ...relativePath.split("/"));
248365
+ const absolutePath = join15(assetsDir, ...relativePath.split("/"));
248465
248366
  const { size } = await stat(absolutePath);
248466
248367
  if (size > MAX_ASSET_SIZE_BYTES) {
248467
248368
  throw new InvalidInputError(`Static asset "${relativePath}" is ${size} bytes, which exceeds the 25 MiB per-file limit.`);
@@ -248481,101 +248382,6 @@ async function buildAssetManifest(assetsDir, appId) {
248481
248382
  return { manifest, filesByHash };
248482
248383
  }
248483
248384
 
248484
- // src/core/site/modules.ts
248485
- import { stat as stat2 } from "node:fs/promises";
248486
- import { relative as relative3, resolve as resolve5, sep } from "node:path";
248487
- var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
248488
- var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
248489
- var RULE_TYPE_TO_MODULE_TYPE = {
248490
- ESModule: "esm",
248491
- CompiledWasm: "wasm",
248492
- Text: "text",
248493
- Data: "data"
248494
- };
248495
- function toPosix(path11) {
248496
- return path11.split(sep).join("/");
248497
- }
248498
- async function collectModules(config9) {
248499
- const entryPath = resolve5(config9.configDir, config9.main);
248500
- if (!await pathExists(entryPath)) {
248501
- throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config9.configPath})`, {
248502
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
248503
- });
248504
- }
248505
- const modulesByName = new Map;
248506
- const entryName = toPosix(relative3(config9.configDir, entryPath));
248507
- modulesByName.set(entryName, {
248508
- name: entryName,
248509
- absolutePath: entryPath,
248510
- size: 0,
248511
- type: "esm"
248512
- });
248513
- const ignore = [...MODULE_IGNORE];
248514
- if (config9.assetsDirectory?.startsWith(config9.configDir + sep)) {
248515
- ignore.push(`${toPosix(relative3(config9.configDir, config9.assetsDirectory))}/**`);
248516
- }
248517
- for (const rule of config9.rules) {
248518
- const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
248519
- if (!type) {
248520
- throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config9.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
248521
- }
248522
- const matches = await globby(rule.globs, {
248523
- cwd: config9.configDir,
248524
- onlyFiles: true,
248525
- dot: true,
248526
- ignore
248527
- });
248528
- for (const match of matches.sort()) {
248529
- if (!modulesByName.has(match)) {
248530
- modulesByName.set(match, {
248531
- name: match,
248532
- absolutePath: resolve5(config9.configDir, match),
248533
- size: 0,
248534
- type
248535
- });
248536
- }
248537
- }
248538
- }
248539
- if (config9.uploadSourceMaps) {
248540
- const maps = await globby("**/*.map", {
248541
- cwd: config9.configDir,
248542
- onlyFiles: true,
248543
- dot: true,
248544
- ignore
248545
- });
248546
- for (const map2 of maps.sort()) {
248547
- addSourcemap(modulesByName, config9.configDir, map2);
248548
- }
248549
- } else {
248550
- for (const name2 of [...modulesByName.keys()]) {
248551
- const mapName = `${name2}.map`;
248552
- if (await pathExists(resolve5(config9.configDir, mapName))) {
248553
- addSourcemap(modulesByName, config9.configDir, mapName);
248554
- }
248555
- }
248556
- }
248557
- const modules = [...modulesByName.values()];
248558
- let totalBytes = 0;
248559
- for (const module of modules) {
248560
- module.size = (await stat2(module.absolutePath)).size;
248561
- totalBytes += module.size;
248562
- }
248563
- if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
248564
- throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for a Base44 deploy.`);
248565
- }
248566
- return modules;
248567
- }
248568
- function addSourcemap(modulesByName, configDir, name2) {
248569
- if (modulesByName.has(name2))
248570
- return;
248571
- modulesByName.set(name2, {
248572
- name: name2,
248573
- absolutePath: resolve5(configDir, name2),
248574
- size: 0,
248575
- type: "sourcemap"
248576
- });
248577
- }
248578
-
248579
248385
  // src/core/site/upload.ts
248580
248386
  import { readFile as readFile3 } from "node:fs/promises";
248581
248387
 
@@ -248610,7 +248416,7 @@ async function pMap(iterable, mapper, {
248610
248416
  const cleanup = () => {
248611
248417
  signal?.removeEventListener("abort", signalListener);
248612
248418
  };
248613
- const resolve6 = (value) => {
248419
+ const resolve3 = (value) => {
248614
248420
  resolve_(value);
248615
248421
  cleanup();
248616
248422
  };
@@ -248643,7 +248449,7 @@ async function pMap(iterable, mapper, {
248643
248449
  }
248644
248450
  isResolved = true;
248645
248451
  if (skippedIndexesMap.size === 0) {
248646
- resolve6(result);
248452
+ resolve3(result);
248647
248453
  return;
248648
248454
  }
248649
248455
  const pureResult = [];
@@ -248653,7 +248459,7 @@ async function pMap(iterable, mapper, {
248653
248459
  }
248654
248460
  pureResult.push(value);
248655
248461
  }
248656
- resolve6(pureResult);
248462
+ resolve3(pureResult);
248657
248463
  }
248658
248464
  return;
248659
248465
  }
@@ -248712,27 +248518,6 @@ var UPLOAD_RETRY = {
248712
248518
  limit: MAX_UPLOAD_ATTEMPTS - 1,
248713
248519
  delay: (attempt) => RETRY_BASE_DELAY_MS * 2 ** (attempt - 1)
248714
248520
  };
248715
- async function uploadDeploymentAssets(assetUploads, assets, options = {}) {
248716
- const { concurrency, progress } = options;
248717
- progress?.onAssets?.({
248718
- totalAssets: Object.keys(assets.manifest).length,
248719
- newAssets: countOwedAssets(assetUploads)
248720
- });
248721
- if (!assetUploads) {
248722
- return null;
248723
- }
248724
- const uploadOptions = { concurrency, onProgress: progress?.onAssetUpload };
248725
- if (assetUploads.type === "cf") {
248726
- return await uploadAssetBuckets(assetUploads, assets.filesByHash, uploadOptions);
248727
- }
248728
- await uploadPresignedAssets(assetUploads.uploads, assets, uploadOptions);
248729
- return null;
248730
- }
248731
- function countOwedAssets(assetUploads) {
248732
- if (!assetUploads)
248733
- return 0;
248734
- return assetUploads.type === "cf" ? new Set(assetUploads.buckets.flat()).size : assetUploads.uploads.length;
248735
- }
248736
248521
  async function uploadAssetBuckets(target, filesByHash, options = {}) {
248737
248522
  const { concurrency = DEFAULT_UPLOAD_CONCURRENCY, onProgress } = options;
248738
248523
  const { buckets } = target;
@@ -248813,54 +248598,271 @@ async function uploadPresignedAsset(upload, assets) {
248813
248598
  }
248814
248599
  }
248815
248600
 
248816
- // src/core/site/deployment.ts
248817
- var NO_ASSETS = { manifest: {}, filesByHash: new Map };
248818
- async function deployToDeployments(options) {
248819
- const { projectRoot, outputDir, gitHash, concurrency, progress } = options;
248820
- const worker = await resolveWorkerBuild(projectRoot, progress);
248821
- const assetsDir = worker ? worker.assetsDir : outputDir;
248822
- const assets = assetsDir ? await buildAssetManifest(assetsDir, getAppContext().id) : NO_ASSETS;
248823
- const completion = worker ? { modules: worker.modules } : { indexHtml: await readIndexHtml(assetsDir, assets) };
248601
+ // src/core/site/static-site.ts
248602
+ var STATIC_DEPLOYMENTS_ENV = "BASE44_STATIC_DEPLOYMENTS";
248603
+ function staticDeploymentsEnabled(env2 = process.env) {
248604
+ const value = env2[STATIC_DEPLOYMENTS_ENV];
248605
+ return value === "1" || value === "true";
248606
+ }
248607
+ async function deployStaticSite(options) {
248608
+ const { outputDir, gitHash, concurrency, progress } = options;
248609
+ const assets = await buildAssetManifest(outputDir, getAppContext().id);
248610
+ if (!assets.manifest["/index.html"]) {
248611
+ throw new InvalidInputError(`No index.html found in "${outputDir}" — a static site needs one at the output directory root.`);
248612
+ }
248824
248613
  const created = await createDeployment({
248825
248614
  git_hash: gitHash,
248826
- config: worker?.config,
248827
248615
  asset_manifest: assets.manifest
248828
248616
  });
248829
- const completionJwt = await uploadDeploymentAssets(created.assetUploads, assets, { concurrency, progress });
248830
- if ("modules" in completion) {
248831
- progress?.onWorker?.({ moduleCount: completion.modules.length });
248617
+ if (created.assetUploads && created.assetUploads.type !== "s3") {
248618
+ throw new ApiError(`The server answered a static-site deploy with the "${created.assetUploads.type}" upload target.`);
248619
+ }
248620
+ progress?.onAssets?.({
248621
+ totalAssets: Object.keys(assets.manifest).length,
248622
+ newAssets: created.assetUploads?.uploads.length ?? 0
248623
+ });
248624
+ if (created.assetUploads) {
248625
+ await uploadPresignedAssets(created.assetUploads.uploads, assets, {
248626
+ concurrency,
248627
+ onProgress: progress?.onAssetUpload
248628
+ });
248832
248629
  }
248833
- const finalized = await finalizeDeployment(created.deploymentId, created.sessionId, "modules" in completion ? { ...completion, completionJwt } : completion);
248630
+ const indexHtml = await readFile4(join16(outputDir, "index.html"));
248631
+ const finalized = await finalizeStaticDeployment(created.deploymentId, new Uint8Array(indexHtml), created.sessionId);
248834
248632
  return { deploymentId: finalized.deploymentId, gitHash };
248835
248633
  }
248836
- async function resolveWorkerBuild(projectRoot, progress) {
248837
- if (!await detectFullStackArtifact(projectRoot)) {
248838
- return null;
248634
+
248635
+ // src/core/site/wrangler-config.ts
248636
+ import { dirname as dirname10, join as join17, resolve as resolve3 } from "node:path";
248637
+ var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
248638
+ var RedirectConfigSchema = exports_external.looseObject({
248639
+ configPath: exports_external.string().min(1)
248640
+ });
248641
+ var WranglerConfigSchema = exports_external.looseObject({
248642
+ main: exports_external.string().min(1, "wrangler config is missing a 'main' entry module"),
248643
+ no_bundle: exports_external.boolean().optional(),
248644
+ rules: exports_external.array(exports_external.looseObject({ type: exports_external.string(), globs: exports_external.array(exports_external.string()) })).optional(),
248645
+ assets: exports_external.looseObject({
248646
+ directory: exports_external.string().optional(),
248647
+ html_handling: exports_external.string().optional(),
248648
+ not_found_handling: exports_external.string().optional(),
248649
+ run_worker_first: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional(),
248650
+ headers: exports_external.string().optional(),
248651
+ redirects: exports_external.string().optional()
248652
+ }).optional(),
248653
+ compatibility_date: exports_external.string().optional(),
248654
+ compatibility_flags: exports_external.array(exports_external.string()).optional(),
248655
+ vars: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
248656
+ upload_source_maps: exports_external.boolean().optional()
248657
+ });
248658
+ async function detectFullStackArtifact(projectRoot) {
248659
+ const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
248660
+ return await pathExists(redirectPath) ? redirectPath : null;
248661
+ }
248662
+ async function resolveWranglerConfig(projectRoot) {
248663
+ const redirectPath = await detectFullStackArtifact(projectRoot);
248664
+ if (!redirectPath) {
248665
+ throw new InvalidInputError("No full-stack build artifact found. Expected a .wrangler/deploy/config.json redirect file.", {
248666
+ hints: [{ message: "Run your framework's build command first" }]
248667
+ });
248668
+ }
248669
+ const configPath = await resolveRedirectedConfigPath(redirectPath);
248670
+ const parsed = await readJsonFile(configPath);
248671
+ const result = WranglerConfigSchema.safeParse(parsed);
248672
+ if (!result.success) {
248673
+ throw new ConfigInvalidError(`Invalid wrangler config: ${exports_external.prettifyError(result.error)}`, configPath);
248674
+ }
248675
+ const config9 = result.data;
248676
+ if (config9.no_bundle !== true) {
248677
+ throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 full-stack deploys only support pre-bundled Workers output (no_bundle: true).");
248678
+ }
248679
+ const configDir = dirname10(configPath);
248680
+ const assetsDirectory = config9.assets?.directory ? resolve3(configDir, config9.assets.directory) : null;
248681
+ return {
248682
+ configPath,
248683
+ configDir,
248684
+ main: config9.main,
248685
+ assetsDirectory,
248686
+ assetsConfig: config9.assets ? toResolvedAssetsConfig(config9.assets) : null,
248687
+ compatibilityDate: config9.compatibility_date ?? null,
248688
+ compatibilityFlags: config9.compatibility_flags ?? [],
248689
+ vars: config9.vars ?? {},
248690
+ rules: (config9.rules ?? []).map((rule) => ({
248691
+ type: rule.type,
248692
+ globs: rule.globs
248693
+ })),
248694
+ uploadSourceMaps: config9.upload_source_maps ?? false
248695
+ };
248696
+ }
248697
+ async function resolveRedirectedConfigPath(redirectPath) {
248698
+ const parsed = await readJsonFile(redirectPath);
248699
+ const result = RedirectConfigSchema.safeParse(parsed);
248700
+ if (!result.success) {
248701
+ throw new ConfigInvalidError(`Invalid deploy redirect file: ${exports_external.prettifyError(result.error)}`, redirectPath);
248839
248702
  }
248703
+ const configPath = resolve3(dirname10(redirectPath), result.data.configPath);
248704
+ if (!await pathExists(configPath)) {
248705
+ throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
248706
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
248707
+ });
248708
+ }
248709
+ return configPath;
248710
+ }
248711
+ function toResolvedAssetsConfig(assets) {
248712
+ return {
248713
+ htmlHandling: assets.html_handling,
248714
+ notFoundHandling: assets.not_found_handling,
248715
+ runWorkerFirst: assets.run_worker_first,
248716
+ headers: assets.headers,
248717
+ redirects: assets.redirects
248718
+ };
248719
+ }
248720
+
248721
+ // src/core/site/deploy-app.ts
248722
+ async function planAppDeploy(target) {
248723
+ if (await detectFullStackArtifact(target.root)) {
248724
+ return { kind: "full-stack" };
248725
+ }
248726
+ const outputDirectory = target.site?.outputDirectory;
248727
+ if (!outputDirectory) {
248728
+ return { kind: "none" };
248729
+ }
248730
+ const outputDir = resolve4(target.root, outputDirectory);
248731
+ return staticDeploymentsEnabled() ? { kind: "static-deployment", outputDir } : { kind: "static", outputDir };
248732
+ }
248733
+ // src/core/site/modules.ts
248734
+ import { stat as stat2 } from "node:fs/promises";
248735
+ import { relative as relative3, resolve as resolve5, sep } from "node:path";
248736
+ var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
248737
+ var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
248738
+ var RULE_TYPE_TO_MODULE_TYPE = {
248739
+ ESModule: "esm",
248740
+ CompiledWasm: "wasm",
248741
+ Text: "text",
248742
+ Data: "data"
248743
+ };
248744
+ function toPosix(path11) {
248745
+ return path11.split(sep).join("/");
248746
+ }
248747
+ async function collectModules(config9) {
248748
+ const entryPath = resolve5(config9.configDir, config9.main);
248749
+ if (!await pathExists(entryPath)) {
248750
+ throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config9.configPath})`, {
248751
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
248752
+ });
248753
+ }
248754
+ const modulesByName = new Map;
248755
+ const entryName = toPosix(relative3(config9.configDir, entryPath));
248756
+ modulesByName.set(entryName, {
248757
+ name: entryName,
248758
+ absolutePath: entryPath,
248759
+ size: 0,
248760
+ type: "esm"
248761
+ });
248762
+ const ignore = [...MODULE_IGNORE];
248763
+ if (config9.assetsDirectory?.startsWith(config9.configDir + sep)) {
248764
+ ignore.push(`${toPosix(relative3(config9.configDir, config9.assetsDirectory))}/**`);
248765
+ }
248766
+ for (const rule of config9.rules) {
248767
+ const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
248768
+ if (!type) {
248769
+ throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config9.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
248770
+ }
248771
+ const matches = await globby(rule.globs, {
248772
+ cwd: config9.configDir,
248773
+ onlyFiles: true,
248774
+ dot: true,
248775
+ ignore
248776
+ });
248777
+ for (const match of matches.sort()) {
248778
+ if (!modulesByName.has(match)) {
248779
+ modulesByName.set(match, {
248780
+ name: match,
248781
+ absolutePath: resolve5(config9.configDir, match),
248782
+ size: 0,
248783
+ type
248784
+ });
248785
+ }
248786
+ }
248787
+ }
248788
+ if (config9.uploadSourceMaps) {
248789
+ const maps = await globby("**/*.map", {
248790
+ cwd: config9.configDir,
248791
+ onlyFiles: true,
248792
+ dot: true,
248793
+ ignore
248794
+ });
248795
+ for (const map2 of maps.sort()) {
248796
+ addSourcemap(modulesByName, config9.configDir, map2);
248797
+ }
248798
+ } else {
248799
+ for (const name2 of [...modulesByName.keys()]) {
248800
+ const mapName = `${name2}.map`;
248801
+ if (await pathExists(resolve5(config9.configDir, mapName))) {
248802
+ addSourcemap(modulesByName, config9.configDir, mapName);
248803
+ }
248804
+ }
248805
+ }
248806
+ const modules = [...modulesByName.values()];
248807
+ let totalBytes = 0;
248808
+ for (const module of modules) {
248809
+ module.size = (await stat2(module.absolutePath)).size;
248810
+ totalBytes += module.size;
248811
+ }
248812
+ if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
248813
+ throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for Base44 full-stack deploys.`);
248814
+ }
248815
+ return modules;
248816
+ }
248817
+ function addSourcemap(modulesByName, configDir, name2) {
248818
+ if (modulesByName.has(name2))
248819
+ return;
248820
+ modulesByName.set(name2, {
248821
+ name: name2,
248822
+ absolutePath: resolve5(configDir, name2),
248823
+ size: 0,
248824
+ type: "sourcemap"
248825
+ });
248826
+ }
248827
+
248828
+ // src/core/site/full-stack.ts
248829
+ async function deployFullStack(options) {
248830
+ const { projectRoot, gitHash, concurrency, progress } = options;
248840
248831
  const config9 = await resolveWranglerConfig(projectRoot);
248841
248832
  if (!config9.compatibilityFlags.includes("nodejs_compat")) {
248842
248833
  progress?.onWarning?.("The wrangler config has no 'nodejs_compat' compatibility flag; Node.js built-ins will be unavailable at runtime. Enable it in your framework's Cloudflare adapter settings if your server code needs Node APIs.");
248843
248834
  }
248844
- if (Object.keys(config9.vars).length > 0) {
248835
+ if (config9.vars && Object.keys(config9.vars).length > 0) {
248845
248836
  progress?.onWarning?.("wrangler 'vars' are not supported and were ignored — a worker's environment comes from the app's secrets (base44 secrets set).");
248846
248837
  }
248847
- const assetsDir = config9.assetsDirectory && await pathExists(config9.assetsDirectory) ? config9.assetsDirectory : null;
248848
- return {
248838
+ const modules = await collectModules(config9);
248839
+ let assets = { manifest: {}, filesByHash: new Map };
248840
+ if (config9.assetsDirectory && await pathExists(config9.assetsDirectory)) {
248841
+ assets = await buildAssetManifest(config9.assetsDirectory, getAppContext().id);
248842
+ }
248843
+ const created = await createDeployment({
248844
+ git_hash: gitHash,
248849
248845
  config: {
248850
248846
  main: config9.main,
248851
248847
  compatibility_date: config9.compatibilityDate,
248852
248848
  compatibility_flags: config9.compatibilityFlags,
248853
248849
  assets: buildAssetsConfig(config9.assetsConfig, progress)
248854
248850
  },
248855
- modules: await collectModules(config9),
248856
- assetsDir
248857
- };
248858
- }
248859
- async function readIndexHtml(assetsDir, assets) {
248860
- if (!assetsDir || !assets.manifest["/index.html"]) {
248861
- throw new InvalidInputError(`No index.html found in "${assetsDir ?? "the site output directory"}" — a static site needs one at the output directory root.`);
248851
+ asset_manifest: assets.manifest
248852
+ });
248853
+ if (created.assetUploads && created.assetUploads.type !== "cf") {
248854
+ throw new ApiError(`The server answered a full-stack deploy with the "${created.assetUploads.type}" upload target.`);
248862
248855
  }
248863
- return new Uint8Array(await readFile4(join17(assetsDir, "index.html")));
248856
+ const totalAssets = Object.keys(assets.manifest).length;
248857
+ const newAssets = created.assetUploads ? new Set(created.assetUploads.buckets.flat()).size : 0;
248858
+ progress?.onAssets?.({ totalAssets, newAssets });
248859
+ const completionJwt = created.assetUploads ? await uploadAssetBuckets(created.assetUploads, assets.filesByHash, {
248860
+ concurrency,
248861
+ onProgress: progress?.onAssetUpload
248862
+ }) : null;
248863
+ progress?.onWorker?.({ moduleCount: modules.length });
248864
+ const finalized = await finalizeDeployment(created.deploymentId, completionJwt, modules, created.sessionId);
248865
+ return { deploymentId: finalized.deploymentId, gitHash };
248864
248866
  }
248865
248867
  function buildAssetsConfig(assetsConfig, progress) {
248866
248868
  if (!assetsConfig)
@@ -259357,19 +259359,22 @@ async function deployAction2(ctx, options) {
259357
259359
  throw new InvalidInputError("--yes is required in non-interactive mode");
259358
259360
  }
259359
259361
  const project2 = await readProjectSettings();
259360
- const outputDirectory = project2.site?.outputDirectory;
259361
- if ((await planAppDeploy(project2)).kind === "none") {
259362
+ const planned = await planAppDeploy(project2);
259363
+ if (planned.kind === "none") {
259362
259364
  throw new ConfigNotFoundError("No site configuration found.", {
259363
259365
  hints: [
259364
259366
  {
259365
259367
  message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
259368
+ },
259369
+ {
259370
+ message: "Full-stack apps ship from their build artifact — run your framework's build first"
259366
259371
  }
259367
259372
  ]
259368
259373
  });
259369
259374
  }
259370
259375
  if (!options.yes) {
259371
259376
  const shouldDeploy = await Re({
259372
- message: outputDirectory ? `Deploy site from ${outputDirectory}?` : "Deploy site?"
259377
+ message: planned.kind === "full-stack" ? "Deploy full-stack app?" : `Deploy site from ${project2.site?.outputDirectory}?`
259373
259378
  });
259374
259379
  if (Ct(shouldDeploy) || !shouldDeploy) {
259375
259380
  return { outroMessage: "Deployment cancelled" };
@@ -259378,47 +259383,42 @@ async function deployAction2(ctx, options) {
259378
259383
  await maybeBuildBeforeDeploy(ctx, project2, options.build);
259379
259384
  const plan = await planAppDeploy(project2);
259380
259385
  switch (plan.kind) {
259381
- case "deployment":
259386
+ case "full-stack":
259387
+ return await deployFullStackApp(ctx, project2.root, options);
259388
+ case "static-deployment":
259382
259389
  return await deployToDeploymentsApi(ctx, project2.root, plan.outputDir, options);
259383
- case "tarball":
259390
+ case "static":
259384
259391
  return await deployTarball(ctx, plan.outputDir);
259385
259392
  case "none":
259386
259393
  return { outroMessage: "Nothing to deploy" };
259387
259394
  }
259388
259395
  }
259389
- async function deployToDeploymentsApi(ctx, projectRoot, outputDir, options) {
259390
- const { runTask: runTask2, log } = ctx;
259396
+ async function deployFullStackApp(ctx, projectRoot, options) {
259391
259397
  const gitHash = await resolveGitHash(projectRoot, options.gitHash);
259392
- const progressLines = [];
259393
- const warnings = [];
259394
- const { deploymentId } = await runTask2("Deploying site...", async (updateMessage) => await deployToDeployments({
259398
+ const { deploymentId } = await runDeployTask(ctx, {
259399
+ start: "Deploying full-stack app...",
259400
+ success: theme.colors.base44Orange("Full-stack app deployed"),
259401
+ error: "Full-stack deploy failed"
259402
+ }, async (progress) => await deployFullStack({
259395
259403
  projectRoot,
259404
+ gitHash,
259405
+ concurrency: options.concurrency,
259406
+ progress
259407
+ }));
259408
+ return deploymentResult(ctx, deploymentId, gitHash);
259409
+ }
259410
+ async function deployToDeploymentsApi(ctx, projectRoot, outputDir, options) {
259411
+ const gitHash = await resolveGitHash(projectRoot, options.gitHash);
259412
+ const { deploymentId } = await runDeployTask(ctx, {
259413
+ start: "Deploying site...",
259414
+ success: "Site deployed",
259415
+ error: "Site deploy failed"
259416
+ }, async (progress) => await deployStaticSite({
259396
259417
  outputDir,
259397
259418
  gitHash,
259398
259419
  concurrency: options.concurrency,
259399
- progress: {
259400
- onWarning: (message) => {
259401
- warnings.push(message);
259402
- },
259403
- onAssets: ({ totalAssets, newAssets }) => {
259404
- const line = `Found ${totalAssets} static assets (${newAssets} new)`;
259405
- progressLines.push(line);
259406
- updateMessage(line);
259407
- },
259408
- onAssetUpload: ({ uploadedFiles, totalFiles }) => {
259409
- updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
259410
- },
259411
- onWorker: ({ moduleCount }) => {
259412
- updateMessage(`Deploying worker (${moduleCount} modules)…`);
259413
- }
259414
- }
259415
- }), { successMessage: "Site deployed", errorMessage: "Site deploy failed" });
259416
- for (const line of progressLines) {
259417
- log.message(theme.styles.dim(line));
259418
- }
259419
- for (const warning of warnings) {
259420
- log.warn(warning);
259421
- }
259420
+ progress
259421
+ }));
259422
259422
  return deploymentResult(ctx, deploymentId, gitHash);
259423
259423
  }
259424
259424
  async function deployTarball({ runTask: runTask2 }, outputDir) {
@@ -259428,6 +259428,33 @@ async function deployTarball({ runTask: runTask2 }, outputDir) {
259428
259428
  });
259429
259429
  return { outroMessage: `Visit your site at: ${appUrl}` };
259430
259430
  }
259431
+ async function runDeployTask({ runTask: runTask2, log }, labels, deploy5) {
259432
+ const progressLines = [];
259433
+ const warnings = [];
259434
+ const result = await runTask2(labels.start, async (updateMessage) => await deploy5({
259435
+ onWarning: (message) => {
259436
+ warnings.push(message);
259437
+ },
259438
+ onAssets: ({ totalAssets, newAssets }) => {
259439
+ const line = `Found ${totalAssets} static assets (${newAssets} new)`;
259440
+ progressLines.push(line);
259441
+ updateMessage(line);
259442
+ },
259443
+ onAssetUpload: ({ uploadedFiles, totalFiles }) => {
259444
+ updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
259445
+ },
259446
+ onWorker: ({ moduleCount }) => {
259447
+ updateMessage(`Deploying worker (${moduleCount} modules)…`);
259448
+ }
259449
+ }), { successMessage: labels.success, errorMessage: labels.error });
259450
+ for (const line of progressLines) {
259451
+ log.message(theme.styles.dim(line));
259452
+ }
259453
+ for (const warning of warnings) {
259454
+ log.warn(warning);
259455
+ }
259456
+ return result;
259457
+ }
259431
259458
  function deploymentResult({ jsonMode }, deploymentId, gitHash) {
259432
259459
  return {
259433
259460
  outroMessage: `Deployment ${deploymentId} (commit ${gitHash.slice(0, 12)})`,
@@ -259436,7 +259463,7 @@ function deploymentResult({ jsonMode }, deploymentId, gitHash) {
259436
259463
  };
259437
259464
  }
259438
259465
  function getSiteDeployCommand() {
259439
- return 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)").addOption(new Option("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash)).addOption(new Option("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency)).action(deployAction2);
259466
+ return new Base44Command("deploy").description("Deploy the built site to Base44 hosting (full-stack apps deploy their Workers build)").option("-y, --yes", "Skip confirmation prompt").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)").addOption(new Option("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash)).addOption(new Option("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency)).action(deployAction2);
259440
259467
  }
259441
259468
  function parseGitHash(value) {
259442
259469
  if (!isGitCommitHash(value)) {
@@ -268517,4 +268544,4 @@ export {
268517
268544
  runCLI
268518
268545
  };
268519
268546
 
268520
- //# debugId=9741A962D703AE2864756E2164756E21
268547
+ //# debugId=38E334A0515CDEB464756E2164756E21