@base44-preview/cli 0.1.16-pr.626.47e8953 → 0.1.16-pr.626.51eb442

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
@@ -228657,20 +228657,6 @@ function isCLIError(error) {
228657
228657
  function isUserError(error) {
228658
228658
  return error instanceof UserError;
228659
228659
  }
228660
- var STEP = Symbol.for("base44.commandStep");
228661
- async function tagStep(step, run) {
228662
- try {
228663
- return await run();
228664
- } catch (error) {
228665
- if (error !== null && typeof error === "object" && !(STEP in error) && Object.isExtensible(error)) {
228666
- Object.defineProperty(error, STEP, { value: step, enumerable: false });
228667
- }
228668
- throw error;
228669
- }
228670
- }
228671
- function stepOf(error) {
228672
- return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
228673
- }
228674
228660
 
228675
228661
  // src/core/utils/fs.ts
228676
228662
  async function pathExists(path) {
@@ -246809,49 +246795,6 @@ async function deployAll(projectData, options) {
246809
246795
  }
246810
246796
  return { connectorResults };
246811
246797
  }
246812
- // src/core/project/target.ts
246813
- import { dirname as dirname13, join as join19, resolve as resolve6 } from "node:path";
246814
- var DEFAULT_BUILD_COMMAND = "npm run build";
246815
- var DEFAULT_OUTPUT_DIRECTORY = "dist";
246816
- async function resolveBuildTarget(projectRoot, overrides = {}) {
246817
- const project = await readSettingsIfPresent(projectRoot);
246818
- const root = project?.root ?? projectRoot ?? process.cwd();
246819
- return {
246820
- root,
246821
- configDir: project ? dirname13(project.configPath) : join19(root, PROJECT_SUBDIR),
246822
- buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
246823
- outputDir: outputDirectory(project, root, overrides.outputDir),
246824
- entitiesDir: project?.entitiesDir ?? "entities",
246825
- agentsDir: project?.agentsDir ?? "agents"
246826
- };
246827
- }
246828
- function outputDirectory(project, root, override) {
246829
- const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
246830
- return configured ? resolve6(root, configured) : null;
246831
- }
246832
- function requireOutputDir(target) {
246833
- if (target.outputDir === null) {
246834
- throw new ConfigNotFoundError("No site configuration found.", {
246835
- hints: [
246836
- {
246837
- message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
246838
- },
246839
- { message: `Or pass --output-dir <dir>, relative to ${target.root}` }
246840
- ]
246841
- });
246842
- }
246843
- return target.outputDir;
246844
- }
246845
- async function readSettingsIfPresent(projectRoot) {
246846
- try {
246847
- return await readProjectSettings(projectRoot);
246848
- } catch (error) {
246849
- if (error instanceof ConfigNotFoundError) {
246850
- return null;
246851
- }
246852
- throw error;
246853
- }
246854
- }
246855
246798
  // src/core/clients/base44-client.ts
246856
246799
  var retriedRequests = new WeakSet;
246857
246800
  async function captureRequestBody(request, options) {
@@ -247305,6 +247248,178 @@ async function resolveBranchName(name) {
247305
247248
  return matches[0].id;
247306
247249
  }
247307
247250
 
247251
+ // src/core/version/publish.ts
247252
+ import { randomUUID as randomUUID4 } from "node:crypto";
247253
+
247254
+ // src/core/version/schema.ts
247255
+ var DeclareVersionResponseSchema = object({
247256
+ session_id: string2(),
247257
+ uploads: array(object({
247258
+ path: string2(),
247259
+ url: string2(),
247260
+ content_type: string2(),
247261
+ content_length: number2(),
247262
+ checksum_sha256: string2()
247263
+ }))
247264
+ }).transform((data) => ({
247265
+ sessionId: data.session_id,
247266
+ uploads: data.uploads.map((upload) => ({
247267
+ path: upload.path,
247268
+ url: upload.url,
247269
+ contentType: upload.content_type,
247270
+ contentLength: upload.content_length,
247271
+ checksumSha256: upload.checksum_sha256
247272
+ }))
247273
+ }));
247274
+ var CreateVersionResponseSchema = object({
247275
+ version_id: string2(),
247276
+ manifest_hash: string2()
247277
+ }).transform((data) => ({
247278
+ versionId: data.version_id,
247279
+ manifestHash: data.manifest_hash
247280
+ }));
247281
+ var EnvironmentResponseSchema = object({
247282
+ name: string2(),
247283
+ version_id: string2(),
247284
+ manifest_hash: string2(),
247285
+ deployment_id: string2()
247286
+ }).transform((data) => ({
247287
+ name: data.name,
247288
+ versionId: data.version_id,
247289
+ manifestHash: data.manifest_hash,
247290
+ deploymentId: data.deployment_id
247291
+ }));
247292
+
247293
+ // src/core/version/api.ts
247294
+ var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
247295
+ var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
247296
+ function declaredFile({ path, size, digest }) {
247297
+ return { path, size, digest };
247298
+ }
247299
+ function declaredModule(module) {
247300
+ return { ...declaredFile(module), type: module.type };
247301
+ }
247302
+ function declaredAssetsConfig(config) {
247303
+ const stated = {
247304
+ html_handling: config?.htmlHandling ?? null,
247305
+ not_found_handling: config?.notFoundHandling ?? null,
247306
+ run_worker_first: config?.runWorkerFirst ?? null,
247307
+ headers: config?.headers ?? null,
247308
+ redirects: config?.redirects ?? null
247309
+ };
247310
+ return Object.values(stated).every((v) => v === null) ? null : stated;
247311
+ }
247312
+ async function post(path, json, doing) {
247313
+ try {
247314
+ return await getAppClient().post(path, { json, timeout: 180000 });
247315
+ } catch (error) {
247316
+ throw await ApiError.fromHttpError(error, doing);
247317
+ }
247318
+ }
247319
+ var KEYED_RETRY = {
247320
+ limit: 3,
247321
+ methods: ["patch"],
247322
+ statusCodes: [408, 500, 502, 503, 504]
247323
+ };
247324
+ async function patch(path, json, doing, retry) {
247325
+ try {
247326
+ return await getAppClient().patch(path, {
247327
+ json,
247328
+ timeout: 180000,
247329
+ ...retry ? { retry } : {}
247330
+ });
247331
+ } catch (error) {
247332
+ throw await ApiError.fromHttpError(error, doing);
247333
+ }
247334
+ }
247335
+ function parse10(schema, body, what) {
247336
+ const result = schema.safeParse(body);
247337
+ if (!result.success) {
247338
+ throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
247339
+ }
247340
+ return result.data;
247341
+ }
247342
+ async function createVersion(artifacts, options = {}) {
247343
+ const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
247344
+ static_bundle: artifacts.files.map(declaredFile),
247345
+ ...artifacts.siteWorker ? {
247346
+ site_worker: {
247347
+ main: artifacts.siteWorker.main,
247348
+ modules: artifacts.siteWorker.modules.map(declaredModule),
247349
+ assets: artifacts.siteWorker.assets.map(declaredFile),
247350
+ compatibility_date: artifacts.siteWorker.compatibilityDate,
247351
+ compatibility_flags: artifacts.siteWorker.compatibilityFlags,
247352
+ assets_config: declaredAssetsConfig(artifacts.siteWorker.assetsConfig)
247353
+ }
247354
+ } : {},
247355
+ entities: artifacts.entities,
247356
+ agents: artifacts.agents,
247357
+ source_commit: options.sourceCommit
247358
+ }, "declaring a version")).json(), "declare");
247359
+ const declaredFiles = [
247360
+ ...artifacts.files,
247361
+ ...artifacts.siteWorker?.modules ?? [],
247362
+ ...artifacts.siteWorker?.assets ?? []
247363
+ ];
247364
+ options.progress?.onDeclared?.({ fileCount: declaredFiles.length });
247365
+ if (declared.uploads.length !== declaredFiles.length) {
247366
+ throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
247367
+ }
247368
+ const drifted = declared.uploads.findIndex((upload, index) => upload.path !== declaredFiles[index].path);
247369
+ if (drifted !== -1) {
247370
+ throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
247371
+ }
247372
+ let uploadedFiles = 0;
247373
+ await pMap(declared.uploads, async (upload, index) => {
247374
+ await putPresigned(upload, declaredFiles[index].absolutePath);
247375
+ uploadedFiles++;
247376
+ options.progress?.onUpload?.({
247377
+ uploadedFiles,
247378
+ totalFiles: declared.uploads.length
247379
+ });
247380
+ }, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
247381
+ return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
247382
+ }
247383
+ async function setEnvironmentVersion(environment, versionId, options = {}) {
247384
+ return parse10(EnvironmentResponseSchema, await (await patch(`environments/${encodeURIComponent(environment)}`, {
247385
+ version_id: versionId,
247386
+ ...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
247387
+ }, "setting the environment's version", options.idempotencyKey ? KEYED_RETRY : undefined)).json(), "environment");
247388
+ }
247389
+
247390
+ // src/core/version/publish.ts
247391
+ var STEP = Symbol.for("base44.publishStep");
247392
+ var DEFAULT_ENVIRONMENT = "production";
247393
+ async function tagStep(step, run) {
247394
+ try {
247395
+ return await run();
247396
+ } catch (error) {
247397
+ if (error !== null && typeof error === "object" && !(STEP in error) && Object.isExtensible(error)) {
247398
+ Object.defineProperty(error, STEP, { value: step, enumerable: false });
247399
+ }
247400
+ throw error;
247401
+ }
247402
+ }
247403
+ function stepOf(error) {
247404
+ return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
247405
+ }
247406
+ async function publishVersion(artifacts, options = {}) {
247407
+ const version = await tagStep("create_version", () => createVersion(artifacts, {
247408
+ sourceCommit: options.sourceCommit,
247409
+ concurrency: options.concurrency,
247410
+ progress: options.progress
247411
+ }));
247412
+ const environment = await tagStep("deploy", () => setEnvironmentVersion(options.target ?? DEFAULT_ENVIRONMENT, version.versionId, {
247413
+ idempotencyKey: randomUUID4()
247414
+ }));
247415
+ return {
247416
+ environment: environment.name,
247417
+ versionId: environment.versionId,
247418
+ manifestHash: environment.manifestHash,
247419
+ deploymentId: environment.deploymentId
247420
+ };
247421
+ }
247422
+
247308
247423
  // src/cli/utils/command/Base44Command.ts
247309
247424
  function writeJsonSuccess(result) {
247310
247425
  if (result.stdout) {
@@ -247695,7 +247810,7 @@ function getActorsCommand() {
247695
247810
  }
247696
247811
 
247697
247812
  // src/cli/commands/agent-skills/pull.ts
247698
- import { dirname as dirname14, join as join20 } from "node:path";
247813
+ import { dirname as dirname13, join as join19 } from "node:path";
247699
247814
  // src/core/utils/dependencies.ts
247700
247815
  import { spawnSync as spawnSync2 } from "node:child_process";
247701
247816
  function verifyDenoInstalled(context) {
@@ -247784,7 +247899,7 @@ async function pullAction({
247784
247899
  runTask
247785
247900
  }) {
247786
247901
  const { project } = await readProjectConfig();
247787
- const dir = join20(dirname14(project.configPath), project.agentSkillsDir);
247902
+ const dir = join19(dirname13(project.configPath), project.agentSkillsDir);
247788
247903
  const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
247789
247904
  successMessage: "Agent skills fetched successfully",
247790
247905
  errorMessage: "Failed to fetch agent skills"
@@ -247840,14 +247955,14 @@ function getAgentSkillsCommand() {
247840
247955
  }
247841
247956
 
247842
247957
  // src/cli/commands/agents/pull.ts
247843
- import { dirname as dirname15, join as join21 } from "node:path";
247958
+ import { dirname as dirname14, join as join20 } from "node:path";
247844
247959
  async function pullAgentsAction({
247845
247960
  log,
247846
247961
  runTask
247847
247962
  }) {
247848
247963
  const { project } = await readProjectConfig();
247849
- const configDir = dirname15(project.configPath);
247850
- const agentsDir = join21(configDir, project.agentsDir);
247964
+ const configDir = dirname14(project.configPath);
247965
+ const agentsDir = join20(configDir, project.agentsDir);
247851
247966
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
247852
247967
  return await fetchAgents();
247853
247968
  }, {
@@ -247917,12 +248032,12 @@ function getAgentsCommand() {
247917
248032
  }
247918
248033
 
247919
248034
  // src/cli/commands/auth/password-login.ts
247920
- import { dirname as dirname16, join as join22 } from "node:path";
248035
+ import { dirname as dirname15, join as join21 } from "node:path";
247921
248036
  async function passwordLoginAction({ log, runTask }, action) {
247922
248037
  const shouldEnable = action === "enable";
247923
248038
  const { project } = await readProjectConfig();
247924
- const configDir = dirname16(project.configPath);
247925
- const authDir = join22(configDir, project.authDir);
248039
+ const configDir = dirname15(project.configPath);
248040
+ const authDir = join21(configDir, project.authDir);
247926
248041
  const updated = await runTask("Updating local auth config", async () => {
247927
248042
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
247928
248043
  const merged = { ...current, enableUsernamePassword: shouldEnable };
@@ -247942,14 +248057,14 @@ function getPasswordLoginCommand() {
247942
248057
  }
247943
248058
 
247944
248059
  // src/cli/commands/auth/pull.ts
247945
- import { dirname as dirname17, join as join23 } from "node:path";
248060
+ import { dirname as dirname16, join as join22 } from "node:path";
247946
248061
  async function pullAuthAction({
247947
248062
  log,
247948
248063
  runTask
247949
248064
  }) {
247950
248065
  const { project } = await readProjectConfig();
247951
- const configDir = dirname17(project.configPath);
247952
- const authDir = join23(configDir, project.authDir);
248066
+ const configDir = dirname16(project.configPath);
248067
+ const authDir = join22(configDir, project.authDir);
247953
248068
  const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
247954
248069
  return await pullAuthConfig();
247955
248070
  }, {
@@ -248013,7 +248128,7 @@ function getAuthPushCommand() {
248013
248128
  }
248014
248129
 
248015
248130
  // src/cli/commands/auth/social-login.ts
248016
- import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
248131
+ import { dirname as dirname17, join as join23, resolve as resolve6 } from "node:path";
248017
248132
  var PROVIDER_LABELS = {
248018
248133
  google: "Google",
248019
248134
  microsoft: "Microsoft",
@@ -248053,7 +248168,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
248053
248168
  let clientSecret;
248054
248169
  if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
248055
248170
  if (options.envFile) {
248056
- const secrets = await parseEnvFile(resolve7(options.envFile));
248171
+ const secrets = await parseEnvFile(resolve6(options.envFile));
248057
248172
  const value = secrets[oauthCli.envVar];
248058
248173
  if (!value) {
248059
248174
  throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
@@ -248083,8 +248198,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
248083
248198
  }
248084
248199
  }
248085
248200
  const { project } = await readProjectConfig();
248086
- const configDir = dirname18(project.configPath);
248087
- const authDir = join24(configDir, project.authDir);
248201
+ const configDir = dirname17(project.configPath);
248202
+ const authDir = join23(configDir, project.authDir);
248088
248203
  const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
248089
248204
  if (clientSecret) {
248090
248205
  await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
@@ -248109,7 +248224,7 @@ function getSocialLoginCommand() {
248109
248224
  }
248110
248225
 
248111
248226
  // src/cli/commands/auth/sso.ts
248112
- import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
248227
+ import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
248113
248228
  var SSOConfigFileSchema = object({
248114
248229
  provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
248115
248230
  clientId: string2(),
@@ -248125,7 +248240,7 @@ var SSOConfigFileSchema = object({
248125
248240
  ssoName: string2().optional()
248126
248241
  });
248127
248242
  async function loadSSOConfigFile(filePath) {
248128
- const resolved = resolve8(filePath);
248243
+ const resolved = resolve7(filePath);
248129
248244
  const raw = await readJsonFile(resolved);
248130
248245
  const result = SSOConfigFileSchema.safeParse(raw);
248131
248246
  if (!result.success) {
@@ -248213,7 +248328,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
248213
248328
  }
248214
248329
  let clientSecret;
248215
248330
  if (merged.envFile && !merged.clientSecret) {
248216
- const secrets = await parseEnvFile(resolve8(merged.envFile));
248331
+ const secrets = await parseEnvFile(resolve7(merged.envFile));
248217
248332
  const value = secrets.sso_client_secret;
248218
248333
  if (!value) {
248219
248334
  throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
@@ -248272,8 +248387,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
248272
248387
  throw error;
248273
248388
  }
248274
248389
  const { project } = await readProjectConfig();
248275
- const configDir = dirname19(project.configPath);
248276
- const authDir = join25(configDir, project.authDir);
248390
+ const configDir = dirname18(project.configPath);
248391
+ const authDir = join24(configDir, project.authDir);
248277
248392
  await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
248278
248393
  await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
248279
248394
  return {
@@ -248288,8 +248403,8 @@ async function ssoDisableAction({ log, runTask }, options) {
248288
248403
  throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
248289
248404
  }
248290
248405
  const { project } = await readProjectConfig();
248291
- const configDir = dirname19(project.configPath);
248292
- const authDir = join25(configDir, project.authDir);
248406
+ const configDir = dirname18(project.configPath);
248407
+ const authDir = join24(configDir, project.authDir);
248293
248408
  const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
248294
248409
  await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
248295
248410
  if (!hasAnyLoginMethod(updated)) {
@@ -249171,13 +249286,13 @@ function getConnectorsListAvailableCommand() {
249171
249286
  }
249172
249287
 
249173
249288
  // src/cli/commands/connectors/pull.ts
249174
- import { dirname as dirname20, join as join26, resolve as resolve9 } from "node:path";
249289
+ import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
249175
249290
  async function resolveConnectorsDir(options) {
249176
249291
  if (!getAppContext().projectRoot) {
249177
- return resolve9(options.dir ?? "connectors");
249292
+ return resolve8(options.dir ?? "connectors");
249178
249293
  }
249179
249294
  const { project } = await readProjectConfig();
249180
- return join26(dirname20(project.configPath), project.connectorsDir);
249295
+ return join25(dirname19(project.configPath), project.connectorsDir);
249181
249296
  }
249182
249297
  async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
249183
249298
  const connectorsDir = await resolveConnectorsDir(options);
@@ -249218,10 +249333,10 @@ function getConnectorsPullCommand() {
249218
249333
  }
249219
249334
 
249220
249335
  // src/cli/commands/connectors/push.ts
249221
- import { resolve as resolve10 } from "node:path";
249336
+ import { resolve as resolve9 } from "node:path";
249222
249337
  async function readConnectorsToPush(options) {
249223
249338
  if (!getAppContext().projectRoot) {
249224
- return readAllConnectors(resolve10(options.dir ?? "connectors"));
249339
+ return readAllConnectors(resolve9(options.dir ?? "connectors"));
249225
249340
  }
249226
249341
  const { connectors } = await readProjectConfig();
249227
249342
  return connectors;
@@ -249564,11 +249679,11 @@ function getListCommand() {
249564
249679
  }
249565
249680
 
249566
249681
  // src/cli/commands/functions/pull.ts
249567
- import { dirname as dirname21, join as join27 } from "node:path";
249682
+ import { dirname as dirname20, join as join26 } from "node:path";
249568
249683
  async function pullFunctionsAction({ log, runTask }, name) {
249569
249684
  const { project, functions } = await readProjectConfig();
249570
- const configDir = dirname21(project.configPath);
249571
- const functionsDir = join27(configDir, project.functionsDir);
249685
+ const configDir = dirname20(project.configPath);
249686
+ const functionsDir = join26(configDir, project.functionsDir);
249572
249687
  const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
249573
249688
  const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
249574
249689
  const { functions } = await listDeployedFunctions();
@@ -249668,17 +249783,156 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
249668
249783
  });
249669
249784
  return !Ct(answer) && answer;
249670
249785
  }
249786
+ // src/core/version/artifacts.ts
249787
+ import { createHash as createHash2 } from "node:crypto";
249788
+ import { join as join28, resolve as resolve11 } from "node:path";
249671
249789
 
249672
- // src/cli/commands/project/build.ts
249673
- async function buildAction(ctx) {
249674
- const app = requireApp(ctx);
249675
- const target = await resolveBuildTarget(app.projectRoot);
249676
- await runSiteBuild(ctx, {
249677
- root: target.root,
249678
- buildCommand: target.buildCommand,
249679
- appId: app.id
249680
- });
249681
- return {
249790
+ // src/core/version/project.ts
249791
+ import { dirname as dirname21, join as join27, resolve as resolve10 } from "node:path";
249792
+ var DEFAULT_BUILD_COMMAND = "npm run build";
249793
+ var DEFAULT_OUTPUT_DIRECTORY = "dist";
249794
+ async function resolvePublishTarget(projectRoot, overrides = {}) {
249795
+ const project = await readSettingsIfPresent(projectRoot);
249796
+ const root = project?.root ?? projectRoot ?? process.cwd();
249797
+ return {
249798
+ root,
249799
+ configDir: project ? dirname21(project.configPath) : join27(root, PROJECT_SUBDIR),
249800
+ buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
249801
+ outputDir: outputDirectory(project, root, overrides.outputDir),
249802
+ entitiesDir: project?.entitiesDir ?? "entities",
249803
+ agentsDir: project?.agentsDir ?? "agents"
249804
+ };
249805
+ }
249806
+ function outputDirectory(project, root, override) {
249807
+ const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
249808
+ return configured ? resolve10(root, configured) : null;
249809
+ }
249810
+ function requireOutputDir(target) {
249811
+ if (target.outputDir === null) {
249812
+ throw new ConfigNotFoundError("No site configuration found.", {
249813
+ hints: [
249814
+ {
249815
+ message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
249816
+ },
249817
+ { message: `Or pass --output-dir <dir>, relative to ${target.root}` }
249818
+ ]
249819
+ });
249820
+ }
249821
+ return target.outputDir;
249822
+ }
249823
+ async function readSettingsIfPresent(projectRoot) {
249824
+ try {
249825
+ return await readProjectSettings(projectRoot);
249826
+ } catch (error) {
249827
+ if (error instanceof ConfigNotFoundError) {
249828
+ return null;
249829
+ }
249830
+ throw error;
249831
+ }
249832
+ }
249833
+
249834
+ // src/core/version/artifacts.ts
249835
+ var MAX_FILE_COUNT = 50000;
249836
+ var HASH_CONCURRENCY = 32;
249837
+ var ENTRY2 = "index.html";
249838
+ async function digestFile(absolutePath) {
249839
+ const hash = await hashFileInto(createHash2("sha256"), absolutePath);
249840
+ return `sha256:${hash.digest("hex")}`;
249841
+ }
249842
+ async function collectBuildOutput(outputDir, options = {}) {
249843
+ const found = await describeBuildOutput(outputDir);
249844
+ if (found.length > MAX_FILE_COUNT) {
249845
+ throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
249846
+ }
249847
+ if (options.entryFile) {
249848
+ if (found.length === 0) {
249849
+ throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
249850
+ hints: [
249851
+ { message: "Run 'base44 build' first", command: "base44 build" }
249852
+ ]
249853
+ });
249854
+ }
249855
+ if (!found.some((f) => f.path === options.entryFile)) {
249856
+ throw new InvalidInputError(`${outputDir} has no ${options.entryFile}, so nothing could enter the site.`);
249857
+ }
249858
+ }
249859
+ return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
249860
+ }
249861
+ async function collectSiteWorker(projectRoot) {
249862
+ const built = await resolveFullStackBuild(projectRoot);
249863
+ if (!built) {
249864
+ return null;
249865
+ }
249866
+ const { config, modules, assetsDir } = built;
249867
+ const entry = resolve11(config.configDir, config.main);
249868
+ const main = modules.find((m) => m.absolutePath === entry)?.name;
249869
+ if (!main) {
249870
+ throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
249871
+ }
249872
+ return {
249873
+ main,
249874
+ modules: await pMap(modules, async ({ name, absolutePath, size, type }) => ({
249875
+ path: name,
249876
+ absolutePath,
249877
+ size,
249878
+ digest: await digestFile(absolutePath),
249879
+ type
249880
+ }), { concurrency: HASH_CONCURRENCY }),
249881
+ assets: assetsDir ? await collectBuildOutput(assetsDir) : [],
249882
+ compatibilityDate: config.compatibilityDate,
249883
+ compatibilityFlags: config.compatibilityFlags,
249884
+ assetsConfig: config.assetsConfig
249885
+ };
249886
+ }
249887
+ async function readRawResources(dir) {
249888
+ if (!await pathExists(dir)) {
249889
+ return {};
249890
+ }
249891
+ const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
249892
+ cwd: dir,
249893
+ onlyFiles: true,
249894
+ followSymbolicLinks: false
249895
+ });
249896
+ const payloads = {};
249897
+ for (const relativePath of files.sort()) {
249898
+ const name = relativePath.replace(/\.jsonc?$/, "");
249899
+ payloads[name] = await readJsonFile(join28(dir, ...relativePath.split("/")));
249900
+ }
249901
+ return payloads;
249902
+ }
249903
+ async function collectResources(configDir, dirs) {
249904
+ const [entities, agents] = await Promise.all([
249905
+ readRawResources(join28(configDir, dirs.entitiesDir)),
249906
+ readRawResources(join28(configDir, dirs.agentsDir))
249907
+ ]);
249908
+ return { entities, agents };
249909
+ }
249910
+ async function collectArtifacts(target) {
249911
+ const siteWorker = await collectSiteWorker(target.root);
249912
+ return {
249913
+ files: siteWorker ? [] : await collectBuildOutput(requireOutputDir(target), {
249914
+ entryFile: ENTRY2
249915
+ }),
249916
+ ...siteWorker ? { siteWorker } : {},
249917
+ ...await collectResources(target.configDir, target)
249918
+ };
249919
+ }
249920
+ // src/core/version/gate.ts
249921
+ var VERSIONS_API_ENV = "BASE44_VERSIONS_API";
249922
+ function versionsApiEnabled(env = process.env) {
249923
+ const value = env[VERSIONS_API_ENV];
249924
+ return value === "1" || value === "true";
249925
+ }
249926
+ // src/cli/commands/project/build.ts
249927
+ async function buildAction(ctx) {
249928
+ const app = requireApp(ctx);
249929
+ const target = await resolvePublishTarget(app.projectRoot);
249930
+ await runSiteBuild(ctx, {
249931
+ root: target.root,
249932
+ buildCommand: target.buildCommand,
249933
+ appId: app.id
249934
+ });
249935
+ return {
249682
249936
  outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
249683
249937
  };
249684
249938
  }
@@ -249687,11 +249941,11 @@ function getBuildCommand() {
249687
249941
  }
249688
249942
 
249689
249943
  // src/cli/commands/project/create.ts
249690
- import { basename as basename6, resolve as resolve11 } from "node:path";
249944
+ import { basename as basename6, resolve as resolve12 } from "node:path";
249691
249945
  var import_kebabCase = __toESM(require_kebabCase(), 1);
249692
249946
 
249693
249947
  // src/cli/commands/project/scaffold-shared.ts
249694
- import { join as join28 } from "node:path";
249948
+ import { join as join29 } from "node:path";
249695
249949
  var DEFAULT_TEMPLATE_ID = "backend-only";
249696
249950
  async function getTemplateById(templateId) {
249697
249951
  const templates = await listTemplates();
@@ -249754,7 +250008,7 @@ async function completeProjectSetup({
249754
250008
  env: { VITE_BASE44_APP_ID: projectId }
249755
250009
  })`${buildCommand}`;
249756
250010
  updateMessage("Deploying site...");
249757
- return await deploySite(join28(resolvedPath, outputDirectory));
250011
+ return await deploySite(join29(resolvedPath, outputDirectory));
249758
250012
  }, {
249759
250013
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
249760
250014
  errorMessage: "Failed to deploy site"
@@ -249883,7 +250137,7 @@ async function createInteractive(options, ctx) {
249883
250137
  }, ctx);
249884
250138
  }
249885
250139
  async function createNonInteractive(options, ctx) {
249886
- ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
250140
+ ctx.log.info(`Creating a new project at ${resolve12(options.path)}`);
249887
250141
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
249888
250142
  return await executeCreate({
249889
250143
  template,
@@ -249907,7 +250161,7 @@ async function executeCreate({
249907
250161
  }, ctx) {
249908
250162
  const { log, runTask } = ctx;
249909
250163
  const name = rawName.trim();
249910
- const resolvedPath = resolve11(projectPath);
250164
+ const resolvedPath = resolve12(projectPath);
249911
250165
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
249912
250166
  const { projectId } = await runTask("Setting up your project...", async () => {
249913
250167
  return await createProjectFiles({
@@ -250548,7 +250802,7 @@ function getLogsCommand() {
250548
250802
  }
250549
250803
 
250550
250804
  // src/cli/commands/project/scaffold.ts
250551
- import { basename as basename7, resolve as resolve12 } from "node:path";
250805
+ import { basename as basename7, resolve as resolve13 } from "node:path";
250552
250806
  function resolveAppId(options) {
250553
250807
  const appId = options.appId;
250554
250808
  if (!appId) {
@@ -250564,7 +250818,7 @@ function resolveAppId(options) {
250564
250818
  async function scaffoldAction(ctx, name, options, command) {
250565
250819
  const { log, runTask } = ctx;
250566
250820
  const appId = resolveAppId(command.optsWithGlobals());
250567
- const resolvedPath = resolve12("./");
250821
+ const resolvedPath = resolve13("./");
250568
250822
  const projectName = (name ?? basename7(resolvedPath)).trim();
250569
250823
  const template = await getTemplateById("backend-only");
250570
250824
  log.info(`Scaffolding project at ${resolvedPath}`);
@@ -250612,258 +250866,6 @@ function getVisibilityCommand() {
250612
250866
  ])).action(setVisibility);
250613
250867
  }
250614
250868
 
250615
- // src/core/version/schema.ts
250616
- var DeclareVersionResponseSchema = object({
250617
- session_id: string2(),
250618
- uploads: array(object({
250619
- path: string2(),
250620
- url: string2(),
250621
- content_type: string2(),
250622
- content_length: number2(),
250623
- checksum_sha256: string2()
250624
- }))
250625
- }).transform((data) => ({
250626
- sessionId: data.session_id,
250627
- uploads: data.uploads.map((upload) => ({
250628
- path: upload.path,
250629
- url: upload.url,
250630
- contentType: upload.content_type,
250631
- contentLength: upload.content_length,
250632
- checksumSha256: upload.checksum_sha256
250633
- }))
250634
- }));
250635
- var CreateVersionResponseSchema = object({
250636
- version_id: string2(),
250637
- manifest_hash: string2()
250638
- }).transform((data) => ({
250639
- versionId: data.version_id,
250640
- manifestHash: data.manifest_hash
250641
- }));
250642
- var EnvironmentResponseSchema = object({
250643
- name: string2(),
250644
- version_id: string2(),
250645
- manifest_hash: string2(),
250646
- deployment_id: string2()
250647
- }).transform((data) => ({
250648
- name: data.name,
250649
- versionId: data.version_id,
250650
- manifestHash: data.manifest_hash,
250651
- deploymentId: data.deployment_id
250652
- }));
250653
-
250654
- // src/core/version/api.ts
250655
- var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
250656
- var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
250657
- function declaredFile({ path, size, digest }) {
250658
- return { path, size, digest };
250659
- }
250660
- function declaredModule(module) {
250661
- return { ...declaredFile(module), type: module.type };
250662
- }
250663
- function declaredAssetsConfig(config) {
250664
- const stated = {
250665
- html_handling: config?.htmlHandling ?? null,
250666
- not_found_handling: config?.notFoundHandling ?? null,
250667
- run_worker_first: config?.runWorkerFirst ?? null,
250668
- headers: config?.headers ?? null,
250669
- redirects: config?.redirects ?? null
250670
- };
250671
- return Object.values(stated).every((v) => v === null) ? null : stated;
250672
- }
250673
- async function post(path, json, doing) {
250674
- try {
250675
- return await getAppClient().post(path, { json, timeout: 180000 });
250676
- } catch (error) {
250677
- throw await ApiError.fromHttpError(error, doing);
250678
- }
250679
- }
250680
- var KEYED_RETRY = {
250681
- limit: 3,
250682
- methods: ["patch"],
250683
- statusCodes: [408, 500, 502, 503, 504],
250684
- retryOnTimeout: true
250685
- };
250686
- async function patch(path, json, doing, retry) {
250687
- try {
250688
- return await getAppClient().patch(path, {
250689
- json,
250690
- timeout: 180000,
250691
- ...retry ? { retry } : {}
250692
- });
250693
- } catch (error) {
250694
- throw await ApiError.fromHttpError(error, doing);
250695
- }
250696
- }
250697
- function parse10(schema, body, what) {
250698
- const result = schema.safeParse(body);
250699
- if (!result.success) {
250700
- throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
250701
- }
250702
- return result.data;
250703
- }
250704
- async function createVersion(artifacts, options = {}) {
250705
- const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
250706
- static_bundle: artifacts.files.map(declaredFile),
250707
- ...artifacts.siteWorker ? {
250708
- site_worker: {
250709
- main: artifacts.siteWorker.main,
250710
- modules: artifacts.siteWorker.modules.map(declaredModule),
250711
- assets: artifacts.siteWorker.assets.map(declaredFile),
250712
- compatibility_date: artifacts.siteWorker.compatibilityDate,
250713
- compatibility_flags: artifacts.siteWorker.compatibilityFlags,
250714
- assets_config: declaredAssetsConfig(artifacts.siteWorker.assetsConfig)
250715
- }
250716
- } : {},
250717
- entities: artifacts.entities,
250718
- agents: artifacts.agents,
250719
- source_commit: options.sourceCommit
250720
- }, "declaring a version")).json(), "declare");
250721
- const declaredFiles = [
250722
- ...artifacts.files,
250723
- ...artifacts.siteWorker?.modules ?? [],
250724
- ...artifacts.siteWorker?.assets ?? []
250725
- ];
250726
- options.progress?.onDeclared?.({ fileCount: declaredFiles.length });
250727
- if (declared.uploads.length !== declaredFiles.length) {
250728
- throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
250729
- }
250730
- const drifted = declared.uploads.findIndex((upload, index) => upload.path !== declaredFiles[index].path);
250731
- if (drifted !== -1) {
250732
- throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
250733
- }
250734
- let uploadedFiles = 0;
250735
- await pMap(declared.uploads, async (upload, index) => {
250736
- await putPresigned(upload, declaredFiles[index].absolutePath);
250737
- uploadedFiles++;
250738
- options.progress?.onUpload?.({
250739
- uploadedFiles,
250740
- totalFiles: declared.uploads.length
250741
- });
250742
- }, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
250743
- return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
250744
- }
250745
- async function setEnvironmentVersion(environment, versionId, options = {}) {
250746
- return parse10(EnvironmentResponseSchema, await (await patch(`environments/${encodeURIComponent(environment)}`, {
250747
- version_id: versionId,
250748
- ...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
250749
- }, "setting the environment's version", options.idempotencyKey ? KEYED_RETRY : undefined)).json(), "environment");
250750
- }
250751
- // src/core/version/artifacts.ts
250752
- import { createHash as createHash2 } from "node:crypto";
250753
- import { join as join29, resolve as resolve13 } from "node:path";
250754
- var MAX_FILE_COUNT = 50000;
250755
- var HASH_CONCURRENCY = 32;
250756
- var ENTRY2 = "index.html";
250757
- async function digestFile(absolutePath) {
250758
- const hash = await hashFileInto(createHash2("sha256"), absolutePath);
250759
- return `sha256:${hash.digest("hex")}`;
250760
- }
250761
- async function collectBuildOutput(outputDir, options = {}) {
250762
- const found = await describeBuildOutput(outputDir);
250763
- if (found.length > MAX_FILE_COUNT) {
250764
- throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
250765
- }
250766
- if (options.entryFile) {
250767
- if (found.length === 0) {
250768
- throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
250769
- hints: [
250770
- { message: "Run 'base44 build' first", command: "base44 build" }
250771
- ]
250772
- });
250773
- }
250774
- if (!found.some((f) => f.path === options.entryFile)) {
250775
- throw new InvalidInputError(`${outputDir} has no ${options.entryFile}, so nothing could enter the site.`);
250776
- }
250777
- }
250778
- return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
250779
- }
250780
- async function collectSiteWorker(projectRoot) {
250781
- const built = await resolveFullStackBuild(projectRoot);
250782
- if (!built) {
250783
- return null;
250784
- }
250785
- const { config, modules, assetsDir } = built;
250786
- const entry = resolve13(config.configDir, config.main);
250787
- const main = modules.find((m) => m.absolutePath === entry)?.name;
250788
- if (!main) {
250789
- throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
250790
- }
250791
- return {
250792
- main,
250793
- modules: await pMap(modules, async ({ name, absolutePath, size, type }) => ({
250794
- path: name,
250795
- absolutePath,
250796
- size,
250797
- digest: await digestFile(absolutePath),
250798
- type
250799
- }), { concurrency: HASH_CONCURRENCY }),
250800
- assets: assetsDir ? await collectBuildOutput(assetsDir) : [],
250801
- compatibilityDate: config.compatibilityDate,
250802
- compatibilityFlags: config.compatibilityFlags,
250803
- assetsConfig: config.assetsConfig
250804
- };
250805
- }
250806
- async function readRawResources(dir) {
250807
- if (!await pathExists(dir)) {
250808
- return {};
250809
- }
250810
- const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
250811
- cwd: dir,
250812
- onlyFiles: true,
250813
- followSymbolicLinks: false
250814
- });
250815
- const payloads = {};
250816
- for (const relativePath of files.sort()) {
250817
- const name = relativePath.replace(/\.jsonc?$/, "");
250818
- payloads[name] = await readJsonFile(join29(dir, ...relativePath.split("/")));
250819
- }
250820
- return payloads;
250821
- }
250822
- async function collectResources(configDir, dirs) {
250823
- const [entities, agents] = await Promise.all([
250824
- readRawResources(join29(configDir, dirs.entitiesDir)),
250825
- readRawResources(join29(configDir, dirs.agentsDir))
250826
- ]);
250827
- return { entities, agents };
250828
- }
250829
- async function collectArtifacts(target) {
250830
- const siteWorker = await collectSiteWorker(target.root);
250831
- return {
250832
- files: siteWorker ? [] : await collectBuildOutput(requireOutputDir(target), {
250833
- entryFile: ENTRY2
250834
- }),
250835
- ...siteWorker ? { siteWorker } : {},
250836
- ...await collectResources(target.configDir, target)
250837
- };
250838
- }
250839
- // src/core/version/gate.ts
250840
- var VERSIONS_API_ENV = "BASE44_VERSIONS_API";
250841
- function versionsApiEnabled(env = process.env) {
250842
- const value = env[VERSIONS_API_ENV];
250843
- return value === "1" || value === "true";
250844
- }
250845
- // src/core/version/publish.ts
250846
- import { randomUUID as randomUUID4 } from "node:crypto";
250847
- var DEFAULT_ENVIRONMENT = "production";
250848
- async function tagStep2(step, run) {
250849
- return await tagStep(step, run);
250850
- }
250851
- async function publishVersion(artifacts, options = {}) {
250852
- const version = await tagStep2("create_version", () => createVersion(artifacts, {
250853
- sourceCommit: options.sourceCommit,
250854
- concurrency: options.concurrency,
250855
- progress: options.progress
250856
- }));
250857
- const environment = await tagStep2("deploy", () => setEnvironmentVersion(options.target ?? DEFAULT_ENVIRONMENT, version.versionId, {
250858
- idempotencyKey: randomUUID4()
250859
- }));
250860
- return {
250861
- environment: environment.name,
250862
- versionId: environment.versionId,
250863
- manifestHash: environment.manifestHash,
250864
- deploymentId: environment.deploymentId
250865
- };
250866
- }
250867
250869
  // src/cli/commands/versions/options.ts
250868
250870
  function outputDirOption() {
250869
250871
  return new Option2("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)");
@@ -250893,9 +250895,9 @@ function concurrencyOption() {
250893
250895
  async function publishAction(ctx, options) {
250894
250896
  const { runTask, log, jsonMode } = ctx;
250895
250897
  const app = requireApp(ctx);
250896
- const target = await tagStep2("create_version", () => resolveBuildTarget(app.projectRoot, { outputDir: options.outputDir }));
250898
+ const target = await tagStep("create_version", () => resolvePublishTarget(app.projectRoot, { outputDir: options.outputDir }));
250897
250899
  if (options.build !== false) {
250898
- await tagStep2("build", () => runSiteBuild(ctx, {
250900
+ await tagStep("build", () => runSiteBuild(ctx, {
250899
250901
  root: target.root,
250900
250902
  buildCommand: target.buildCommand,
250901
250903
  appId: app.id
@@ -250903,7 +250905,7 @@ async function publishAction(ctx, options) {
250903
250905
  }
250904
250906
  const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
250905
250907
  const result = await runTask("Publishing...", async (updateMessage) => {
250906
- const artifacts = await tagStep2("create_version", () => collectArtifacts(target));
250908
+ const artifacts = await tagStep("create_version", () => collectArtifacts(target));
250907
250909
  return await publishVersion(artifacts, {
250908
250910
  sourceCommit: gitHash,
250909
250911
  target: options.target,
@@ -251637,7 +251639,7 @@ function getTypesCommand() {
251637
251639
  // src/cli/commands/versions/create.ts
251638
251640
  async function createAction2(ctx, options) {
251639
251641
  const { runTask, jsonMode } = ctx;
251640
- const target = await resolveBuildTarget(requireApp(ctx).projectRoot, {
251642
+ const target = await resolvePublishTarget(requireApp(ctx).projectRoot, {
251641
251643
  outputDir: options.outputDir
251642
251644
  });
251643
251645
  const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
@@ -260403,4 +260405,4 @@ export {
260403
260405
  runCLI
260404
260406
  };
260405
260407
 
260406
- //# debugId=4A0444E0B8A1C5CD64756E2164756E21
260408
+ //# debugId=C69AFB00876B9AF264756E2164756E21