@base44-preview/cli 0.1.15-pr.626.2df644b → 0.1.15-pr.626.454d562

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
@@ -239590,94 +239590,8 @@ async function createArchive(pathToArchive, targetArchivePath) {
239590
239590
  import { readFile as readFile3 } from "node:fs/promises";
239591
239591
  import { join as join18 } from "node:path";
239592
239592
 
239593
- // src/core/site/manifest.ts
239594
- import { createHash } from "node:crypto";
239595
- import { createReadStream } from "node:fs";
239596
- import { stat } from "node:fs/promises";
239597
- import { basename as basename5, extname, join as join16 } from "node:path";
239598
- var MAX_ASSET_COUNT = 1e5;
239599
- var ASSETS_IGNORE_FILE = ".assetsignore";
239600
- var ALWAYS_IGNORED = new Set([
239601
- ASSETS_IGNORE_FILE,
239602
- "wrangler.json",
239603
- ".dev.vars"
239604
- ]);
239605
- var MIME_TYPES = {
239606
- ".html": "text/html",
239607
- ".htm": "text/html",
239608
- ".css": "text/css",
239609
- ".js": "text/javascript",
239610
- ".mjs": "text/javascript",
239611
- ".json": "application/json",
239612
- ".map": "application/json",
239613
- ".txt": "text/plain",
239614
- ".xml": "application/xml",
239615
- ".svg": "image/svg+xml",
239616
- ".png": "image/png",
239617
- ".jpg": "image/jpeg",
239618
- ".jpeg": "image/jpeg",
239619
- ".gif": "image/gif",
239620
- ".webp": "image/webp",
239621
- ".avif": "image/avif",
239622
- ".ico": "image/x-icon",
239623
- ".woff": "font/woff",
239624
- ".woff2": "font/woff2",
239625
- ".ttf": "font/ttf",
239626
- ".otf": "font/otf",
239627
- ".eot": "application/vnd.ms-fontobject",
239628
- ".mp3": "audio/mpeg",
239629
- ".mp4": "video/mp4",
239630
- ".webm": "video/webm",
239631
- ".pdf": "application/pdf",
239632
- ".wasm": "application/wasm",
239633
- ".webmanifest": "application/manifest+json"
239634
- };
239635
- function getAssetContentType(filePath) {
239636
- return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
239637
- }
239638
- async function walkBuildOutput(outputDir) {
239639
- const found = await globby("**/*", {
239640
- cwd: outputDir,
239641
- dot: true,
239642
- onlyFiles: true,
239643
- followSymbolicLinks: false,
239644
- ignoreFiles: [ASSETS_IGNORE_FILE]
239645
- });
239646
- return found.filter((path) => !ALWAYS_IGNORED.has(basename5(path))).sort();
239647
- }
239648
- async function hashAssetFile(appId, absolutePath) {
239649
- const hash = createHash("sha256").update(Buffer.from(appId, "utf8"));
239650
- for await (const chunk of createReadStream(absolutePath)) {
239651
- hash.update(chunk);
239652
- }
239653
- return hash.digest("hex").slice(0, 32);
239654
- }
239655
- async function buildAssetManifest(assetsDir, appId) {
239656
- const manifest = {};
239657
- const filesByHash = new Map;
239658
- const relativeFilePaths = await walkBuildOutput(assetsDir);
239659
- if (relativeFilePaths.length > MAX_ASSET_COUNT) {
239660
- throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
239661
- }
239662
- for (const relativePath of relativeFilePaths) {
239663
- const absolutePath = join16(assetsDir, ...relativePath.split("/"));
239664
- const { size } = await stat(absolutePath);
239665
- const hash = await hashAssetFile(appId, absolutePath);
239666
- manifest[`/${relativePath}`] = { hash, size };
239667
- if (!filesByHash.has(hash)) {
239668
- filesByHash.set(hash, {
239669
- absolutePath,
239670
- hash,
239671
- size,
239672
- contentType: getAssetContentType(absolutePath)
239673
- });
239674
- }
239675
- }
239676
- return { manifest, filesByHash };
239677
- }
239678
-
239679
239593
  // src/core/site/modules.ts
239680
- import { stat as stat2 } from "node:fs/promises";
239594
+ import { stat } from "node:fs/promises";
239681
239595
  import { relative as relative5, resolve as resolve3, sep } from "node:path";
239682
239596
  var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
239683
239597
  var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
@@ -239752,7 +239666,7 @@ async function collectModules(config) {
239752
239666
  const modules = [...modulesByName.values()];
239753
239667
  let totalBytes = 0;
239754
239668
  for (const module of modules) {
239755
- module.size = (await stat2(module.absolutePath)).size;
239669
+ module.size = (await stat(module.absolutePath)).size;
239756
239670
  totalBytes += module.size;
239757
239671
  }
239758
239672
  if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
@@ -239771,8 +239685,104 @@ function addSourcemap(modulesByName, configDir, name) {
239771
239685
  });
239772
239686
  }
239773
239687
 
239774
- // src/core/site/upload.ts
239775
- import { readFile as readFile2 } from "node:fs/promises";
239688
+ // src/core/site/wrangler-config.ts
239689
+ import { dirname as dirname12, join as join16, resolve as resolve4 } from "node:path";
239690
+ var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
239691
+ var RedirectConfigSchema = looseObject({
239692
+ configPath: string2().min(1)
239693
+ });
239694
+ var WranglerConfigSchema = looseObject({
239695
+ main: string2().min(1, "wrangler config is missing a 'main' entry module"),
239696
+ no_bundle: boolean2().optional(),
239697
+ rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
239698
+ assets: looseObject({
239699
+ directory: string2().optional(),
239700
+ html_handling: string2().optional(),
239701
+ not_found_handling: string2().optional(),
239702
+ run_worker_first: union([boolean2(), array(string2())]).optional(),
239703
+ headers: string2().optional(),
239704
+ redirects: string2().optional()
239705
+ }).optional(),
239706
+ compatibility_date: string2().optional(),
239707
+ compatibility_flags: array(string2()).optional(),
239708
+ vars: record(string2(), unknown()).optional(),
239709
+ upload_source_maps: boolean2().optional()
239710
+ });
239711
+ async function detectFullStackArtifact(projectRoot) {
239712
+ const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
239713
+ return await pathExists(redirectPath) ? redirectPath : null;
239714
+ }
239715
+ async function resolveWranglerConfig(redirectPath) {
239716
+ const configPath = await resolveRedirectedConfigPath(redirectPath);
239717
+ const parsed = await readJsonFile(configPath);
239718
+ const result = WranglerConfigSchema.safeParse(parsed);
239719
+ if (!result.success) {
239720
+ throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
239721
+ }
239722
+ const config = result.data;
239723
+ if (config.no_bundle !== true) {
239724
+ throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
239725
+ }
239726
+ const configDir = dirname12(configPath);
239727
+ const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
239728
+ return {
239729
+ configPath,
239730
+ configDir,
239731
+ main: config.main,
239732
+ assetsDirectory,
239733
+ assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
239734
+ compatibilityDate: config.compatibility_date ?? null,
239735
+ compatibilityFlags: config.compatibility_flags ?? [],
239736
+ rules: (config.rules ?? []).map((rule) => ({
239737
+ type: rule.type,
239738
+ globs: rule.globs
239739
+ })),
239740
+ uploadSourceMaps: config.upload_source_maps ?? false
239741
+ };
239742
+ }
239743
+ async function resolveRedirectedConfigPath(redirectPath) {
239744
+ const parsed = await readJsonFile(redirectPath);
239745
+ const result = RedirectConfigSchema.safeParse(parsed);
239746
+ if (!result.success) {
239747
+ throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
239748
+ }
239749
+ const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
239750
+ if (!await pathExists(configPath)) {
239751
+ throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
239752
+ hints: [{ message: "Rebuild the project to regenerate the artifact" }]
239753
+ });
239754
+ }
239755
+ return configPath;
239756
+ }
239757
+ function toResolvedAssetsConfig(assets) {
239758
+ return {
239759
+ htmlHandling: assets.html_handling,
239760
+ notFoundHandling: assets.not_found_handling,
239761
+ runWorkerFirst: assets.run_worker_first,
239762
+ headers: assets.headers,
239763
+ redirects: assets.redirects
239764
+ };
239765
+ }
239766
+
239767
+ // src/core/site/full-stack.ts
239768
+ async function resolveFullStackBuild(projectRoot) {
239769
+ const redirectPath = await detectFullStackArtifact(projectRoot);
239770
+ if (!redirectPath) {
239771
+ return null;
239772
+ }
239773
+ const config = await resolveWranglerConfig(redirectPath);
239774
+ return {
239775
+ config,
239776
+ modules: await collectModules(config),
239777
+ assetsDir: config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null
239778
+ };
239779
+ }
239780
+
239781
+ // src/core/site/manifest.ts
239782
+ import { createHash } from "node:crypto";
239783
+ import { createReadStream } from "node:fs";
239784
+ import { stat as stat2 } from "node:fs/promises";
239785
+ import { basename as basename5, extname, join as join17 } from "node:path";
239776
239786
 
239777
239787
  // ../../node_modules/p-map/index.js
239778
239788
  async function pMap(iterable, mapper, {
@@ -239898,7 +239908,99 @@ async function pMap(iterable, mapper, {
239898
239908
  }
239899
239909
  var pMapSkip = Symbol("skip");
239900
239910
 
239911
+ // src/core/site/manifest.ts
239912
+ var MAX_ASSET_COUNT = 1e5;
239913
+ var ASSETS_IGNORE_FILE = ".assetsignore";
239914
+ var ALWAYS_IGNORED = new Set([
239915
+ ASSETS_IGNORE_FILE,
239916
+ "wrangler.json",
239917
+ ".dev.vars"
239918
+ ]);
239919
+ var MIME_TYPES = {
239920
+ ".html": "text/html",
239921
+ ".htm": "text/html",
239922
+ ".css": "text/css",
239923
+ ".js": "text/javascript",
239924
+ ".mjs": "text/javascript",
239925
+ ".json": "application/json",
239926
+ ".map": "application/json",
239927
+ ".txt": "text/plain",
239928
+ ".xml": "application/xml",
239929
+ ".svg": "image/svg+xml",
239930
+ ".png": "image/png",
239931
+ ".jpg": "image/jpeg",
239932
+ ".jpeg": "image/jpeg",
239933
+ ".gif": "image/gif",
239934
+ ".webp": "image/webp",
239935
+ ".avif": "image/avif",
239936
+ ".ico": "image/x-icon",
239937
+ ".woff": "font/woff",
239938
+ ".woff2": "font/woff2",
239939
+ ".ttf": "font/ttf",
239940
+ ".otf": "font/otf",
239941
+ ".eot": "application/vnd.ms-fontobject",
239942
+ ".mp3": "audio/mpeg",
239943
+ ".mp4": "video/mp4",
239944
+ ".webm": "video/webm",
239945
+ ".pdf": "application/pdf",
239946
+ ".wasm": "application/wasm",
239947
+ ".webmanifest": "application/manifest+json"
239948
+ };
239949
+ function getAssetContentType(filePath) {
239950
+ return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
239951
+ }
239952
+ async function walkBuildOutput(outputDir) {
239953
+ const found = await globby("**/*", {
239954
+ cwd: outputDir,
239955
+ dot: true,
239956
+ onlyFiles: true,
239957
+ followSymbolicLinks: false,
239958
+ ignoreFiles: [ASSETS_IGNORE_FILE]
239959
+ });
239960
+ return found.filter((path) => !ALWAYS_IGNORED.has(basename5(path))).sort();
239961
+ }
239962
+ var STAT_CONCURRENCY = 32;
239963
+ async function describeBuildOutput(outputDir) {
239964
+ const relativePaths = await walkBuildOutput(outputDir);
239965
+ return await pMap(relativePaths, async (path) => {
239966
+ const absolutePath = join17(outputDir, ...path.split("/"));
239967
+ return { path, absolutePath, size: (await stat2(absolutePath)).size };
239968
+ }, { concurrency: STAT_CONCURRENCY });
239969
+ }
239970
+ async function hashFileInto(hash, absolutePath) {
239971
+ for await (const chunk of createReadStream(absolutePath)) {
239972
+ hash.update(chunk);
239973
+ }
239974
+ return hash;
239975
+ }
239976
+ async function hashAssetFile(appId, absolutePath) {
239977
+ const hash = await hashFileInto(createHash("sha256").update(Buffer.from(appId, "utf8")), absolutePath);
239978
+ return hash.digest("hex").slice(0, 32);
239979
+ }
239980
+ async function buildAssetManifest(assetsDir, appId) {
239981
+ const manifest = {};
239982
+ const filesByHash = new Map;
239983
+ const files = await describeBuildOutput(assetsDir);
239984
+ if (files.length > MAX_ASSET_COUNT) {
239985
+ throw new InvalidInputError(`Too many static assets: found ${files.length}, the limit is ${MAX_ASSET_COUNT} files.`);
239986
+ }
239987
+ for (const { path: relativePath, absolutePath, size } of files) {
239988
+ const hash = await hashAssetFile(appId, absolutePath);
239989
+ manifest[`/${relativePath}`] = { hash, size };
239990
+ if (!filesByHash.has(hash)) {
239991
+ filesByHash.set(hash, {
239992
+ absolutePath,
239993
+ hash,
239994
+ size,
239995
+ contentType: getAssetContentType(absolutePath)
239996
+ });
239997
+ }
239998
+ }
239999
+ return { manifest, filesByHash };
240000
+ }
240001
+
239901
240002
  // src/core/site/upload.ts
240003
+ import { readFile as readFile2 } from "node:fs/promises";
239902
240004
  var DEFAULT_UPLOAD_CONCURRENCY = 3;
239903
240005
  var MAX_UPLOAD_CONCURRENCY = 50;
239904
240006
  var MAX_UPLOAD_ATTEMPTS = 3;
@@ -239997,7 +240099,10 @@ async function uploadPresignedAsset(upload, assets) {
239997
240099
  if (!file) {
239998
240100
  throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
239999
240101
  }
240000
- const content = await readFile2(file.absolutePath);
240102
+ await putPresigned(upload, file.absolutePath);
240103
+ }
240104
+ async function putPresigned(upload, absolutePath) {
240105
+ const content = await readFile2(absolutePath);
240001
240106
  try {
240002
240107
  await distribution_default.put(upload.url, {
240003
240108
  body: new Uint8Array(content),
@@ -240013,85 +240118,6 @@ async function uploadPresignedAsset(upload, assets) {
240013
240118
  }
240014
240119
  }
240015
240120
 
240016
- // src/core/site/wrangler-config.ts
240017
- import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
240018
- var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
240019
- var RedirectConfigSchema = looseObject({
240020
- configPath: string2().min(1)
240021
- });
240022
- var WranglerConfigSchema = looseObject({
240023
- main: string2().min(1, "wrangler config is missing a 'main' entry module"),
240024
- no_bundle: boolean2().optional(),
240025
- rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
240026
- assets: looseObject({
240027
- directory: string2().optional(),
240028
- html_handling: string2().optional(),
240029
- not_found_handling: string2().optional(),
240030
- run_worker_first: union([boolean2(), array(string2())]).optional(),
240031
- headers: string2().optional(),
240032
- redirects: string2().optional()
240033
- }).optional(),
240034
- compatibility_date: string2().optional(),
240035
- compatibility_flags: array(string2()).optional(),
240036
- vars: record(string2(), unknown()).optional(),
240037
- upload_source_maps: boolean2().optional()
240038
- });
240039
- async function detectFullStackArtifact(projectRoot) {
240040
- const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
240041
- return await pathExists(redirectPath) ? redirectPath : null;
240042
- }
240043
- async function resolveWranglerConfig(redirectPath) {
240044
- const configPath = await resolveRedirectedConfigPath(redirectPath);
240045
- const parsed = await readJsonFile(configPath);
240046
- const result = WranglerConfigSchema.safeParse(parsed);
240047
- if (!result.success) {
240048
- throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
240049
- }
240050
- const config = result.data;
240051
- if (config.no_bundle !== true) {
240052
- throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
240053
- }
240054
- const configDir = dirname12(configPath);
240055
- const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
240056
- return {
240057
- configPath,
240058
- configDir,
240059
- main: config.main,
240060
- assetsDirectory,
240061
- assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
240062
- compatibilityDate: config.compatibility_date ?? null,
240063
- compatibilityFlags: config.compatibility_flags ?? [],
240064
- rules: (config.rules ?? []).map((rule) => ({
240065
- type: rule.type,
240066
- globs: rule.globs
240067
- })),
240068
- uploadSourceMaps: config.upload_source_maps ?? false
240069
- };
240070
- }
240071
- async function resolveRedirectedConfigPath(redirectPath) {
240072
- const parsed = await readJsonFile(redirectPath);
240073
- const result = RedirectConfigSchema.safeParse(parsed);
240074
- if (!result.success) {
240075
- throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
240076
- }
240077
- const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
240078
- if (!await pathExists(configPath)) {
240079
- throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
240080
- hints: [{ message: "Rebuild the project to regenerate the artifact" }]
240081
- });
240082
- }
240083
- return configPath;
240084
- }
240085
- function toResolvedAssetsConfig(assets) {
240086
- return {
240087
- htmlHandling: assets.html_handling,
240088
- notFoundHandling: assets.not_found_handling,
240089
- runWorkerFirst: assets.run_worker_first,
240090
- headers: assets.headers,
240091
- redirects: assets.redirects
240092
- };
240093
- }
240094
-
240095
240121
  // src/core/site/deployment.ts
240096
240122
  var NO_ASSETS = { manifest: {}, filesByHash: new Map };
240097
240123
  var DEPLOYMENTS_API_ENV = "BASE44_DEPLOYMENTS_API";
@@ -240118,12 +240144,11 @@ async function deployToDeployments(options) {
240118
240144
  return { deploymentId: finalized.deploymentId, gitHash };
240119
240145
  }
240120
240146
  async function resolveWorkerBuild(projectRoot, progress) {
240121
- const redirectPath = await detectFullStackArtifact(projectRoot);
240122
- if (!redirectPath) {
240147
+ const built = await resolveFullStackBuild(projectRoot);
240148
+ if (!built) {
240123
240149
  return null;
240124
240150
  }
240125
- const config = await resolveWranglerConfig(redirectPath);
240126
- const assetsDir = config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null;
240151
+ const { config, modules, assetsDir } = built;
240127
240152
  return {
240128
240153
  config: {
240129
240154
  main: config.main,
@@ -240131,7 +240156,7 @@ async function resolveWorkerBuild(projectRoot, progress) {
240131
240156
  compatibility_flags: config.compatibilityFlags,
240132
240157
  assets: buildAssetsConfig(config.assetsConfig, progress)
240133
240158
  },
240134
- modules: await collectModules(config),
240159
+ modules,
240135
240160
  assetsDir
240136
240161
  };
240137
240162
  }
@@ -247051,6 +247076,12 @@ async function ensureAppContext(ctx, options = {}) {
247051
247076
  ctx.app = appContext;
247052
247077
  ctx.errorReporter.setContext({ appId: appContext.id });
247053
247078
  }
247079
+ function requireApp(ctx) {
247080
+ if (!ctx.app) {
247081
+ throw new InternalError("This command read an app context it never resolved — it is declared with requireAppContext: false.");
247082
+ }
247083
+ return ctx.app;
247084
+ }
247054
247085
 
247055
247086
  // src/cli/utils/version-check.ts
247056
247087
  async function checkForUpgrade() {
@@ -247262,6 +247293,9 @@ var EnvironmentResponseSchema = object({
247262
247293
  // src/core/version/api.ts
247263
247294
  var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
247264
247295
  var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
247296
+ function declaredFile({ path, size, digest }) {
247297
+ return { path, size, digest };
247298
+ }
247265
247299
  async function post(path, json, doing) {
247266
247300
  try {
247267
247301
  return await getAppClient().post(path, { json, timeout: 180000 });
@@ -247285,36 +247319,41 @@ function parse10(schema, body, what) {
247285
247319
  }
247286
247320
  async function createVersion(artifacts, options = {}) {
247287
247321
  const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
247288
- static_bundle: artifacts.files.map(({ path, size, digest }) => ({
247289
- path,
247290
- size,
247291
- digest
247292
- })),
247322
+ static_bundle: artifacts.files.map(declaredFile),
247323
+ ...artifacts.siteWorker ? {
247324
+ site_worker: {
247325
+ main: artifacts.siteWorker.main,
247326
+ modules: artifacts.siteWorker.modules.map(declaredFile),
247327
+ assets: artifacts.siteWorker.assets.map(declaredFile),
247328
+ compatibility_date: artifacts.siteWorker.compatibilityDate,
247329
+ compatibility_flags: artifacts.siteWorker.compatibilityFlags
247330
+ }
247331
+ } : {},
247293
247332
  entities: artifacts.entities,
247294
247333
  agents: artifacts.agents,
247295
247334
  source_commit: options.sourceCommit
247296
247335
  }, "declaring a version")).json(), "declare");
247336
+ const declaredFiles = [
247337
+ ...artifacts.files,
247338
+ ...artifacts.siteWorker?.modules ?? [],
247339
+ ...artifacts.siteWorker?.assets ?? []
247340
+ ];
247297
247341
  options.progress?.onDeclared?.({
247298
- fileCount: artifacts.files.length,
247342
+ fileCount: declaredFiles.length,
247299
247343
  owedFiles: declared.uploads.length
247300
247344
  });
247301
- await uploadPresignedAssets(declared.uploads, {
247302
- manifest: Object.fromEntries(artifacts.files.map((file) => [
247303
- file.path,
247304
- { hash: file.digest, size: file.size }
247305
- ])),
247306
- filesByHash: new Map(artifacts.files.map((file) => [
247307
- file.digest,
247308
- {
247309
- absolutePath: file.absolutePath,
247310
- hash: file.digest,
247311
- size: file.size
247312
- }
247313
- ]))
247314
- }, {
247315
- concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY,
247316
- onProgress: options.progress?.onUpload
247317
- });
247345
+ if (declared.uploads.length !== declaredFiles.length) {
247346
+ throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
247347
+ }
247348
+ let uploadedFiles = 0;
247349
+ await pMap(declared.uploads, async (upload, index) => {
247350
+ await putPresigned(upload, declaredFiles[index].absolutePath);
247351
+ uploadedFiles++;
247352
+ options.progress?.onUpload?.({
247353
+ uploadedFiles,
247354
+ totalFiles: declared.uploads.length
247355
+ });
247356
+ }, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
247318
247357
  return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
247319
247358
  }
247320
247359
  async function setEnvironmentVersion(environment, versionId, options = {}) {
@@ -249722,44 +249761,54 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
249722
249761
  }
249723
249762
  // src/core/version/artifacts.ts
249724
249763
  import { createHash as createHash2 } from "node:crypto";
249725
- import { createReadStream as createReadStream3 } from "node:fs";
249726
- import { stat as stat3 } from "node:fs/promises";
249727
- import { join as join27 } from "node:path";
249764
+ import { join as join27, resolve as resolve10 } from "node:path";
249728
249765
  var MAX_FILE_COUNT = 50000;
249729
249766
  var HASH_CONCURRENCY = 32;
249730
249767
  var ENTRY2 = "index.html";
249731
249768
  async function digestFile(absolutePath) {
249732
- const hash = createHash2("sha256");
249733
- for await (const chunk of createReadStream3(absolutePath)) {
249734
- hash.update(chunk);
249735
- }
249769
+ const hash = await hashFileInto(createHash2("sha256"), absolutePath);
249736
249770
  return `sha256:${hash.digest("hex")}`;
249737
249771
  }
249738
- async function collectBuildOutput(outputDir) {
249739
- const relativePaths = await walkBuildOutput(outputDir);
249740
- if (relativePaths.length === 0) {
249772
+ async function collectBuildOutput(outputDir, options = {}) {
249773
+ const found = await describeBuildOutput(outputDir);
249774
+ if (found.length === 0) {
249741
249775
  throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
249742
249776
  hints: [
249743
249777
  { message: "Run 'base44 build' first", command: "base44 build" }
249744
249778
  ]
249745
249779
  });
249746
249780
  }
249747
- if (relativePaths.length > MAX_FILE_COUNT) {
249748
- throw new InvalidInputError(`Too many files: found ${relativePaths.length}, the limit is ${MAX_FILE_COUNT}.`);
249781
+ if (found.length > MAX_FILE_COUNT) {
249782
+ throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
249749
249783
  }
249750
- if (!relativePaths.includes(ENTRY2)) {
249784
+ if (options.requireEntry !== false && !found.some((f) => f.path === ENTRY2)) {
249751
249785
  throw new InvalidInputError(`${outputDir} has no ${ENTRY2}, so nothing could enter the site.`);
249752
249786
  }
249753
- return await pMap(relativePaths, async (path) => {
249754
- const absolutePath = join27(outputDir, ...path.split("/"));
249755
- const { size } = await stat3(absolutePath);
249756
- return {
249757
- path,
249787
+ return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
249788
+ }
249789
+ async function collectSiteWorker(projectRoot) {
249790
+ const built = await resolveFullStackBuild(projectRoot);
249791
+ if (!built) {
249792
+ return null;
249793
+ }
249794
+ const { config, modules, assetsDir } = built;
249795
+ const entry = resolve10(config.configDir, config.main);
249796
+ const main = modules.find((m) => m.absolutePath === entry)?.name;
249797
+ if (!main) {
249798
+ throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
249799
+ }
249800
+ return {
249801
+ main,
249802
+ modules: await pMap(modules, async ({ name, absolutePath, size }) => ({
249803
+ path: name,
249758
249804
  absolutePath,
249759
249805
  size,
249760
249806
  digest: await digestFile(absolutePath)
249761
- };
249762
- }, { concurrency: HASH_CONCURRENCY });
249807
+ }), { concurrency: HASH_CONCURRENCY }),
249808
+ assets: assetsDir ? await collectBuildOutput(assetsDir, { requireEntry: false }) : [],
249809
+ compatibilityDate: config.compatibilityDate,
249810
+ compatibilityFlags: config.compatibilityFlags
249811
+ };
249763
249812
  }
249764
249813
  async function readRawResources(dir) {
249765
249814
  if (!await pathExists(dir)) {
@@ -249791,7 +249840,7 @@ function versionsApiEnabled(env = process.env) {
249791
249840
  return value === "1" || value === "true";
249792
249841
  }
249793
249842
  // src/core/version/project.ts
249794
- import { dirname as dirname21, join as join28, resolve as resolve10 } from "node:path";
249843
+ import { dirname as dirname21, join as join28, resolve as resolve11 } from "node:path";
249795
249844
  var DEFAULT_BUILD_COMMAND = "npm run build";
249796
249845
  var DEFAULT_OUTPUT_DIRECTORY = "dist";
249797
249846
  async function resolvePublishTarget(projectRoot, overrides = {}) {
@@ -249808,7 +249857,7 @@ async function resolvePublishTarget(projectRoot, overrides = {}) {
249808
249857
  }
249809
249858
  function outputDirectory(project, root, override) {
249810
249859
  const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
249811
- return configured ? resolve10(root, configured) : null;
249860
+ return configured ? resolve11(root, configured) : null;
249812
249861
  }
249813
249862
  function requireOutputDir(target) {
249814
249863
  if (target.outputDir === null) {
@@ -249835,15 +249884,15 @@ async function readSettingsIfPresent(projectRoot) {
249835
249884
  }
249836
249885
  // src/cli/commands/project/build.ts
249837
249886
  async function buildAction(ctx) {
249838
- const { app } = ctx;
249839
- const target = await resolvePublishTarget(app?.projectRoot);
249887
+ const app = requireApp(ctx);
249888
+ const target = await resolvePublishTarget(app.projectRoot);
249840
249889
  await runSiteBuild(ctx, {
249841
249890
  root: target.root,
249842
249891
  buildCommand: target.buildCommand,
249843
- appId: app?.id ?? ""
249892
+ appId: app.id
249844
249893
  });
249845
249894
  return {
249846
- outroMessage: `Site built with app id ${theme.styles.bold(app?.id ?? "")}`
249895
+ outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
249847
249896
  };
249848
249897
  }
249849
249898
  function getBuildCommand() {
@@ -249851,7 +249900,7 @@ function getBuildCommand() {
249851
249900
  }
249852
249901
 
249853
249902
  // src/cli/commands/project/create.ts
249854
- import { basename as basename6, resolve as resolve11 } from "node:path";
249903
+ import { basename as basename6, resolve as resolve12 } from "node:path";
249855
249904
  var import_kebabCase = __toESM(require_kebabCase(), 1);
249856
249905
 
249857
249906
  // src/cli/commands/project/scaffold-shared.ts
@@ -250047,7 +250096,7 @@ async function createInteractive(options, ctx) {
250047
250096
  }, ctx);
250048
250097
  }
250049
250098
  async function createNonInteractive(options, ctx) {
250050
- ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
250099
+ ctx.log.info(`Creating a new project at ${resolve12(options.path)}`);
250051
250100
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
250052
250101
  return await executeCreate({
250053
250102
  template,
@@ -250071,7 +250120,7 @@ async function executeCreate({
250071
250120
  }, ctx) {
250072
250121
  const { log, runTask } = ctx;
250073
250122
  const name = rawName.trim();
250074
- const resolvedPath = resolve11(projectPath);
250123
+ const resolvedPath = resolve12(projectPath);
250075
250124
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
250076
250125
  const { projectId } = await runTask("Setting up your project...", async () => {
250077
250126
  return await createProjectFiles({
@@ -250712,7 +250761,7 @@ function getLogsCommand() {
250712
250761
  }
250713
250762
 
250714
250763
  // src/cli/commands/project/scaffold.ts
250715
- import { basename as basename7, resolve as resolve12 } from "node:path";
250764
+ import { basename as basename7, resolve as resolve13 } from "node:path";
250716
250765
  function resolveAppId(options) {
250717
250766
  const appId = options.appId;
250718
250767
  if (!appId) {
@@ -250728,7 +250777,7 @@ function resolveAppId(options) {
250728
250777
  async function scaffoldAction(ctx, name, options, command) {
250729
250778
  const { log, runTask } = ctx;
250730
250779
  const appId = resolveAppId(command.optsWithGlobals());
250731
- const resolvedPath = resolve12("./");
250780
+ const resolvedPath = resolve13("./");
250732
250781
  const projectName = (name ?? basename7(resolvedPath)).trim();
250733
250782
  const template = await getTemplateById("backend-only");
250734
250783
  log.info(`Scaffolding project at ${resolvedPath}`);
@@ -250803,23 +250852,28 @@ function concurrencyOption() {
250803
250852
 
250804
250853
  // src/cli/commands/publish.ts
250805
250854
  async function publishAction(ctx, options) {
250806
- const { runTask, log, jsonMode, app } = ctx;
250807
- const target = await resolvePublishTarget(app?.projectRoot, {
250855
+ const { runTask, log, jsonMode } = ctx;
250856
+ const app = requireApp(ctx);
250857
+ const target = await resolvePublishTarget(app.projectRoot, {
250808
250858
  outputDir: options.outputDir
250809
250859
  });
250810
250860
  if (options.build !== false) {
250811
250861
  await tagStep("build", () => runSiteBuild(ctx, {
250812
250862
  root: target.root,
250813
250863
  buildCommand: target.buildCommand,
250814
- appId: app?.id ?? ""
250864
+ appId: app.id
250815
250865
  }));
250816
250866
  }
250817
250867
  const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
250818
250868
  const result = await runTask("Publishing...", async (updateMessage) => {
250819
- const artifacts = await tagStep("create_version", async () => ({
250820
- files: await collectBuildOutput(requireOutputDir(target)),
250821
- ...await collectResources(target.configDir, target)
250822
- }));
250869
+ const artifacts = await tagStep("create_version", async () => {
250870
+ const siteWorker = await collectSiteWorker(target.root);
250871
+ return {
250872
+ files: siteWorker ? [] : await collectBuildOutput(requireOutputDir(target)),
250873
+ ...siteWorker ? { siteWorker } : {},
250874
+ ...await collectResources(target.configDir, target)
250875
+ };
250876
+ });
250823
250877
  return await publishVersion(artifacts, {
250824
250878
  sourceCommit: gitHash,
250825
250879
  target: options.target,
@@ -251212,7 +251266,7 @@ function getSecretsListCommand() {
251212
251266
  }
251213
251267
 
251214
251268
  // src/cli/commands/secrets/set.ts
251215
- import { resolve as resolve13 } from "node:path";
251269
+ import { resolve as resolve14 } from "node:path";
251216
251270
  function parseEntries(entries) {
251217
251271
  const secrets = {};
251218
251272
  for (const entry of entries) {
@@ -251243,7 +251297,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
251243
251297
  validateInput(entries, options);
251244
251298
  let secrets;
251245
251299
  if (options.envFile) {
251246
- secrets = await parseEnvFile(resolve13(options.envFile));
251300
+ secrets = await parseEnvFile(resolve14(options.envFile));
251247
251301
  if (Object.keys(secrets).length === 0) {
251248
251302
  throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
251249
251303
  }
@@ -251272,7 +251326,7 @@ function getSecretsCommand() {
251272
251326
  }
251273
251327
 
251274
251328
  // src/cli/commands/site/deploy.ts
251275
- import { resolve as resolve14 } from "node:path";
251329
+ import { resolve as resolve15 } from "node:path";
251276
251330
  async function deployAction2(ctx, options) {
251277
251331
  const { isNonInteractive } = ctx;
251278
251332
  if (isNonInteractive && !options.yes) {
@@ -251350,7 +251404,7 @@ async function deployTarball({ runTask }, project) {
251350
251404
  }
251351
251405
  function siteOutputDir(project) {
251352
251406
  const outputDirectory = project.site?.outputDirectory;
251353
- return outputDirectory ? resolve14(project.root, outputDirectory) : null;
251407
+ return outputDirectory ? resolve15(project.root, outputDirectory) : null;
251354
251408
  }
251355
251409
  function getSiteDeployCommand() {
251356
251410
  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)");
@@ -253912,11 +253966,11 @@ import { relative as relative9 } from "node:path";
253912
253966
  // ../../node_modules/chokidar/index.js
253913
253967
  import { EventEmitter as EventEmitter3 } from "node:events";
253914
253968
  import { stat as statcb, Stats } from "node:fs";
253915
- import { readdir as readdir3, stat as stat7 } from "node:fs/promises";
253969
+ import { readdir as readdir3, stat as stat6 } from "node:fs/promises";
253916
253970
  import * as sp3 from "node:path";
253917
253971
 
253918
253972
  // ../../node_modules/readdirp/index.js
253919
- import { lstat as lstat2, readdir as readdir2, realpath, stat as stat5 } from "node:fs/promises";
253973
+ import { lstat as lstat2, readdir as readdir2, realpath, stat as stat4 } from "node:fs/promises";
253920
253974
  import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
253921
253975
  import { Readable as Readable6 } from "node:stream";
253922
253976
  var EntryTypes = {
@@ -253998,7 +254052,7 @@ class ReaddirpStream extends Readable6 {
253998
254052
  const { root, type } = opts;
253999
254053
  this._fileFilter = normalizeFilter(opts.fileFilter);
254000
254054
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
254001
- const statMethod = opts.lstat ? lstat2 : stat5;
254055
+ const statMethod = opts.lstat ? lstat2 : stat4;
254002
254056
  if (wantBigintFsStats) {
254003
254057
  this._stat = (path) => statMethod(path, { bigint: true });
254004
254058
  } else {
@@ -254151,7 +254205,7 @@ function readdirp(root, options = {}) {
254151
254205
 
254152
254206
  // ../../node_modules/chokidar/handler.js
254153
254207
  import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
254154
- import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat6 } from "node:fs/promises";
254208
+ import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat5 } from "node:fs/promises";
254155
254209
  import { type as osType } from "node:os";
254156
254210
  import * as sp2 from "node:path";
254157
254211
  var STR_DATA = "data";
@@ -254177,7 +254231,7 @@ var EVENTS = {
254177
254231
  };
254178
254232
  var EV = EVENTS;
254179
254233
  var THROTTLE_MODE_WATCH = "watch";
254180
- var statMethods = { lstat: lstat3, stat: stat6 };
254234
+ var statMethods = { lstat: lstat3, stat: stat5 };
254181
254235
  var KEY_LISTENERS = "listeners";
254182
254236
  var KEY_ERR = "errHandlers";
254183
254237
  var KEY_RAW = "rawEmitters";
@@ -254648,7 +254702,7 @@ class NodeFsHandler {
254648
254702
  return;
254649
254703
  if (!newStats || newStats.mtimeMs === 0) {
254650
254704
  try {
254651
- const newStats = await stat6(file);
254705
+ const newStats = await stat5(file);
254652
254706
  if (this.fsw.closed)
254653
254707
  return;
254654
254708
  const at = newStats.atimeMs;
@@ -255320,7 +255374,7 @@ class FSWatcher extends EventEmitter3 {
255320
255374
  const fullPath = opts.cwd ? sp3.join(opts.cwd, path) : path;
255321
255375
  let stats;
255322
255376
  try {
255323
- stats = await stat7(fullPath);
255377
+ stats = await stat6(fullPath);
255324
255378
  } catch (err) {}
255325
255379
  if (!stats || this.closed)
255326
255380
  return;
@@ -256102,7 +256156,7 @@ Examples:
256102
256156
  }
256103
256157
 
256104
256158
  // src/cli/commands/project/eject.ts
256105
- import { resolve as resolve18 } from "node:path";
256159
+ import { resolve as resolve19 } from "node:path";
256106
256160
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
256107
256161
  async function eject(ctx, options, command) {
256108
256162
  const { log, runTask, isNonInteractive } = ctx;
@@ -256166,7 +256220,7 @@ async function eject(ctx, options, command) {
256166
256220
  Ne("Operation cancelled.");
256167
256221
  throw new CLIExitError(0);
256168
256222
  }
256169
- const resolvedPath = resolve18(selectedPath);
256223
+ const resolvedPath = resolve19(selectedPath);
256170
256224
  await runTask("Downloading your project's code...", async (updateMessage) => {
256171
256225
  await createProjectFilesForExistingProject({
256172
256226
  projectId,
@@ -258310,7 +258364,7 @@ class ReduceableCache {
258310
258364
  }
258311
258365
  }
258312
258366
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
258313
- import { createReadStream as createReadStream4 } from "node:fs";
258367
+ import { createReadStream as createReadStream3 } from "node:fs";
258314
258368
  import { createInterface as createInterface2 } from "node:readline";
258315
258369
  var LRU_FILE_CONTENTS_CACHE = new ReduceableCache(25);
258316
258370
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new ReduceableCache(20);
@@ -258354,7 +258408,7 @@ async function addSourceContext(frames) {
258354
258408
  }
258355
258409
  function getContextLinesFromFile(path, ranges, output) {
258356
258410
  return new Promise((resolve) => {
258357
- const stream = createReadStream4(path);
258411
+ const stream = createReadStream3(path);
258358
258412
  const lineReaded = createInterface2({
258359
258413
  input: stream
258360
258414
  });
@@ -260305,4 +260359,4 @@ export {
260305
260359
  runCLI
260306
260360
  };
260307
260361
 
260308
- //# debugId=B07922109E14BECF64756E2164756E21
260362
+ //# debugId=A3CC3878ECA39CF664756E2164756E21