@base44-preview/cli 0.1.25-pr.647.fff4a17 → 0.1.25-pr.649.02c0574

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
@@ -236708,8 +236708,74 @@ async function getSiteUrl() {
236708
236708
  return result.data.url;
236709
236709
  }
236710
236710
  // src/core/project/config.ts
236711
+ import { existsSync } from "node:fs";
236711
236712
  import { dirname as dirname10, join as join12 } from "node:path";
236712
236713
 
236714
+ // src/core/project/fallback.ts
236715
+ var DEFAULT_SITE = Object.freeze({
236716
+ installCommand: "npm install",
236717
+ buildCommand: "npm run build",
236718
+ serveCommand: "npm run dev",
236719
+ outputDirectory: "./dist"
236720
+ });
236721
+ var PLACEHOLDER_APP_NAME = "base44-app";
236722
+ var DEFAULTABLE_FIELDS = new Set(["name", "description", "site"]);
236723
+ var warningHandler = () => {};
236724
+ var warned = new Set;
236725
+ function setConfigWarningHandler(handler) {
236726
+ warningHandler = handler;
236727
+ }
236728
+ function warnConfigFallback(message) {
236729
+ if (warned.has(message)) {
236730
+ return;
236731
+ }
236732
+ warned.add(message);
236733
+ warningHandler(message);
236734
+ }
236735
+ function defaultProjectConfig() {
236736
+ return ProjectConfigSchema.parse({
236737
+ name: PLACEHOLDER_APP_NAME,
236738
+ site: DEFAULT_SITE
236739
+ });
236740
+ }
236741
+ function onlyDefaultableFieldsInvalid(error) {
236742
+ return error.issues.every((issue) => issue.path.length > 0 && DEFAULTABLE_FIELDS.has(String(issue.path[0])));
236743
+ }
236744
+ function salvageProjectConfig(raw, error) {
236745
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
236746
+ return defaultProjectConfig();
236747
+ }
236748
+ const fixed = { ...raw };
236749
+ for (const issue of error.issues) {
236750
+ if (issue.path.length === 0) {
236751
+ return defaultProjectConfig();
236752
+ }
236753
+ const [key, field] = issue.path.map(String);
236754
+ if (key === "name") {
236755
+ fixed.name = PLACEHOLDER_APP_NAME;
236756
+ } else if (key === "site") {
236757
+ fixed.site = field !== undefined && isPlainObject2(fixed.site) ? withoutKey(fixed.site, field) : DEFAULT_SITE;
236758
+ } else {
236759
+ fixed[key] = undefined;
236760
+ }
236761
+ }
236762
+ const result = ProjectConfigSchema.safeParse(fixed);
236763
+ return result.success ? result.data : defaultProjectConfig();
236764
+ }
236765
+ function siteOrDefault(project) {
236766
+ if (project.site) {
236767
+ return project.site;
236768
+ }
236769
+ warnConfigFallback(`${project.configPath} has no 'site' block; using the default site commands.`);
236770
+ return DEFAULT_SITE;
236771
+ }
236772
+ function withoutKey(record, key) {
236773
+ return Object.fromEntries(Object.entries(record).filter(([k]) => k !== key));
236774
+ }
236775
+ function isPlainObject2(value) {
236776
+ return typeof value === "object" && value !== null && !Array.isArray(value);
236777
+ }
236778
+
236713
236779
  // src/core/project/plugins.ts
236714
236780
  import { createRequire as createRequire2 } from "node:module";
236715
236781
  import { dirname as dirname5, isAbsolute as isAbsolute2, join as join4, resolve } from "node:path";
@@ -238340,8 +238406,8 @@ var FieldRLSSchema = looseObject({
238340
238406
  update: RLSRuleSchema.optional(),
238341
238407
  delete: RLSRuleSchema.optional()
238342
238408
  });
238343
- var PropertyTypeSchema = union([string2(), array(string2())]);
238344
- var propertyFields = {
238409
+ var PropertyDefinitionSchema = looseObject({
238410
+ type: union([string2(), array(string2())]).optional(),
238345
238411
  title: string2().optional(),
238346
238412
  description: string2().optional(),
238347
238413
  minLength: number2().int().min(0).optional(),
@@ -238355,34 +238421,21 @@ var propertyFields = {
238355
238421
  default: unknown().optional(),
238356
238422
  $ref: string2().optional(),
238357
238423
  rls: FieldRLSSchema.optional(),
238358
- required: array(string2()).optional()
238359
- };
238360
- var NestedPropertyDefinitionSchema = looseObject({
238361
- ...propertyFields,
238362
- type: PropertyTypeSchema.optional(),
238363
- get items() {
238364
- return NestedPropertyDefinitionSchema.optional();
238365
- },
238366
- get properties() {
238367
- return record(string2(), NestedPropertyDefinitionSchema).optional();
238368
- }
238369
- });
238370
- var PropertyDefinitionSchema = looseObject({
238371
- ...propertyFields,
238372
- type: PropertyTypeSchema,
238424
+ required: array(string2()).optional(),
238373
238425
  get items() {
238374
- return NestedPropertyDefinitionSchema.optional();
238426
+ return PropertyDefinitionSchema.optional();
238375
238427
  },
238376
238428
  get properties() {
238377
- return record(string2(), NestedPropertyDefinitionSchema).optional();
238429
+ return record(string2(), PropertyDefinitionSchema).optional();
238378
238430
  }
238379
238431
  });
238432
+ var TopLevelPropertySchema = PropertyDefinitionSchema.refine((property) => property.type !== undefined, { message: "Top-level properties must declare a type", path: ["type"] });
238380
238433
  var EntitySchema = looseObject({
238381
238434
  type: literal("object").default("object"),
238382
238435
  name: string2().min(1).regex(/^\w+$/, "Entity name must contain only letters, numbers, and underscores"),
238383
238436
  title: string2().optional(),
238384
238437
  description: string2().optional(),
238385
- properties: record(string2(), PropertyDefinitionSchema).default({}),
238438
+ properties: record(string2(), TopLevelPropertySchema).default({}),
238386
238439
  required: array(string2()).optional(),
238387
238440
  rls: EntityRLSSchema.optional(),
238388
238441
  source: ResourceSourceSchema.default({ type: "project" })
@@ -239079,14 +239132,24 @@ async function openLogStream(filters) {
239079
239132
  return { kind: "stream", events: readStreamEvents(response.body) };
239080
239133
  }
239081
239134
  // src/core/project/config.ts
239135
+ var PROJECT_ROOT_NOT_FOUND = `Project root not found. Please ensure config.jsonc or config.json exists in the project directory or ${PROJECT_SUBDIR}/ subdirectory.`;
239136
+
239082
239137
  class ProjectConfigReader {
239083
239138
  pluginSourceByNamespace = new Map;
239084
239139
  async readProjectSettings(projectRoot) {
239085
239140
  const { root, configPath } = await this.findConfigOrThrow(projectRoot);
239086
- const project = await this.readConfigFile(configPath);
239141
+ const project = await this.readConfigFile(configPath, "safe");
239087
239142
  this.assertPluginProjectDoesNotLoadPlugins(project, configPath);
239088
239143
  return { ...project, root, configPath };
239089
239144
  }
239145
+ async readProjectSettingsOrDefaults(projectRoot) {
239146
+ const found = this.findConfig(projectRoot);
239147
+ if (!found) {
239148
+ return this.defaultSettingsOrThrow(projectRoot);
239149
+ }
239150
+ const project = await this.readConfigFile(found.configPath, "lenient");
239151
+ return { ...project, ...found };
239152
+ }
239090
239153
  async readProjectConfig(projectRoot) {
239091
239154
  const project = await this.readProjectSettings(projectRoot);
239092
239155
  const { configPath } = project;
@@ -239116,25 +239179,50 @@ class ProjectConfigReader {
239116
239179
  };
239117
239180
  }
239118
239181
  async findConfigOrThrow(projectRoot) {
239119
- let found;
239120
- if (projectRoot) {
239121
- const configPath = findConfigInDir(projectRoot);
239122
- found = configPath ? { root: projectRoot, configPath } : null;
239123
- } else {
239124
- found = findProjectRoot();
239125
- }
239182
+ const found = this.findConfig(projectRoot);
239126
239183
  if (!found) {
239127
- throw new ConfigNotFoundError(`Project root not found. Please ensure config.jsonc or config.json exists in the project directory or ${PROJECT_SUBDIR}/ subdirectory.`);
239184
+ throw new ConfigNotFoundError(PROJECT_ROOT_NOT_FOUND);
239128
239185
  }
239129
239186
  return found;
239130
239187
  }
239131
- async readConfigFile(configPath) {
239132
- const parsed = await readJsonFile(configPath);
239188
+ findConfig(projectRoot) {
239189
+ if (!projectRoot) {
239190
+ return findProjectRoot();
239191
+ }
239192
+ const configPath = findConfigInDir(projectRoot);
239193
+ return configPath ? { root: projectRoot, configPath } : null;
239194
+ }
239195
+ defaultSettingsOrThrow(projectRoot) {
239196
+ const root = projectRoot ?? process.cwd();
239197
+ if (!existsSync(join12(root, "package.json"))) {
239198
+ throw new ConfigNotFoundError(PROJECT_ROOT_NOT_FOUND);
239199
+ }
239200
+ warnConfigFallback(`No ${PROJECT_SUBDIR}/config.jsonc found in ${root}; using the default project config.`);
239201
+ const configPath = join12(root, PROJECT_SUBDIR, "config.jsonc");
239202
+ return { ...defaultProjectConfig(), root, configPath };
239203
+ }
239204
+ async readConfigFile(configPath, mode = "strict") {
239205
+ let parsed;
239206
+ try {
239207
+ parsed = await readJsonFile(configPath);
239208
+ } catch (error) {
239209
+ if (mode !== "lenient") {
239210
+ throw error;
239211
+ }
239212
+ warnConfigFallback(`${configPath} could not be read (${errorMessage(error)}); using the default project config.`);
239213
+ return defaultProjectConfig();
239214
+ }
239133
239215
  const result = ProjectConfigSchema.safeParse(parsed);
239134
- if (!result.success) {
239216
+ if (result.success) {
239217
+ return result.data;
239218
+ }
239219
+ const defaultable = mode === "lenient" || mode === "safe" && onlyDefaultableFieldsInvalid(result.error);
239220
+ if (!defaultable) {
239135
239221
  throw new SchemaValidationError("Invalid project configuration", result.error, configPath);
239136
239222
  }
239137
- return result.data;
239223
+ warnConfigFallback(`Invalid project configuration in ${configPath}; using defaults for the invalid fields:
239224
+ ${prettifyError(result.error)}`);
239225
+ return salvageProjectConfig(parsed, result.error);
239138
239226
  }
239139
239227
  async readProjectResources(configPath, project, includeActors = true) {
239140
239228
  const configDir = dirname10(configPath);
@@ -239267,13 +239355,20 @@ async function readProjectSettings(projectRoot) {
239267
239355
  const reader = new ProjectConfigReader;
239268
239356
  return await reader.readProjectSettings(projectRoot);
239269
239357
  }
239358
+ async function readProjectSettingsOrDefaults(projectRoot) {
239359
+ const reader = new ProjectConfigReader;
239360
+ return await reader.readProjectSettingsOrDefaults(projectRoot);
239361
+ }
239362
+ function errorMessage(error) {
239363
+ return error instanceof Error ? error.message : String(error);
239364
+ }
239270
239365
  // src/core/project/template.ts
239271
239366
  var import_ejs = __toESM(require_ejs(), 1);
239272
239367
  var import_front_matter2 = __toESM(require_front_matter(), 1);
239273
239368
  import { dirname as dirname11, join as join14 } from "node:path";
239274
239369
 
239275
239370
  // src/core/assets.ts
239276
- import { cpSync, existsSync } from "node:fs";
239371
+ import { cpSync, existsSync as existsSync2 } from "node:fs";
239277
239372
  import { homedir as homedir2 } from "node:os";
239278
239373
  import { join as join13 } from "node:path";
239279
239374
  // package.json
@@ -239399,9 +239494,9 @@ function getExecWrapperPath() {
239399
239494
  return join13(getBackendRuntimeDir(), "exec.ts");
239400
239495
  }
239401
239496
  function ensureNpmAssets(sourceDir) {
239402
- if (existsSync(ASSETS_DIR) && existsSync(getBackendRuntimeDir()))
239497
+ if (existsSync2(ASSETS_DIR) && existsSync2(getBackendRuntimeDir()))
239403
239498
  return;
239404
- if (!existsSync(sourceDir))
239499
+ if (!existsSync2(sourceDir))
239405
239500
  return;
239406
239501
  cpSync(sourceDir, ASSETS_DIR, { recursive: true });
239407
239502
  }
@@ -240240,7 +240335,7 @@ function buildAssetsConfig(assetsConfig, progress) {
240240
240335
  };
240241
240336
  }
240242
240337
  // ../../node_modules/is-plain-obj/index.js
240243
- function isPlainObject2(value) {
240338
+ function isPlainObject3(value) {
240244
240339
  if (typeof value !== "object" || value === null) {
240245
240340
  return false;
240246
240341
  }
@@ -240264,7 +240359,7 @@ var normalizeFileUrl = (file) => file instanceof URL ? fileURLToPath2(file) : fi
240264
240359
  // ../../node_modules/execa/lib/methods/parameters.js
240265
240360
  var normalizeParameters = (rawFile, rawArguments = [], rawOptions = {}) => {
240266
240361
  const filePath = safeNormalizeFileUrl(rawFile, "First argument");
240267
- const [commandArguments, options] = isPlainObject2(rawArguments) ? [[], rawArguments] : [rawArguments, rawOptions];
240362
+ const [commandArguments, options] = isPlainObject3(rawArguments) ? [[], rawArguments] : [rawArguments, rawOptions];
240268
240363
  if (!Array.isArray(commandArguments)) {
240269
240364
  throw new TypeError(`Second argument must be either an array of arguments or an options object: ${commandArguments}`);
240270
240365
  }
@@ -240276,7 +240371,7 @@ var normalizeParameters = (rawFile, rawArguments = [], rawOptions = {}) => {
240276
240371
  if (nullByteArgument !== undefined) {
240277
240372
  throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${nullByteArgument}`);
240278
240373
  }
240279
- if (!isPlainObject2(options)) {
240374
+ if (!isPlainObject3(options)) {
240280
240375
  throw new TypeError(`Last argument must be an options object: ${options}`);
240281
240376
  }
240282
240377
  return [filePath, normalizedArguments, options];
@@ -240413,7 +240508,7 @@ var parseExpression = (expression) => {
240413
240508
  if (typeOfExpression === "number") {
240414
240509
  return String(expression);
240415
240510
  }
240416
- if (isPlainObject2(expression) && (("stdout" in expression) || ("isMaxBuffer" in expression))) {
240511
+ if (isPlainObject3(expression) && (("stdout" in expression) || ("isMaxBuffer" in expression))) {
240417
240512
  return getSubprocessResult(expression);
240418
240513
  }
240419
240514
  if (expression instanceof ChildProcess || Object.prototype.toString.call(expression) === "[object Promise]") {
@@ -240461,7 +240556,7 @@ var normalizeFdSpecificOption = (options, optionName) => {
240461
240556
  return addDefaultValue(optionArray, optionName);
240462
240557
  };
240463
240558
  var getStdioLength = ({ stdio }) => Array.isArray(stdio) ? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length) : STANDARD_STREAMS_ALIASES.length;
240464
- var normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject2(optionValue) ? normalizeOptionObject(optionValue, optionArray, optionName) : optionArray.fill(optionValue);
240559
+ var normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject3(optionValue) ? normalizeOptionObject(optionValue, optionArray, optionName) : optionArray.fill(optionValue);
240465
240560
  var normalizeOptionObject = (optionValue, optionArray, optionName) => {
240466
240561
  for (const fdName of Object.keys(optionValue).sort(compareFdName)) {
240467
240562
  for (const fdNumber of parseFdName(fdName, optionName, optionArray)) {
@@ -243537,10 +243632,10 @@ var checkBooleanOption = (value, optionName) => {
243537
243632
  var isGenerator = (value) => isAsyncGenerator(value) || isSyncGenerator(value);
243538
243633
  var isAsyncGenerator = (value) => Object.prototype.toString.call(value) === "[object AsyncGeneratorFunction]";
243539
243634
  var isSyncGenerator = (value) => Object.prototype.toString.call(value) === "[object GeneratorFunction]";
243540
- var isTransformOptions = (value) => isPlainObject2(value) && (value.transform !== undefined || value.final !== undefined);
243635
+ var isTransformOptions = (value) => isPlainObject3(value) && (value.transform !== undefined || value.final !== undefined);
243541
243636
  var isUrl = (value) => Object.prototype.toString.call(value) === "[object URL]";
243542
243637
  var isRegularUrl = (value) => isUrl(value) && value.protocol !== "file:";
243543
- var isFilePathObject = (value) => isPlainObject2(value) && Object.keys(value).length > 0 && Object.keys(value).every((key) => FILE_PATH_KEYS.has(key)) && isFilePathString(value.file);
243638
+ var isFilePathObject = (value) => isPlainObject3(value) && Object.keys(value).length > 0 && Object.keys(value).every((key) => FILE_PATH_KEYS.has(key)) && isFilePathString(value.file);
243544
243639
  var FILE_PATH_KEYS = new Set(["file", "append"]);
243545
243640
  var isFilePathString = (file) => typeof file === "string";
243546
243641
  var isUnknownStdioString = (type, value) => type === "native" && typeof value === "string" && !KNOWN_STDIO_STRINGS.has(value);
@@ -243657,7 +243752,7 @@ var normalizeDuplex = ({
243657
243752
  };
243658
243753
  };
243659
243754
  var normalizeTransformStream = ({ stdioItem, stdioItem: { value }, index, newTransforms, direction }) => {
243660
- const { transform, objectMode } = isPlainObject2(value) ? value : { transform: value };
243755
+ const { transform, objectMode } = isPlainObject3(value) ? value : { transform: value };
243661
243756
  const { writableObjectMode, readableObjectMode } = getTransformObjectModes(objectMode, index, newTransforms, direction);
243662
243757
  return {
243663
243758
  ...stdioItem,
@@ -243671,7 +243766,7 @@ var normalizeGenerator = ({ stdioItem, stdioItem: { value }, index, newTransform
243671
243766
  binary: binaryOption = false,
243672
243767
  preserveNewlines = false,
243673
243768
  objectMode
243674
- } = isPlainObject2(value) ? value : { transform: value };
243769
+ } = isPlainObject3(value) ? value : { transform: value };
243675
243770
  const binary = binaryOption || BINARY_ENCODINGS.has(encoding);
243676
243771
  const { writableObjectMode, readableObjectMode } = getTransformObjectModes(objectMode, index, newTransforms, direction);
243677
243772
  return {
@@ -245607,7 +245702,7 @@ var unpipeOnSignalAbort = async (unpipeSignal, { sourceStream, mergedStream, fil
245607
245702
 
245608
245703
  // ../../node_modules/execa/lib/pipe/setup.js
245609
245704
  var pipeToSubprocess = (sourceInfo, ...pipeArguments) => {
245610
- if (isPlainObject2(pipeArguments[0])) {
245705
+ if (isPlainObject3(pipeArguments[0])) {
245611
245706
  return pipeToSubprocess.bind(undefined, {
245612
245707
  ...sourceInfo,
245613
245708
  boundOptions: { ...sourceInfo.boundOptions, ...pipeArguments[0] }
@@ -246626,7 +246721,7 @@ var mergeOptions = (boundOptions, options) => {
246626
246721
  return { ...boundOptions, ...newOptions };
246627
246722
  };
246628
246723
  var mergeOption = (optionName, boundOptionValue, optionValue) => {
246629
- if (DEEP_OPTIONS.has(optionName) && isPlainObject2(boundOptionValue) && isPlainObject2(optionValue)) {
246724
+ if (DEEP_OPTIONS.has(optionName) && isPlainObject3(boundOptionValue) && isPlainObject3(optionValue)) {
246630
246725
  return { ...boundOptionValue, ...optionValue };
246631
246726
  }
246632
246727
  return optionValue;
@@ -246649,7 +246744,7 @@ var createExeca = (mapArguments, boundOptions, deepOptions, setBoundExeca) => {
246649
246744
  return boundExeca;
246650
246745
  };
246651
246746
  var callBoundExeca = ({ mapArguments, deepOptions = {}, boundOptions = {}, setBoundExeca, createNested }, firstArgument, ...nextArguments) => {
246652
- if (isPlainObject2(firstArgument)) {
246747
+ if (isPlainObject3(firstArgument)) {
246653
246748
  return createNested(mapArguments, mergeOptions(boundOptions, firstArgument), setBoundExeca);
246654
246749
  }
246655
246750
  const { file, commandArguments, options, isSync } = parseArguments({
@@ -246852,37 +246947,19 @@ async function deployAll(projectData, options) {
246852
246947
  }
246853
246948
  // src/core/project/target.ts
246854
246949
  import { dirname as dirname13, join as join19, resolve as resolve6 } from "node:path";
246855
- var DEFAULT_BUILD_COMMAND = "npm run build";
246856
- var DEFAULT_OUTPUT_DIRECTORY = "dist";
246857
246950
  async function resolveBuildTarget(projectRoot, overrides = {}) {
246858
246951
  const project = await readSettingsIfPresent(projectRoot);
246859
246952
  const root = project?.root ?? projectRoot ?? process.cwd();
246953
+ const site = project ? siteOrDefault(project) : DEFAULT_SITE;
246860
246954
  return {
246861
246955
  root,
246862
246956
  configDir: project ? dirname13(project.configPath) : join19(root, PROJECT_SUBDIR),
246863
- buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
246864
- outputDir: outputDirectory(project, root, overrides.outputDir),
246957
+ buildCommand: site.buildCommand,
246958
+ outputDir: resolve6(root, overrides.outputDir ?? site.outputDirectory ?? DEFAULT_SITE.outputDirectory),
246865
246959
  entitiesDir: project?.entitiesDir ?? "entities",
246866
246960
  agentsDir: project?.agentsDir ?? "agents"
246867
246961
  };
246868
246962
  }
246869
- function outputDirectory(project, root, override) {
246870
- const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
246871
- return configured ? resolve6(root, configured) : null;
246872
- }
246873
- function requireOutputDir(target) {
246874
- if (target.outputDir === null) {
246875
- throw new ConfigNotFoundError("No site configuration found.", {
246876
- hints: [
246877
- {
246878
- message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
246879
- },
246880
- { message: `Or pass --output-dir <dir>, relative to ${target.root}` }
246881
- ]
246882
- });
246883
- }
246884
- return target.outputDir;
246885
- }
246886
246963
  async function readSettingsIfPresent(projectRoot) {
246887
246964
  try {
246888
246965
  return await readProjectSettings(projectRoot);
@@ -247411,6 +247488,7 @@ class Base44Command extends Command2 {
247411
247488
  }
247412
247489
  action(fn) {
247413
247490
  return super.action(async (...args) => {
247491
+ setConfigWarningHandler((message) => this.context.log.warn(message));
247414
247492
  const jsonMode = this.context.jsonMode;
247415
247493
  const quiet = this.context.isNonInteractive || jsonMode;
247416
247494
  if (!quiet) {
@@ -249668,16 +249746,7 @@ function getFunctionsCommand() {
249668
249746
  }
249669
249747
 
249670
249748
  // src/cli/commands/project/site-build.ts
249671
- async function runSiteBuild({ runTask }, { root, buildCommand, appId }) {
249672
- if (!buildCommand) {
249673
- throw new ConfigNotFoundError("No site build command found.", {
249674
- hints: [
249675
- {
249676
- message: `Add a 'site' block to your config.jsonc (e.g., "site": { "buildCommand": "npm run build" }). Inside one, buildCommand defaults to "npm run build".`
249677
- }
249678
- ]
249679
- });
249680
- }
249749
+ async function runSiteBuild({ runTask }, { root, buildCommand = DEFAULT_SITE.buildCommand, appId }) {
249681
249750
  await runTask("Building site...", () => execa({
249682
249751
  cwd: root,
249683
249752
  shell: true,
@@ -250864,7 +250933,7 @@ async function collectArtifacts(target) {
250864
250933
  const built = await resolveFullStackBuild(target.root);
250865
250934
  const siteWorker = built ? await describeSiteWorker(built) : null;
250866
250935
  return {
250867
- assets: built ? built.assetsDir ? await collectBuildOutput(built.assetsDir) : [] : await collectBuildOutput(requireOutputDir(target), {
250936
+ assets: built ? built.assetsDir ? await collectBuildOutput(built.assetsDir) : [] : await collectBuildOutput(target.outputDir, {
250868
250937
  entryFile: ENTRY2
250869
250938
  }),
250870
250939
  ...siteWorker ? { siteWorker } : {},
@@ -251468,15 +251537,6 @@ async function deployToDeploymentsApi(ctx, project, options) {
251468
251537
  }
251469
251538
  async function deployTarball({ runTask }, project) {
251470
251539
  const outputDir = siteOutputDir(project);
251471
- if (!outputDir) {
251472
- throw new ConfigNotFoundError("No site configuration found.", {
251473
- hints: [
251474
- {
251475
- message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
251476
- }
251477
- ]
251478
- });
251479
- }
251480
251540
  const { appUrl } = await runTask("Creating archive and deploying site...", async () => await deploySite(outputDir), {
251481
251541
  successMessage: "Site deployed successfully",
251482
251542
  errorMessage: "Deployment failed"
@@ -251484,8 +251544,8 @@ async function deployTarball({ runTask }, project) {
251484
251544
  return { outroMessage: `Visit your site at: ${appUrl}` };
251485
251545
  }
251486
251546
  function siteOutputDir(project) {
251487
- const outputDirectory = project.site?.outputDirectory;
251488
- return outputDirectory ? resolve15(project.root, outputDirectory) : null;
251547
+ const { outputDirectory = DEFAULT_SITE.outputDirectory } = siteOrDefault(project);
251548
+ return resolve15(project.root, outputDirectory);
251489
251549
  }
251490
251550
  function getSiteDeployCommand() {
251491
251551
  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)");
@@ -251679,14 +251739,11 @@ function stopRunnerOnProcessSignals(runner) {
251679
251739
  var DEFAULT_SERVE_COMMAND = "npm run dev";
251680
251740
  async function siteDevAction(ctx, forwarded) {
251681
251741
  const { app } = ctx;
251682
- if (!app?.projectRoot) {
251742
+ if (!app) {
251683
251743
  throw new ConfigInvalidError("base44 site dev requires a linked local project. Run it from a project with base44/.app.jsonc.");
251684
251744
  }
251685
- const project = await readProjectSettings(app.projectRoot);
251686
- const site = project.site;
251687
- if (!site) {
251688
- 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".`);
251689
- }
251745
+ const project = await readProjectSettingsOrDefaults(app.projectRoot);
251746
+ const site = siteOrDefault(project);
251690
251747
  const serveCommand = site.serveCommand ?? DEFAULT_SERVE_COMMAND;
251691
251748
  const command = [serveCommand, ...forwarded].join(" ");
251692
251749
  const runner = createServeCommandRunner({
@@ -251707,17 +251764,8 @@ function getSiteDevCommand() {
251707
251764
  async function installAction({
251708
251765
  runTask
251709
251766
  }) {
251710
- const project = await readProjectSettings();
251711
- const installCommand = project.site?.installCommand;
251712
- if (!installCommand) {
251713
- throw new ConfigNotFoundError("No site install command found.", {
251714
- hints: [
251715
- {
251716
- message: `Add a 'site' block to your config.jsonc (e.g., "site": { "installCommand": "npm ci" }). Inside one, installCommand defaults to "npm install".`
251717
- }
251718
- ]
251719
- });
251720
- }
251767
+ const project = await readProjectSettingsOrDefaults();
251768
+ const { installCommand } = siteOrDefault(project);
251721
251769
  await runTask("Installing site dependencies...", () => execa({ cwd: project.root, shell: true })`${installCommand}`, {
251722
251770
  successMessage: "Dependencies installed",
251723
251771
  errorMessage: "Install failed"
@@ -256980,7 +257028,7 @@ function isBuiltin2(candidate, className) {
256980
257028
  function isEvent(candidate) {
256981
257029
  return !isUndefined(Event) && isInstanceOf(candidate, Event);
256982
257030
  }
256983
- function isPlainObject3(candidate) {
257031
+ function isPlainObject4(candidate) {
256984
257032
  return isBuiltin2(candidate, "Object");
256985
257033
  }
256986
257034
  function isInstanceOf(candidate, base) {
@@ -260116,7 +260164,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
260116
260164
  const personProperties = {};
260117
260165
  const groupProperties = {};
260118
260166
  for (const [key, value] of Object.entries(eventProperties))
260119
- if (isPlainObject3(value) && groups && key in groups) {
260167
+ if (isPlainObject4(value) && groups && key in groups) {
260120
260168
  const groupProps = {};
260121
260169
  for (const [groupKey, groupValue] of Object.entries(value))
260122
260170
  groupProps[String(groupKey)] = String(groupValue);
@@ -260593,4 +260641,4 @@ export {
260593
260641
  runCLI
260594
260642
  };
260595
260643
 
260596
- //# debugId=0FFE93EB6111BBF064756E2164756E21
260644
+ //# debugId=F5BEAB54424CF0ED64756E2164756E21