@base44-preview/cli 0.0.41-pr.382.5f81bb2 → 0.0.41-pr.383.0ebfd7a

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
@@ -16459,7 +16459,7 @@ var require_lodash = __commonJS((exports, module) => {
16459
16459
  }
16460
16460
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
16461
16461
  });
16462
- function join11(array2, separator) {
16462
+ function join10(array2, separator) {
16463
16463
  return array2 == null ? "" : nativeJoin.call(array2, separator);
16464
16464
  }
16465
16465
  function last(array2) {
@@ -16481,7 +16481,7 @@ var require_lodash = __commonJS((exports, module) => {
16481
16481
  function nth(array2, n2) {
16482
16482
  return array2 && array2.length ? baseNth(array2, toInteger(n2)) : undefined2;
16483
16483
  }
16484
- var pull2 = baseRest(pullAll);
16484
+ var pull = baseRest(pullAll);
16485
16485
  function pullAll(array2, values2) {
16486
16486
  return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2) : array2;
16487
16487
  }
@@ -18246,7 +18246,7 @@ __p += '`;
18246
18246
  lodash.pickBy = pickBy;
18247
18247
  lodash.property = property;
18248
18248
  lodash.propertyOf = propertyOf;
18249
- lodash.pull = pull2;
18249
+ lodash.pull = pull;
18250
18250
  lodash.pullAll = pullAll;
18251
18251
  lodash.pullAllBy = pullAllBy;
18252
18252
  lodash.pullAllWith = pullAllWith;
@@ -18391,7 +18391,7 @@ __p += '`;
18391
18391
  lodash.isUndefined = isUndefined;
18392
18392
  lodash.isWeakMap = isWeakMap;
18393
18393
  lodash.isWeakSet = isWeakSet;
18394
- lodash.join = join11;
18394
+ lodash.join = join10;
18395
18395
  lodash.kebabCase = kebabCase;
18396
18396
  lodash.last = last;
18397
18397
  lodash.lastIndexOf = lastIndexOf;
@@ -27503,7 +27503,7 @@ function cleanDoc(doc2) {
27503
27503
  return mapDoc(doc2, (currentDoc) => cleanDocFn(currentDoc));
27504
27504
  }
27505
27505
  function replaceEndOfLine(doc2, replacement = literalline) {
27506
- return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ? join15(replacement, currentDoc.split(`
27506
+ return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ? join13(replacement, currentDoc.split(`
27507
27507
  `)) : currentDoc);
27508
27508
  }
27509
27509
  function canBreakFn(doc2) {
@@ -27583,7 +27583,7 @@ function indentIfBreak(contents, options) {
27583
27583
  negate: options.negate
27584
27584
  };
27585
27585
  }
27586
- function join15(separator, docs) {
27586
+ function join13(separator, docs) {
27587
27587
  assertDoc(separator);
27588
27588
  assertDocArray(docs);
27589
27589
  const parts = [];
@@ -28294,7 +28294,7 @@ var init_doc = __esm(() => {
28294
28294
  MODE_FLAT = Symbol("MODE_FLAT");
28295
28295
  DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
28296
28296
  builders = {
28297
- join: join15,
28297
+ join: join13,
28298
28298
  line,
28299
28299
  softline,
28300
28300
  hardline,
@@ -133208,7 +133208,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
133208
133208
  return mapDoc2(doc2, (currentDoc) => cleanDocFn2(currentDoc));
133209
133209
  }
133210
133210
  function replaceEndOfLine2(doc2, replacement = literalline2) {
133211
- return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ? join17(replacement, currentDoc.split(`
133211
+ return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ? join15(replacement, currentDoc.split(`
133212
133212
  `)) : currentDoc);
133213
133213
  }
133214
133214
  function canBreakFn2(doc2) {
@@ -133294,7 +133294,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
133294
133294
  negate: options8.negate
133295
133295
  };
133296
133296
  }
133297
- function join17(separator, docs) {
133297
+ function join15(separator, docs) {
133298
133298
  assertDoc2(separator);
133299
133299
  assertDocArray2(docs);
133300
133300
  const parts = [];
@@ -133959,7 +133959,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
133959
133959
  }
133960
133960
  }
133961
133961
  var builders2 = {
133962
- join: join17,
133962
+ join: join15,
133963
133963
  line: line3,
133964
133964
  softline: softline2,
133965
133965
  hardline: hardline4,
@@ -160399,10 +160399,10 @@ var require_view = __commonJS((exports, module) => {
160399
160399
  var debug = require_src4()("express:view");
160400
160400
  var path18 = __require("node:path");
160401
160401
  var fs28 = __require("node:fs");
160402
- var dirname12 = path18.dirname;
160402
+ var dirname11 = path18.dirname;
160403
160403
  var basename4 = path18.basename;
160404
160404
  var extname2 = path18.extname;
160405
- var join18 = path18.join;
160405
+ var join16 = path18.join;
160406
160406
  var resolve6 = path18.resolve;
160407
160407
  module.exports = View;
160408
160408
  function View(name2, options8) {
@@ -160438,7 +160438,7 @@ var require_view = __commonJS((exports, module) => {
160438
160438
  for (var i5 = 0;i5 < roots.length && !path19; i5++) {
160439
160439
  var root2 = roots[i5];
160440
160440
  var loc = resolve6(root2, name2);
160441
- var dir = dirname12(loc);
160441
+ var dir = dirname11(loc);
160442
160442
  var file2 = basename4(loc);
160443
160443
  path19 = this.resolve(dir, file2);
160444
160444
  }
@@ -160464,12 +160464,12 @@ var require_view = __commonJS((exports, module) => {
160464
160464
  };
160465
160465
  View.prototype.resolve = function resolve7(dir, file2) {
160466
160466
  var ext = this.ext;
160467
- var path19 = join18(dir, file2);
160467
+ var path19 = join16(dir, file2);
160468
160468
  var stat2 = tryStat(path19);
160469
160469
  if (stat2 && stat2.isFile()) {
160470
160470
  return path19;
160471
160471
  }
160472
- path19 = join18(dir, basename4(file2, ext), "index" + ext);
160472
+ path19 = join16(dir, basename4(file2, ext), "index" + ext);
160473
160473
  stat2 = tryStat(path19);
160474
160474
  if (stat2 && stat2.isFile()) {
160475
160475
  return path19;
@@ -164164,7 +164164,7 @@ var require_send = __commonJS((exports, module) => {
164164
164164
  var Stream2 = __require("stream");
164165
164165
  var util2 = __require("util");
164166
164166
  var extname2 = path18.extname;
164167
- var join18 = path18.join;
164167
+ var join16 = path18.join;
164168
164168
  var normalize = path18.normalize;
164169
164169
  var resolve6 = path18.resolve;
164170
164170
  var sep = path18.sep;
@@ -164336,7 +164336,7 @@ var require_send = __commonJS((exports, module) => {
164336
164336
  return res;
164337
164337
  }
164338
164338
  parts = path19.split(sep);
164339
- path19 = normalize(join18(root2, path19));
164339
+ path19 = normalize(join16(root2, path19));
164340
164340
  } else {
164341
164341
  if (UP_PATH_REGEXP.test(path19)) {
164342
164342
  debug('malicious path "%s"', path19);
@@ -164476,7 +164476,7 @@ var require_send = __commonJS((exports, module) => {
164476
164476
  return self2.onStatError(err);
164477
164477
  return self2.error(404);
164478
164478
  }
164479
- var p4 = join18(path19, self2._index[i5]);
164479
+ var p4 = join16(path19, self2._index[i5]);
164480
164480
  debug('stat "%s"', p4);
164481
164481
  fs28.stat(p4, function(err2, stat2) {
164482
164482
  if (err2)
@@ -211071,7 +211071,7 @@ var require_buffer_list = __commonJS((exports, module) => {
211071
211071
  }
211072
211072
  }, {
211073
211073
  key: "join",
211074
- value: function join18(s5) {
211074
+ value: function join16(s5) {
211075
211075
  if (this.length === 0)
211076
211076
  return "";
211077
211077
  var p4 = this.head;
@@ -214782,7 +214782,7 @@ var require_dist5 = __commonJS((exports, module) => {
214782
214782
  });
214783
214783
 
214784
214784
  // src/cli/index.ts
214785
- import { dirname as dirname16, join as join21 } from "node:path";
214785
+ import { dirname as dirname15, join as join19 } from "node:path";
214786
214786
  import { fileURLToPath as fileURLToPath6 } from "node:url";
214787
214787
 
214788
214788
  // ../../node_modules/commander/esm.mjs
@@ -214802,7 +214802,7 @@ var {
214802
214802
  } = import__.default;
214803
214803
 
214804
214804
  // src/cli/commands/agents/pull.ts
214805
- import { dirname as dirname7, join as join11 } from "node:path";
214805
+ import { dirname as dirname7, join as join10 } from "node:path";
214806
214806
 
214807
214807
  // ../../node_modules/@clack/core/dist/index.mjs
214808
214808
  var import_picocolors = __toESM(require_picocolors(), 1);
@@ -237298,7 +237298,7 @@ var generateGlobTasks = normalizeArguments(generateTasks);
237298
237298
  var generateGlobTasksSync = normalizeArgumentsSync(generateTasksSync);
237299
237299
 
237300
237300
  // src/core/project/config.ts
237301
- import { dirname as dirname5, join as join7 } from "node:path";
237301
+ import { dirname as dirname5, join as join6 } from "node:path";
237302
237302
 
237303
237303
  // src/core/resources/agent/schema.ts
237304
237304
  var EntityOperationSchema = exports_external.enum(["create", "update", "delete", "read"]);
@@ -238075,27 +238075,15 @@ var BackendFunctionSchema = FunctionConfigSchema.extend({
238075
238075
  entryPath: exports_external.string().min(1, "Entry path cannot be empty"),
238076
238076
  filePaths: exports_external.array(exports_external.string()).min(1, "Function must have at least one file")
238077
238077
  });
238078
- var DeployFunctionsResponseSchema = exports_external.object({
238079
- deployed: exports_external.array(exports_external.string()),
238080
- deleted: exports_external.array(exports_external.string()),
238081
- skipped: exports_external.array(exports_external.string()).optional().nullable(),
238082
- errors: exports_external.array(exports_external.object({ name: exports_external.string(), message: exports_external.string() })).nullable()
238078
+ var DeploySingleFunctionResponseSchema = exports_external.object({
238079
+ status: exports_external.enum(["deployed", "unchanged"])
238083
238080
  });
238084
- var FunctionAutomationInfoSchema = exports_external.object({
238085
- name: exports_external.string(),
238086
- type: exports_external.string(),
238087
- is_active: exports_external.boolean()
238088
- }).transform((data) => ({
238089
- name: data.name,
238090
- type: data.type,
238091
- isActive: data.is_active
238092
- }));
238093
238081
  var FunctionInfoSchema = exports_external.object({
238094
238082
  name: exports_external.string(),
238095
238083
  deployment_id: exports_external.string(),
238096
238084
  entry: exports_external.string(),
238097
238085
  files: exports_external.array(FunctionFileSchema),
238098
- automations: exports_external.array(FunctionAutomationInfoSchema)
238086
+ automations: exports_external.array(AutomationSchema)
238099
238087
  }).transform((data) => ({
238100
238088
  name: data.name,
238101
238089
  deploymentId: data.deployment_id,
@@ -238115,29 +238103,39 @@ var FunctionLogEntrySchema = exports_external.object({
238115
238103
  var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
238116
238104
 
238117
238105
  // src/core/resources/function/api.ts
238118
- function toDeployPayloadItem(fn) {
238119
- return {
238120
- name: fn.name,
238121
- entry: fn.entry,
238122
- files: fn.files,
238123
- automations: fn.automations
238124
- };
238125
- }
238126
- async function deployFunctions(functions) {
238106
+ async function deploySingleFunction(name2, payload) {
238127
238107
  const appClient = getAppClient();
238128
- const payload = {
238129
- functions: functions.map(toDeployPayloadItem)
238130
- };
238131
238108
  let response;
238132
238109
  try {
238133
- response = await appClient.put("backend-functions", {
238134
- json: payload,
238135
- timeout: false
238110
+ response = await appClient.put(`backend-functions/${encodeURIComponent(name2)}`, { json: payload, timeout: false });
238111
+ } catch (error48) {
238112
+ throw await ApiError.fromHttpError(error48, `deploying function "${name2}"`);
238113
+ }
238114
+ const result = DeploySingleFunctionResponseSchema.safeParse(await response.json());
238115
+ if (!result.success) {
238116
+ throw new SchemaValidationError("Invalid response from server", result.error);
238117
+ }
238118
+ return result.data;
238119
+ }
238120
+ async function deleteSingleFunction(name2) {
238121
+ const appClient = getAppClient();
238122
+ try {
238123
+ await appClient.delete(`backend-functions/${encodeURIComponent(name2)}`, {
238124
+ timeout: 60000
238136
238125
  });
238137
238126
  } catch (error48) {
238138
- throw await ApiError.fromHttpError(error48, "deploying functions");
238127
+ throw await ApiError.fromHttpError(error48, `deleting function "${name2}"`);
238139
238128
  }
238140
- const result = DeployFunctionsResponseSchema.safeParse(await response.json());
238129
+ }
238130
+ async function listDeployedFunctions() {
238131
+ const appClient = getAppClient();
238132
+ let response;
238133
+ try {
238134
+ response = await appClient.get("backend-functions", { timeout: 30000 });
238135
+ } catch (error48) {
238136
+ throw await ApiError.fromHttpError(error48, "listing deployed functions");
238137
+ }
238138
+ const result = ListFunctionsResponseSchema.safeParse(await response.json());
238141
238139
  if (!result.success) {
238142
238140
  throw new SchemaValidationError("Invalid response from server", result.error);
238143
238141
  }
@@ -238179,20 +238177,6 @@ async function fetchFunctionLogs(functionName, filters = {}) {
238179
238177
  }
238180
238178
  return result.data;
238181
238179
  }
238182
- async function listDeployedFunctions() {
238183
- const appClient = getAppClient();
238184
- let response;
238185
- try {
238186
- response = await appClient.get("backend-functions", { timeout: 30000 });
238187
- } catch (error48) {
238188
- throw await ApiError.fromHttpError(error48, "listing deployed functions");
238189
- }
238190
- const result = ListFunctionsResponseSchema.safeParse(await response.json());
238191
- if (!result.success) {
238192
- throw new SchemaValidationError("Invalid response from server", result.error);
238193
- }
238194
- return result.data;
238195
- }
238196
238180
  // src/core/resources/function/config.ts
238197
238181
  import { basename as basename2, dirname as dirname3, join as join5, relative } from "node:path";
238198
238182
  async function readFunctionConfig(configPath) {
@@ -238274,85 +238258,70 @@ async function readAllFunctions(functionsDir) {
238274
238258
  import { dirname as dirname4, relative as relative2 } from "node:path";
238275
238259
  async function loadFunctionCode(fn) {
238276
238260
  const functionDir = dirname4(fn.entryPath);
238277
- const loadedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238261
+ const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238278
238262
  const content = await readTextFile(filePath);
238279
238263
  const path11 = relative2(functionDir, filePath).split(/[/\\]/).join("/");
238280
238264
  return { path: path11, content };
238281
238265
  }));
238282
- return { ...fn, files: loadedFiles };
238283
- }
238284
- async function pushFunctions(functions) {
238285
- if (functions.length === 0) {
238286
- return { deployed: [], deleted: [], skipped: [], errors: null };
238287
- }
238288
- const functionsWithCode = await Promise.all(functions.map(loadFunctionCode));
238289
- return deployFunctions(functionsWithCode);
238266
+ return { ...fn, files: resolvedFiles };
238290
238267
  }
238291
- // src/core/resources/function/pull.ts
238292
- import { join as join6 } from "node:path";
238293
- async function writeFunctions(functionsDir, functions) {
238294
- const written = [];
238295
- const skipped = [];
238296
- for (const fn of functions) {
238297
- const functionDir = join6(functionsDir, fn.name);
238298
- const configPath = join6(functionDir, "function.jsonc");
238299
- if (await isFunctionUnchanged(functionDir, fn)) {
238300
- skipped.push(fn.name);
238301
- continue;
238302
- }
238303
- const config5 = {
238268
+ async function deployOne(fn) {
238269
+ const start = Date.now();
238270
+ try {
238271
+ const functionWithCode = await loadFunctionCode(fn);
238272
+ const response = await deploySingleFunction(functionWithCode.name, {
238273
+ entry: functionWithCode.entry,
238274
+ files: functionWithCode.files,
238275
+ automations: functionWithCode.automations
238276
+ });
238277
+ return {
238278
+ name: functionWithCode.name,
238279
+ status: response.status,
238280
+ durationMs: Date.now() - start
238281
+ };
238282
+ } catch (error48) {
238283
+ return {
238304
238284
  name: fn.name,
238305
- entry: fn.entry
238285
+ status: "error",
238286
+ error: error48 instanceof Error ? error48.message : String(error48)
238306
238287
  };
238307
- if (fn.automations.length > 0) {
238308
- config5.automations = fn.automations;
238309
- }
238310
- await writeJsonFile(configPath, config5);
238311
- for (const file2 of fn.files) {
238312
- await writeFile(join6(functionDir, file2.path), file2.content);
238313
- }
238314
- written.push(fn.name);
238315
238288
  }
238316
- return { written, skipped };
238317
238289
  }
238318
- async function isFunctionUnchanged(functionDir, fn) {
238319
- if (!await pathExists(functionDir)) {
238320
- return false;
238321
- }
238322
- const configPath = join6(functionDir, "function.jsonc");
238323
- try {
238324
- const localConfig = await readJsonFile(configPath);
238325
- if (localConfig.entry !== fn.entry) {
238326
- return false;
238327
- }
238328
- const localAuto = JSON.stringify(localConfig.automations ?? []);
238329
- const remoteAuto = JSON.stringify(fn.automations);
238330
- if (localAuto !== remoteAuto) {
238331
- return false;
238332
- }
238333
- } catch {
238334
- return false;
238290
+ async function deployFunctionsSequentially(functions, options) {
238291
+ if (functions.length === 0)
238292
+ return [];
238293
+ const results = [];
238294
+ for (const fn of functions) {
238295
+ options?.onStart?.([fn.name]);
238296
+ const result = await deployOne(fn);
238297
+ results.push(result);
238298
+ options?.onResult?.(result);
238335
238299
  }
238336
- for (const file2 of fn.files) {
238337
- const filePath = join6(functionDir, file2.path);
238338
- if (!await pathExists(filePath)) {
238339
- return false;
238340
- }
238300
+ return results;
238301
+ }
238302
+ async function pruneRemovedFunctions(localFunctionNames) {
238303
+ const remote = await listDeployedFunctions();
238304
+ const localSet = new Set(localFunctionNames);
238305
+ const toDelete = remote.functions.filter((f) => !localSet.has(f.name));
238306
+ const results = [];
238307
+ for (const fn of toDelete) {
238341
238308
  try {
238342
- const localContent = await readTextFile(filePath);
238343
- if (localContent !== file2.content) {
238344
- return false;
238345
- }
238346
- } catch {
238347
- return false;
238309
+ await deleteSingleFunction(fn.name);
238310
+ results.push({ name: fn.name, deleted: true });
238311
+ } catch (error48) {
238312
+ results.push({
238313
+ name: fn.name,
238314
+ deleted: false,
238315
+ error: error48 instanceof Error ? error48.message : String(error48)
238316
+ });
238348
238317
  }
238349
238318
  }
238350
- return true;
238319
+ return results;
238351
238320
  }
238352
238321
  // src/core/resources/function/resource.ts
238353
238322
  var functionResource = {
238354
238323
  readAll: readAllFunctions,
238355
- push: pushFunctions
238324
+ push: (functions) => deployFunctionsSequentially(functions)
238356
238325
  };
238357
238326
  // src/core/project/config.ts
238358
238327
  async function findConfigInDir(dir) {
@@ -238393,10 +238362,10 @@ async function readProjectConfig(projectRoot) {
238393
238362
  const project = result.data;
238394
238363
  const configDir = dirname5(configPath);
238395
238364
  const [entities, functions, agents, connectors] = await Promise.all([
238396
- entityResource.readAll(join7(configDir, project.entitiesDir)),
238397
- functionResource.readAll(join7(configDir, project.functionsDir)),
238398
- agentResource.readAll(join7(configDir, project.agentsDir)),
238399
- connectorResource.readAll(join7(configDir, project.connectorsDir))
238365
+ entityResource.readAll(join6(configDir, project.entitiesDir)),
238366
+ functionResource.readAll(join6(configDir, project.functionsDir)),
238367
+ agentResource.readAll(join6(configDir, project.agentsDir)),
238368
+ connectorResource.readAll(join6(configDir, project.connectorsDir))
238400
238369
  ]);
238401
238370
  return {
238402
238371
  project: { ...project, root, configPath },
@@ -238493,12 +238462,12 @@ async function readAppConfig(projectRoot) {
238493
238462
  // src/core/project/template.ts
238494
238463
  var import_ejs = __toESM(require_ejs(), 1);
238495
238464
  var import_front_matter = __toESM(require_front_matter(), 1);
238496
- import { dirname as dirname6, join as join9 } from "node:path";
238465
+ import { dirname as dirname6, join as join8 } from "node:path";
238497
238466
 
238498
238467
  // src/core/assets.ts
238499
238468
  import { cpSync, existsSync } from "node:fs";
238500
238469
  import { homedir as homedir2 } from "node:os";
238501
- import { join as join8 } from "node:path";
238470
+ import { join as join7 } from "node:path";
238502
238471
  // package.json
238503
238472
  var package_default = {
238504
238473
  name: "base44",
@@ -238591,15 +238560,15 @@ var package_default = {
238591
238560
  };
238592
238561
 
238593
238562
  // src/core/assets.ts
238594
- var ASSETS_DIR = join8(homedir2(), ".base44", "assets", package_default.version);
238563
+ var ASSETS_DIR = join7(homedir2(), ".base44", "assets", package_default.version);
238595
238564
  function getTemplatesDir() {
238596
- return join8(ASSETS_DIR, "templates");
238565
+ return join7(ASSETS_DIR, "templates");
238597
238566
  }
238598
238567
  function getTemplatesIndexPath() {
238599
- return join8(ASSETS_DIR, "templates", "templates.json");
238568
+ return join7(ASSETS_DIR, "templates", "templates.json");
238600
238569
  }
238601
238570
  function getDenoWrapperPath() {
238602
- return join8(ASSETS_DIR, "deno-runtime", "main.js");
238571
+ return join7(ASSETS_DIR, "deno-runtime", "main.js");
238603
238572
  }
238604
238573
  function ensureNpmAssets(sourceDir) {
238605
238574
  if (existsSync(ASSETS_DIR))
@@ -238620,23 +238589,23 @@ async function listTemplates() {
238620
238589
  return result.data.templates;
238621
238590
  }
238622
238591
  async function renderTemplate(template, destPath, data) {
238623
- const templateDir = join9(getTemplatesDir(), template.path);
238592
+ const templateDir = join8(getTemplatesDir(), template.path);
238624
238593
  const files = await globby("**/*", {
238625
238594
  cwd: templateDir,
238626
238595
  dot: true,
238627
238596
  onlyFiles: true
238628
238597
  });
238629
238598
  for (const file2 of files) {
238630
- const srcPath = join9(templateDir, file2);
238599
+ const srcPath = join8(templateDir, file2);
238631
238600
  try {
238632
238601
  if (file2.endsWith(".ejs")) {
238633
238602
  const rendered = await import_ejs.default.renderFile(srcPath, data);
238634
238603
  const { attributes, body } = import_front_matter.default(rendered);
238635
- const destFile = attributes.outputFileName ? join9(dirname6(file2), attributes.outputFileName) : file2.replace(/\.ejs$/, "");
238636
- const destFilePath = join9(destPath, destFile);
238604
+ const destFile = attributes.outputFileName ? join8(dirname6(file2), attributes.outputFileName) : file2.replace(/\.ejs$/, "");
238605
+ const destFilePath = join8(destPath, destFile);
238637
238606
  await writeFile(destFilePath, body);
238638
238607
  } else {
238639
- const destFilePath = join9(destPath, file2);
238608
+ const destFilePath = join8(destPath, file2);
238640
238609
  await copyFile(srcPath, destFilePath);
238641
238610
  }
238642
238611
  } catch (error48) {
@@ -238735,7 +238704,7 @@ async function getSiteFilePaths(outputDir) {
238735
238704
  // src/core/site/deploy.ts
238736
238705
  import { randomUUID } from "node:crypto";
238737
238706
  import { tmpdir } from "node:os";
238738
- import { join as join10 } from "node:path";
238707
+ import { join as join9 } from "node:path";
238739
238708
  async function deploySite(siteOutputDir) {
238740
238709
  if (!await pathExists(siteOutputDir)) {
238741
238710
  throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
@@ -238752,7 +238721,7 @@ async function deploySite(siteOutputDir) {
238752
238721
  ]
238753
238722
  });
238754
238723
  }
238755
- const archivePath = join10(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
238724
+ const archivePath = join9(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
238756
238725
  try {
238757
238726
  await createArchive(siteOutputDir, archivePath);
238758
238727
  return await uploadSite(archivePath);
@@ -246504,7 +246473,7 @@ function formatYaml(data, options = {}) {
246504
246473
  async function pullAgentsAction() {
246505
246474
  const { project: project2 } = await readProjectConfig();
246506
246475
  const configDir = dirname7(project2.configPath);
246507
- const agentsDir = join11(configDir, project2.agentsDir);
246476
+ const agentsDir = join10(configDir, project2.agentsDir);
246508
246477
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
246509
246478
  return await fetchAgents();
246510
246479
  }, {
@@ -246626,11 +246595,11 @@ function getConnectorsListAvailableCommand(context) {
246626
246595
  }
246627
246596
 
246628
246597
  // src/cli/commands/connectors/pull.ts
246629
- import { dirname as dirname8, join as join12 } from "node:path";
246598
+ import { dirname as dirname8, join as join11 } from "node:path";
246630
246599
  async function pullConnectorsAction() {
246631
246600
  const { project: project2 } = await readProjectConfig();
246632
246601
  const configDir = dirname8(project2.configPath);
246633
- const connectorsDir = join12(configDir, project2.connectorsDir);
246602
+ const connectorsDir = join11(configDir, project2.connectorsDir);
246634
246603
  const remoteConnectors = await runTask("Fetching connectors from Base44", async () => {
246635
246604
  return await listConnectors();
246636
246605
  }, {
@@ -247478,95 +247447,132 @@ function getEntitiesPushCommand(context) {
247478
247447
  }));
247479
247448
  }
247480
247449
 
247450
+ // src/cli/commands/functions/formatDeployResult.ts
247451
+ function formatDuration(ms) {
247452
+ return `${(ms / 1000).toFixed(1)}s`;
247453
+ }
247454
+ function formatDeployResult(result) {
247455
+ const label = result.name.padEnd(25);
247456
+ if (result.status === "deployed") {
247457
+ const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
247458
+ R2.success(`${label} deployed${timing}`);
247459
+ } else if (result.status === "unchanged") {
247460
+ R2.success(`${label} unchanged`);
247461
+ } else {
247462
+ R2.error(`${label} error: ${result.error}`);
247463
+ }
247464
+ }
247465
+
247466
+ // src/cli/commands/functions/parseNames.ts
247467
+ function parseNames(args) {
247468
+ return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
247469
+ }
247470
+
247481
247471
  // src/cli/commands/functions/deploy.ts
247482
- async function deployFunctionsAction() {
247472
+ function resolveFunctionsToDeploy(names, allFunctions) {
247473
+ if (names.length === 0)
247474
+ return allFunctions;
247475
+ const notFound = names.filter((n2) => !allFunctions.some((f) => f.name === n2));
247476
+ if (notFound.length > 0) {
247477
+ throw new InvalidInputError(`Function${notFound.length > 1 ? "s" : ""} not found in project: ${notFound.join(", ")}`);
247478
+ }
247479
+ return allFunctions.filter((f) => names.includes(f.name));
247480
+ }
247481
+ function formatPruneResults(pruneResults) {
247482
+ for (const pruneResult of pruneResults) {
247483
+ if (pruneResult.deleted) {
247484
+ R2.success(`${pruneResult.name.padEnd(25)} deleted`);
247485
+ } else {
247486
+ R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
247487
+ }
247488
+ }
247489
+ if (pruneResults.length > 0) {
247490
+ const pruned = pruneResults.filter((r) => r.deleted).length;
247491
+ R2.info(`${pruned} function${pruned !== 1 ? "s" : ""} removed`);
247492
+ }
247493
+ }
247494
+ function buildDeploySummary(results) {
247495
+ const deployed = results.filter((r) => r.status === "deployed").length;
247496
+ const unchanged = results.filter((r) => r.status === "unchanged").length;
247497
+ const failed = results.filter((r) => r.status === "error").length;
247498
+ const parts = [];
247499
+ if (deployed > 0)
247500
+ parts.push(`${deployed} deployed`);
247501
+ if (unchanged > 0)
247502
+ parts.push(`${unchanged} unchanged`);
247503
+ if (failed > 0)
247504
+ parts.push(`${failed} error${failed !== 1 ? "s" : ""}`);
247505
+ return parts.join(", ") || "No functions deployed";
247506
+ }
247507
+ async function deployFunctionsAction(names, options) {
247508
+ if (options.force && names.length > 0) {
247509
+ throw new InvalidInputError("--force cannot be used when specifying function names");
247510
+ }
247483
247511
  const { functions } = await readProjectConfig();
247484
- if (functions.length === 0) {
247512
+ const toDeploy = resolveFunctionsToDeploy(names, functions);
247513
+ if (toDeploy.length === 0) {
247485
247514
  return {
247486
247515
  outroMessage: "No functions found. Create functions in the 'functions' directory."
247487
247516
  };
247488
247517
  }
247489
- R2.info(`Found ${functions.length} ${functions.length === 1 ? "function" : "functions"} to deploy`);
247490
- const result = await runTask("Deploying functions to Base44", async () => {
247491
- return await pushFunctions(functions);
247492
- }, {
247493
- successMessage: "Functions deployed successfully",
247494
- errorMessage: "Failed to deploy functions"
247518
+ R2.info(`Found ${toDeploy.length} ${toDeploy.length === 1 ? "function" : "functions"} to deploy`);
247519
+ let completed = 0;
247520
+ const total = toDeploy.length;
247521
+ const results = await deployFunctionsSequentially(toDeploy, {
247522
+ onStart: (startNames) => {
247523
+ const label = startNames.length === 1 ? startNames[0] : `${startNames.length} functions`;
247524
+ R2.step(theme.styles.dim(`[${completed + 1}/${total}] Deploying ${label}...`));
247525
+ },
247526
+ onResult: (result) => {
247527
+ completed++;
247528
+ formatDeployResult(result);
247529
+ }
247495
247530
  });
247496
- if (result.deployed.length > 0) {
247497
- R2.success(`Deployed: ${result.deployed.join(", ")}`);
247498
- }
247499
- if (result.deleted.length > 0) {
247500
- R2.warn(`Deleted: ${result.deleted.join(", ")}`);
247531
+ if (options.force) {
247532
+ R2.info("Removing remote functions not found locally...");
247533
+ const allLocalNames = functions.map((f) => f.name);
247534
+ const pruneResults = await pruneRemovedFunctions(allLocalNames);
247535
+ formatPruneResults(pruneResults);
247501
247536
  }
247502
- if (result.errors && result.errors.length > 0) {
247503
- throw new ApiError("Function deployment errors", {
247504
- details: result.errors.map((e2) => `'${e2.name}': ${e2.message}`),
247505
- hints: [
247506
- { message: "Check the function code for syntax errors" },
247507
- { message: "Ensure all imports are valid" }
247508
- ]
247509
- });
247510
- }
247511
- return { outroMessage: "Functions deployed to Base44" };
247537
+ return { outroMessage: buildDeploySummary(results) };
247512
247538
  }
247513
247539
  function getDeployCommand(context) {
247514
- return new Command("deploy").description("Deploy local functions to Base44").action(async () => {
247515
- await runCommand(deployFunctionsAction, { requireAuth: true }, context);
247540
+ return new Command("deploy").description("Deploy functions to Base44").argument("[names...]", "Function names to deploy (deploys all if omitted)").option("--force", "Delete remote functions not found locally").action(async (rawNames, options) => {
247541
+ await runCommand(() => {
247542
+ const names = parseNames(rawNames);
247543
+ return deployFunctionsAction(names, options);
247544
+ }, { requireAuth: true }, context);
247516
247545
  });
247517
247546
  }
247518
247547
 
247519
- // src/cli/commands/functions/pull.ts
247520
- import { dirname as dirname9, join as join13 } from "node:path";
247521
- async function pullFunctionsAction(name2) {
247522
- const { project: project2 } = await readProjectConfig();
247523
- const configDir = dirname9(project2.configPath);
247524
- const functionsDir = join13(configDir, project2.functionsDir);
247525
- const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
247526
- const { functions } = await listDeployedFunctions();
247527
- return functions;
247528
- }, {
247529
- successMessage: "Functions fetched successfully",
247530
- errorMessage: "Failed to fetch functions"
247531
- });
247532
- const toPull = name2 ? remoteFunctions.filter((f) => f.name === name2) : remoteFunctions;
247533
- if (name2 && toPull.length === 0) {
247534
- return {
247535
- outroMessage: `Function "${name2}" not found on remote`
247536
- };
247537
- }
247538
- if (toPull.length === 0) {
247539
- return { outroMessage: "No functions found on remote" };
247540
- }
247541
- const { written, skipped } = await runTask("Writing function files", async () => {
247542
- return await writeFunctions(functionsDir, toPull);
247543
- }, {
247544
- successMessage: "Function files written successfully",
247545
- errorMessage: "Failed to write function files"
247546
- });
247547
- for (const name3 of written) {
247548
- R2.success(`${name3.padEnd(25)} written`);
247548
+ // src/cli/commands/functions/list.ts
247549
+ async function listFunctionsAction() {
247550
+ const { functions } = await runTask("Fetching functions...", async () => listDeployedFunctions(), { errorMessage: "Failed to fetch functions" });
247551
+ if (functions.length === 0) {
247552
+ return { outroMessage: "No functions on remote" };
247549
247553
  }
247550
- for (const name3 of skipped) {
247551
- R2.info(`${name3.padEnd(25)} unchanged`);
247554
+ for (const fn of functions) {
247555
+ const automationCount = fn.automations.length;
247556
+ const automationLabel = automationCount > 0 ? theme.styles.dim(` (${automationCount} automation${automationCount > 1 ? "s" : ""})`) : "";
247557
+ R2.message(` ${fn.name}${automationLabel}`);
247552
247558
  }
247553
247559
  return {
247554
- outroMessage: `Pulled ${toPull.length} function${toPull.length !== 1 ? "s" : ""} to ${functionsDir}`
247560
+ outroMessage: `${functions.length} function${functions.length !== 1 ? "s" : ""} on remote`
247555
247561
  };
247556
247562
  }
247557
- function getPullCommand(context) {
247558
- return new Command("pull").description("Pull deployed functions from Base44").argument("[name]", "Pull a single function by name").action(async (name2) => {
247559
- await runCommand(() => pullFunctionsAction(name2), { requireAuth: true }, context);
247563
+ function getListCommand(context) {
247564
+ return new Command("list").description("List all deployed functions").action(async () => {
247565
+ await runCommand(listFunctionsAction, { requireAuth: true }, context);
247560
247566
  });
247561
247567
  }
247562
247568
 
247563
247569
  // src/cli/commands/functions/index.ts
247564
247570
  function getFunctionsCommand(context) {
247565
- return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand(context)).addCommand(getPullCommand(context));
247571
+ return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand(context)).addCommand(getListCommand(context));
247566
247572
  }
247567
247573
 
247568
247574
  // src/cli/commands/project/create.ts
247569
- import { basename as basename3, join as join14, resolve as resolve2 } from "node:path";
247575
+ import { basename as basename3, join as join12, resolve as resolve2 } from "node:path";
247570
247576
  var import_kebabCase = __toESM(require_kebabCase(), 1);
247571
247577
  var DEFAULT_TEMPLATE_ID = "backend-only";
247572
247578
  async function getTemplateById(templateId) {
@@ -247702,7 +247708,7 @@ async function executeCreate({
247702
247708
  updateMessage("Building project...");
247703
247709
  await execa({ cwd: resolvedPath, shell: true })`${buildCommand}`;
247704
247710
  updateMessage("Deploying site...");
247705
- return await deploySite(join14(resolvedPath, outputDirectory));
247711
+ return await deploySite(join12(resolvedPath, outputDirectory));
247706
247712
  }, {
247707
247713
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
247708
247714
  errorMessage: "Failed to deploy site"
@@ -248330,10 +248336,10 @@ function toPascalCase(name2) {
248330
248336
  return name2.split(/[-_\s]+/).map((w8) => w8.charAt(0).toUpperCase() + w8.slice(1)).join("");
248331
248337
  }
248332
248338
  // src/core/types/update-project.ts
248333
- import { join as join17 } from "node:path";
248339
+ import { join as join15 } from "node:path";
248334
248340
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
248335
248341
  async function updateProjectConfig(projectRoot) {
248336
- const tsconfigPath = join17(projectRoot, "tsconfig.json");
248342
+ const tsconfigPath = join15(projectRoot, "tsconfig.json");
248337
248343
  if (!await pathExists(tsconfigPath)) {
248338
248344
  return false;
248339
248345
  }
@@ -248376,7 +248382,7 @@ function getTypesCommand(context) {
248376
248382
  }
248377
248383
 
248378
248384
  // src/cli/dev/dev-server/main.ts
248379
- import { dirname as dirname14, join as join20 } from "node:path";
248385
+ import { dirname as dirname13, join as join18 } from "node:path";
248380
248386
  var import_cors = __toESM(require_lib4(), 1);
248381
248387
  var import_express4 = __toESM(require_express(), 1);
248382
248388
 
@@ -249856,9 +249862,9 @@ class NodeFsHandler {
249856
249862
  if (this.fsw.closed) {
249857
249863
  return;
249858
249864
  }
249859
- const dirname13 = sp2.dirname(file2);
249865
+ const dirname12 = sp2.dirname(file2);
249860
249866
  const basename5 = sp2.basename(file2);
249861
- const parent = this.fsw._getWatchedDir(dirname13);
249867
+ const parent = this.fsw._getWatchedDir(dirname12);
249862
249868
  let prevStats = stats;
249863
249869
  if (parent.has(basename5))
249864
249870
  return;
@@ -249885,7 +249891,7 @@ class NodeFsHandler {
249885
249891
  prevStats = newStats2;
249886
249892
  }
249887
249893
  } catch (error48) {
249888
- this.fsw._remove(dirname13, basename5);
249894
+ this.fsw._remove(dirname12, basename5);
249889
249895
  }
249890
249896
  } else if (parent.has(basename5)) {
249891
249897
  const at13 = newStats.atimeMs;
@@ -250906,8 +250912,8 @@ async function createDevServer(options8) {
250906
250912
  broadcastEntityEvent(io6, appId, entityName, event);
250907
250913
  };
250908
250914
  const base44ConfigWatcher = new WatchBase44({
250909
- functions: join20(dirname14(project2.configPath), project2.functionsDir),
250910
- entities: join20(dirname14(project2.configPath), project2.entitiesDir)
250915
+ functions: join18(dirname13(project2.configPath), project2.functionsDir),
250916
+ entities: join18(dirname13(project2.configPath), project2.entitiesDir)
250911
250917
  }, devLogger);
250912
250918
  base44ConfigWatcher.on("change", async (name2) => {
250913
250919
  try {
@@ -251097,7 +251103,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
251097
251103
  import { release, type } from "node:os";
251098
251104
 
251099
251105
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
251100
- import { dirname as dirname15, posix, sep } from "path";
251106
+ import { dirname as dirname14, posix, sep } from "path";
251101
251107
  function createModulerModifier() {
251102
251108
  const getModuleFromFileName = createGetModuleFromFilename();
251103
251109
  return async (frames) => {
@@ -251106,7 +251112,7 @@ function createModulerModifier() {
251106
251112
  return frames;
251107
251113
  };
251108
251114
  }
251109
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname15(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
251115
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname14(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
251110
251116
  const normalizedBase = isWindows5 ? normalizeWindowsPath2(basePath) : basePath;
251111
251117
  return (filename) => {
251112
251118
  if (!filename)
@@ -255295,9 +255301,9 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
255295
255301
  });
255296
255302
  }
255297
255303
  // src/cli/index.ts
255298
- var __dirname4 = dirname16(fileURLToPath6(import.meta.url));
255304
+ var __dirname4 = dirname15(fileURLToPath6(import.meta.url));
255299
255305
  async function runCLI() {
255300
- ensureNpmAssets(join21(__dirname4, "../assets"));
255306
+ ensureNpmAssets(join19(__dirname4, "../assets"));
255301
255307
  const errorReporter = new ErrorReporter;
255302
255308
  errorReporter.registerProcessErrorHandlers();
255303
255309
  const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
@@ -255329,4 +255335,4 @@ export {
255329
255335
  CLIExitError
255330
255336
  };
255331
255337
 
255332
- //# debugId=AC227C160FCE9CC164756E2164756E21
255338
+ //# debugId=F3F799D2EDA5BC2A64756E2164756E21