@base44-preview/cli 0.0.41-pr.382.5e7988f → 0.0.41-pr.383.d14a5c0

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 pull3 = 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 = pull3;
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"]);
@@ -237514,10 +237514,6 @@ var GoogleBigQueryConnectorSchema = exports_external.object({
237514
237514
  type: exports_external.literal("googlebigquery"),
237515
237515
  scopes: exports_external.array(exports_external.string()).default([])
237516
237516
  });
237517
- var StripeConnectorSchema = exports_external.object({
237518
- type: exports_external.literal("stripe"),
237519
- scopes: exports_external.array(exports_external.string()).default([])
237520
- });
237521
237517
  var CustomTypeSchema = exports_external.string().min(1).regex(/^[a-z0-9_-]+$/i);
237522
237518
  var GenericConnectorSchema = exports_external.object({
237523
237519
  type: CustomTypeSchema,
@@ -237537,7 +237533,6 @@ var ConnectorResourceSchema = exports_external.union([
237537
237533
  HubspotConnectorSchema,
237538
237534
  LinkedInConnectorSchema,
237539
237535
  TikTokConnectorSchema,
237540
- StripeConnectorSchema,
237541
237536
  GenericConnectorSchema
237542
237537
  ]);
237543
237538
  var KnownIntegrationTypes = [
@@ -237553,8 +237548,7 @@ var KnownIntegrationTypes = [
237553
237548
  "salesforce",
237554
237549
  "hubspot",
237555
237550
  "linkedin",
237556
- "tiktok",
237557
- "stripe"
237551
+ "tiktok"
237558
237552
  ];
237559
237553
  var IntegrationTypeSchema = exports_external.union([
237560
237554
  exports_external.enum(KnownIntegrationTypes),
@@ -237607,24 +237601,6 @@ var RemoveConnectorResponseSchema = exports_external.object({
237607
237601
  status: data.status,
237608
237602
  integrationType: data.integration_type
237609
237603
  }));
237610
- var STRIPE_CONNECTOR_TYPE = "stripe";
237611
- var InstallStripeResponseSchema = exports_external.object({
237612
- already_installed: exports_external.boolean(),
237613
- claim_url: exports_external.string().nullable()
237614
- }).transform((data) => ({
237615
- alreadyInstalled: data.already_installed,
237616
- claimUrl: data.claim_url
237617
- }));
237618
- var StripeStatusResponseSchema = exports_external.object({
237619
- stripe_mode: exports_external.enum(["sandbox", "live"]).nullable(),
237620
- sandbox_claim_url: exports_external.string().nullable().optional()
237621
- }).transform((data) => ({
237622
- stripeMode: data.stripe_mode,
237623
- sandboxClaimUrl: data.sandbox_claim_url
237624
- }));
237625
- var RemoveStripeResponseSchema = exports_external.object({
237626
- success: exports_external.boolean()
237627
- });
237628
237604
  var ConnectionConfigFieldSchema = exports_external.object({
237629
237605
  name: exports_external.string(),
237630
237606
  display_name: exports_external.string(),
@@ -237739,54 +237715,6 @@ async function removeConnector(integrationType) {
237739
237715
  }
237740
237716
  return result.data;
237741
237717
  }
237742
- async function installStripe() {
237743
- const appClient = getAppClient();
237744
- let response;
237745
- try {
237746
- response = await appClient.post("payments/stripe/install", {
237747
- timeout: 60000
237748
- });
237749
- } catch (error48) {
237750
- throw await ApiError.fromHttpError(error48, "installing Stripe");
237751
- }
237752
- const result = InstallStripeResponseSchema.safeParse(await response.json());
237753
- if (!result.success) {
237754
- throw new SchemaValidationError("Invalid response from server", result.error);
237755
- }
237756
- return result.data;
237757
- }
237758
- async function getStripeStatus() {
237759
- const appClient = getAppClient();
237760
- let response;
237761
- try {
237762
- response = await appClient.get("payments/stripe/status", {
237763
- timeout: 60000
237764
- });
237765
- } catch (error48) {
237766
- throw await ApiError.fromHttpError(error48, "checking Stripe integration status");
237767
- }
237768
- const result = StripeStatusResponseSchema.safeParse(await response.json());
237769
- if (!result.success) {
237770
- throw new SchemaValidationError("Invalid response from server", result.error);
237771
- }
237772
- return result.data;
237773
- }
237774
- async function removeStripe() {
237775
- const appClient = getAppClient();
237776
- let response;
237777
- try {
237778
- response = await appClient.delete("payments/stripe", {
237779
- timeout: 60000
237780
- });
237781
- } catch (error48) {
237782
- throw await ApiError.fromHttpError(error48, "removing Stripe integration");
237783
- }
237784
- const result = RemoveStripeResponseSchema.safeParse(await response.json());
237785
- if (!result.success) {
237786
- throw new SchemaValidationError("Invalid response from server", result.error);
237787
- }
237788
- return result.data;
237789
- }
237790
237718
  // src/core/resources/connector/config.ts
237791
237719
  import { join as join4 } from "node:path";
237792
237720
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
@@ -237835,7 +237763,7 @@ async function readAllConnectors(connectorsDir) {
237835
237763
  async function writeConnectors(connectorsDir, remoteConnectors) {
237836
237764
  const entries = await readConnectorFiles(connectorsDir);
237837
237765
  const typeToEntry = buildTypeToEntryMap(entries);
237838
- const newTypes = new Set(remoteConnectors.map((c) => c.type));
237766
+ const newTypes = new Set(remoteConnectors.map((c) => c.integrationType));
237839
237767
  const deleted = [];
237840
237768
  for (const [type, entry] of typeToEntry) {
237841
237769
  if (!newTypes.has(type)) {
@@ -237845,105 +237773,22 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
237845
237773
  }
237846
237774
  const written = [];
237847
237775
  for (const connector of remoteConnectors) {
237848
- const existing = typeToEntry.get(connector.type);
237849
- if (existing && isDeepStrictEqual2(existing.data, connector)) {
237776
+ const existing = typeToEntry.get(connector.integrationType);
237777
+ const localConnector = {
237778
+ type: connector.integrationType,
237779
+ scopes: connector.scopes
237780
+ };
237781
+ if (existing && isDeepStrictEqual2(existing.data, localConnector)) {
237850
237782
  continue;
237851
237783
  }
237852
- const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
237853
- await writeJsonFile(filePath, connector);
237854
- written.push(connector.type);
237784
+ const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.integrationType}.${CONFIG_FILE_EXTENSION}`);
237785
+ await writeJsonFile(filePath, localConnector);
237786
+ written.push(connector.integrationType);
237855
237787
  }
237856
237788
  return { written, deleted };
237857
237789
  }
237858
- // src/core/resources/connector/stripe.ts
237859
- async function syncStripeConnector(localStripe) {
237860
- const remoteStatus = await fetchStripeRemoteStatus();
237861
- if (remoteStatus === "error") {
237862
- return localStripe ? stripeError("Failed to check Stripe integration status") : null;
237863
- }
237864
- const isRemoteInstalled = remoteStatus.stripeMode !== null;
237865
- const needsInstall = localStripe && !isRemoteInstalled;
237866
- const alreadySynced = localStripe && isRemoteInstalled;
237867
- const needsRemoval = !localStripe && isRemoteInstalled;
237868
- if (needsInstall) {
237869
- return handleStripeInstall();
237870
- }
237871
- if (alreadySynced) {
237872
- return stripeSynced();
237873
- }
237874
- if (needsRemoval) {
237875
- return handleStripeRemoval();
237876
- }
237877
- return null;
237878
- }
237879
- async function isStripeInstalled() {
237880
- const status = await getStripeStatus();
237881
- return status.stripeMode !== null;
237882
- }
237883
- async function fetchStripeRemoteStatus() {
237884
- try {
237885
- return await getStripeStatus();
237886
- } catch {
237887
- return "error";
237888
- }
237889
- }
237890
- async function handleStripeInstall() {
237891
- try {
237892
- const result = await installStripe();
237893
- return stripeProvisioned(result.claimUrl ?? undefined);
237894
- } catch (err) {
237895
- return stripeError(err instanceof Error ? err.message : String(err));
237896
- }
237897
- }
237898
- async function handleStripeRemoval() {
237899
- try {
237900
- await removeStripe();
237901
- return stripeRemoved();
237902
- } catch (err) {
237903
- return stripeError(err instanceof Error ? err.message : String(err));
237904
- }
237905
- }
237906
- function stripeSynced() {
237907
- return { type: STRIPE_CONNECTOR_TYPE, action: "synced" };
237908
- }
237909
- function stripeProvisioned(claimUrl) {
237910
- return { type: STRIPE_CONNECTOR_TYPE, action: "provisioned", claimUrl };
237911
- }
237912
- function stripeRemoved() {
237913
- return { type: STRIPE_CONNECTOR_TYPE, action: "removed" };
237914
- }
237915
- function stripeError(error48) {
237916
- return { type: STRIPE_CONNECTOR_TYPE, action: "error", error: error48 };
237917
- }
237918
-
237919
- // src/core/resources/connector/pull.ts
237920
- async function pullAllConnectors() {
237921
- const [oauthResponse, stripeInstalled] = await Promise.all([
237922
- listConnectors(),
237923
- isStripeInstalled()
237924
- ]);
237925
- const connectors = oauthResponse.integrations.map((i) => ({
237926
- type: i.integrationType,
237927
- scopes: i.scopes
237928
- }));
237929
- if (stripeInstalled) {
237930
- connectors.push({ type: STRIPE_CONNECTOR_TYPE, scopes: [] });
237931
- }
237932
- return connectors;
237933
- }
237934
237790
  // src/core/resources/connector/push.ts
237935
237791
  async function pushConnectors(connectors) {
237936
- const stripeConnector = connectors.find((c) => c.type === STRIPE_CONNECTOR_TYPE);
237937
- const oauthConnectors = connectors.filter((c) => c.type !== STRIPE_CONNECTOR_TYPE);
237938
- const oauthResults = await syncOAuthConnectors(oauthConnectors);
237939
- const stripeResult = await syncStripeConnector(stripeConnector);
237940
- const results = [...oauthResults];
237941
- if (stripeResult) {
237942
- results.push(stripeResult);
237943
- }
237944
- return { results };
237945
- }
237946
- async function syncOAuthConnectors(connectors) {
237947
237792
  const results = [];
237948
237793
  const upstream = await listConnectors();
237949
237794
  const localTypes = new Set(connectors.map((c) => c.type));
@@ -237976,7 +237821,7 @@ async function syncOAuthConnectors(connectors) {
237976
237821
  }
237977
237822
  }
237978
237823
  }
237979
- return results;
237824
+ return { results };
237980
237825
  }
237981
237826
  function getConnectorSyncResult(type, response) {
237982
237827
  if (response.error === "different_user") {
@@ -238230,11 +238075,8 @@ var BackendFunctionSchema = FunctionConfigSchema.extend({
238230
238075
  entryPath: exports_external.string().min(1, "Entry path cannot be empty"),
238231
238076
  filePaths: exports_external.array(exports_external.string()).min(1, "Function must have at least one file")
238232
238077
  });
238233
- var DeployFunctionsResponseSchema = exports_external.object({
238234
- deployed: exports_external.array(exports_external.string()),
238235
- deleted: exports_external.array(exports_external.string()),
238236
- skipped: exports_external.array(exports_external.string()).optional().nullable(),
238237
- 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"])
238238
238080
  });
238239
238081
  var FunctionAutomationInfoSchema = exports_external.object({
238240
238082
  name: exports_external.string(),
@@ -238270,29 +238112,39 @@ var FunctionLogEntrySchema = exports_external.object({
238270
238112
  var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
238271
238113
 
238272
238114
  // src/core/resources/function/api.ts
238273
- function toDeployPayloadItem(fn) {
238274
- return {
238275
- name: fn.name,
238276
- entry: fn.entry,
238277
- files: fn.files,
238278
- automations: fn.automations
238279
- };
238280
- }
238281
- async function deployFunctions(functions) {
238115
+ async function deploySingleFunction(name2, payload) {
238282
238116
  const appClient = getAppClient();
238283
- const payload = {
238284
- functions: functions.map(toDeployPayloadItem)
238285
- };
238286
238117
  let response;
238287
238118
  try {
238288
- response = await appClient.put("backend-functions", {
238289
- json: payload,
238290
- timeout: false
238119
+ response = await appClient.put(`backend-functions/${encodeURIComponent(name2)}`, { json: payload, timeout: false });
238120
+ } catch (error48) {
238121
+ throw await ApiError.fromHttpError(error48, `deploying function "${name2}"`);
238122
+ }
238123
+ const result = DeploySingleFunctionResponseSchema.safeParse(await response.json());
238124
+ if (!result.success) {
238125
+ throw new SchemaValidationError("Invalid response from server", result.error);
238126
+ }
238127
+ return result.data;
238128
+ }
238129
+ async function deleteSingleFunction(name2) {
238130
+ const appClient = getAppClient();
238131
+ try {
238132
+ await appClient.delete(`backend-functions/${encodeURIComponent(name2)}`, {
238133
+ timeout: 60000
238291
238134
  });
238292
238135
  } catch (error48) {
238293
- throw await ApiError.fromHttpError(error48, "deploying functions");
238136
+ throw await ApiError.fromHttpError(error48, `deleting function "${name2}"`);
238294
238137
  }
238295
- const result = DeployFunctionsResponseSchema.safeParse(await response.json());
238138
+ }
238139
+ async function listDeployedFunctions() {
238140
+ const appClient = getAppClient();
238141
+ let response;
238142
+ try {
238143
+ response = await appClient.get("backend-functions", { timeout: 30000 });
238144
+ } catch (error48) {
238145
+ throw await ApiError.fromHttpError(error48, "listing deployed functions");
238146
+ }
238147
+ const result = ListFunctionsResponseSchema.safeParse(await response.json());
238296
238148
  if (!result.success) {
238297
238149
  throw new SchemaValidationError("Invalid response from server", result.error);
238298
238150
  }
@@ -238334,20 +238186,6 @@ async function fetchFunctionLogs(functionName, filters = {}) {
238334
238186
  }
238335
238187
  return result.data;
238336
238188
  }
238337
- async function listDeployedFunctions() {
238338
- const appClient = getAppClient();
238339
- let response;
238340
- try {
238341
- response = await appClient.get("backend-functions", { timeout: 30000 });
238342
- } catch (error48) {
238343
- throw await ApiError.fromHttpError(error48, "listing deployed functions");
238344
- }
238345
- const result = ListFunctionsResponseSchema.safeParse(await response.json());
238346
- if (!result.success) {
238347
- throw new SchemaValidationError("Invalid response from server", result.error);
238348
- }
238349
- return result.data;
238350
- }
238351
238189
  // src/core/resources/function/config.ts
238352
238190
  import { basename as basename2, dirname as dirname3, join as join5, relative } from "node:path";
238353
238191
  async function readFunctionConfig(configPath) {
@@ -238429,84 +238267,70 @@ async function readAllFunctions(functionsDir) {
238429
238267
  import { dirname as dirname4, relative as relative2 } from "node:path";
238430
238268
  async function loadFunctionCode(fn) {
238431
238269
  const functionDir = dirname4(fn.entryPath);
238432
- const loadedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238270
+ const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238433
238271
  const content = await readTextFile(filePath);
238434
238272
  const path11 = relative2(functionDir, filePath).split(/[/\\]/).join("/");
238435
238273
  return { path: path11, content };
238436
238274
  }));
238437
- return { ...fn, files: loadedFiles };
238438
- }
238439
- async function pushFunctions(functions) {
238440
- if (functions.length === 0) {
238441
- return { deployed: [], deleted: [], skipped: [], errors: null };
238442
- }
238443
- const functionsWithCode = await Promise.all(functions.map(loadFunctionCode));
238444
- return deployFunctions(functionsWithCode);
238275
+ return { ...fn, files: resolvedFiles };
238445
238276
  }
238446
- // src/core/resources/function/pull.ts
238447
- import { join as join6 } from "node:path";
238448
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
238449
- async function writeFunctions(functionsDir, functions) {
238450
- const written = [];
238451
- const skipped = [];
238452
- for (const fn of functions) {
238453
- const functionDir = join6(functionsDir, fn.name);
238454
- const configPath = join6(functionDir, "function.jsonc");
238455
- if (await isFunctionUnchanged(functionDir, fn)) {
238456
- skipped.push(fn.name);
238457
- continue;
238458
- }
238459
- const config5 = {
238277
+ async function deployOne(fn) {
238278
+ const start = Date.now();
238279
+ try {
238280
+ const functionWithCode = await loadFunctionCode(fn);
238281
+ const response = await deploySingleFunction(functionWithCode.name, {
238282
+ entry: functionWithCode.entry,
238283
+ files: functionWithCode.files,
238284
+ automations: functionWithCode.automations
238285
+ });
238286
+ return {
238287
+ name: functionWithCode.name,
238288
+ status: response.status,
238289
+ durationMs: Date.now() - start
238290
+ };
238291
+ } catch (error48) {
238292
+ return {
238460
238293
  name: fn.name,
238461
- entry: fn.entry
238294
+ status: "error",
238295
+ error: error48 instanceof Error ? error48.message : String(error48)
238462
238296
  };
238463
- if (fn.automations.length > 0) {
238464
- config5.automations = fn.automations;
238465
- }
238466
- await writeJsonFile(configPath, config5);
238467
- for (const file2 of fn.files) {
238468
- await writeFile(join6(functionDir, file2.path), file2.content);
238469
- }
238470
- written.push(fn.name);
238471
238297
  }
238472
- return { written, skipped };
238473
238298
  }
238474
- async function isFunctionUnchanged(functionDir, fn) {
238475
- if (!await pathExists(functionDir)) {
238476
- return false;
238477
- }
238478
- const configPath = join6(functionDir, "function.jsonc");
238479
- try {
238480
- const localConfig = await readJsonFile(configPath);
238481
- if (localConfig.entry !== fn.entry) {
238482
- return false;
238483
- }
238484
- if (!isDeepStrictEqual3(localConfig.automations ?? [], fn.automations)) {
238485
- return false;
238486
- }
238487
- } catch {
238488
- return false;
238299
+ async function deployFunctionsSequentially(functions, options) {
238300
+ if (functions.length === 0)
238301
+ return [];
238302
+ const results = [];
238303
+ for (const fn of functions) {
238304
+ options?.onStart?.([fn.name]);
238305
+ const result = await deployOne(fn);
238306
+ results.push(result);
238307
+ options?.onResult?.(result);
238489
238308
  }
238490
- for (const file2 of fn.files) {
238491
- const filePath = join6(functionDir, file2.path);
238492
- if (!await pathExists(filePath)) {
238493
- return false;
238494
- }
238309
+ return results;
238310
+ }
238311
+ async function pruneRemovedFunctions(localFunctionNames) {
238312
+ const remote = await listDeployedFunctions();
238313
+ const localSet = new Set(localFunctionNames);
238314
+ const toDelete = remote.functions.filter((f) => !localSet.has(f.name));
238315
+ const results = [];
238316
+ for (const fn of toDelete) {
238495
238317
  try {
238496
- const localContent = await readTextFile(filePath);
238497
- if (localContent !== file2.content) {
238498
- return false;
238499
- }
238500
- } catch {
238501
- return false;
238318
+ await deleteSingleFunction(fn.name);
238319
+ results.push({ name: fn.name, deleted: true });
238320
+ } catch (error48) {
238321
+ results.push({
238322
+ name: fn.name,
238323
+ deleted: false,
238324
+ error: error48 instanceof Error ? error48.message : String(error48)
238325
+ });
238502
238326
  }
238503
238327
  }
238504
- return true;
238328
+ return results;
238505
238329
  }
238506
238330
  // src/core/resources/function/resource.ts
238507
238331
  var functionResource = {
238508
238332
  readAll: readAllFunctions,
238509
- push: pushFunctions
238333
+ push: (functions) => deployFunctionsSequentially(functions)
238510
238334
  };
238511
238335
  // src/core/project/config.ts
238512
238336
  async function findConfigInDir(dir) {
@@ -238547,10 +238371,10 @@ async function readProjectConfig(projectRoot) {
238547
238371
  const project = result.data;
238548
238372
  const configDir = dirname5(configPath);
238549
238373
  const [entities, functions, agents, connectors] = await Promise.all([
238550
- entityResource.readAll(join7(configDir, project.entitiesDir)),
238551
- functionResource.readAll(join7(configDir, project.functionsDir)),
238552
- agentResource.readAll(join7(configDir, project.agentsDir)),
238553
- connectorResource.readAll(join7(configDir, project.connectorsDir))
238374
+ entityResource.readAll(join6(configDir, project.entitiesDir)),
238375
+ functionResource.readAll(join6(configDir, project.functionsDir)),
238376
+ agentResource.readAll(join6(configDir, project.agentsDir)),
238377
+ connectorResource.readAll(join6(configDir, project.connectorsDir))
238554
238378
  ]);
238555
238379
  return {
238556
238380
  project: { ...project, root, configPath },
@@ -238647,12 +238471,12 @@ async function readAppConfig(projectRoot) {
238647
238471
  // src/core/project/template.ts
238648
238472
  var import_ejs = __toESM(require_ejs(), 1);
238649
238473
  var import_front_matter = __toESM(require_front_matter(), 1);
238650
- import { dirname as dirname6, join as join9 } from "node:path";
238474
+ import { dirname as dirname6, join as join8 } from "node:path";
238651
238475
 
238652
238476
  // src/core/assets.ts
238653
238477
  import { cpSync, existsSync } from "node:fs";
238654
238478
  import { homedir as homedir2 } from "node:os";
238655
- import { join as join8 } from "node:path";
238479
+ import { join as join7 } from "node:path";
238656
238480
  // package.json
238657
238481
  var package_default = {
238658
238482
  name: "base44",
@@ -238745,15 +238569,15 @@ var package_default = {
238745
238569
  };
238746
238570
 
238747
238571
  // src/core/assets.ts
238748
- var ASSETS_DIR = join8(homedir2(), ".base44", "assets", package_default.version);
238572
+ var ASSETS_DIR = join7(homedir2(), ".base44", "assets", package_default.version);
238749
238573
  function getTemplatesDir() {
238750
- return join8(ASSETS_DIR, "templates");
238574
+ return join7(ASSETS_DIR, "templates");
238751
238575
  }
238752
238576
  function getTemplatesIndexPath() {
238753
- return join8(ASSETS_DIR, "templates", "templates.json");
238577
+ return join7(ASSETS_DIR, "templates", "templates.json");
238754
238578
  }
238755
238579
  function getDenoWrapperPath() {
238756
- return join8(ASSETS_DIR, "deno-runtime", "main.js");
238580
+ return join7(ASSETS_DIR, "deno-runtime", "main.js");
238757
238581
  }
238758
238582
  function ensureNpmAssets(sourceDir) {
238759
238583
  if (existsSync(ASSETS_DIR))
@@ -238774,23 +238598,23 @@ async function listTemplates() {
238774
238598
  return result.data.templates;
238775
238599
  }
238776
238600
  async function renderTemplate(template, destPath, data) {
238777
- const templateDir = join9(getTemplatesDir(), template.path);
238601
+ const templateDir = join8(getTemplatesDir(), template.path);
238778
238602
  const files = await globby("**/*", {
238779
238603
  cwd: templateDir,
238780
238604
  dot: true,
238781
238605
  onlyFiles: true
238782
238606
  });
238783
238607
  for (const file2 of files) {
238784
- const srcPath = join9(templateDir, file2);
238608
+ const srcPath = join8(templateDir, file2);
238785
238609
  try {
238786
238610
  if (file2.endsWith(".ejs")) {
238787
238611
  const rendered = await import_ejs.default.renderFile(srcPath, data);
238788
238612
  const { attributes, body } = import_front_matter.default(rendered);
238789
- const destFile = attributes.outputFileName ? join9(dirname6(file2), attributes.outputFileName) : file2.replace(/\.ejs$/, "");
238790
- const destFilePath = join9(destPath, destFile);
238613
+ const destFile = attributes.outputFileName ? join8(dirname6(file2), attributes.outputFileName) : file2.replace(/\.ejs$/, "");
238614
+ const destFilePath = join8(destPath, destFile);
238791
238615
  await writeFile(destFilePath, body);
238792
238616
  } else {
238793
- const destFilePath = join9(destPath, file2);
238617
+ const destFilePath = join8(destPath, file2);
238794
238618
  await copyFile(srcPath, destFilePath);
238795
238619
  }
238796
238620
  } catch (error48) {
@@ -238889,7 +238713,7 @@ async function getSiteFilePaths(outputDir) {
238889
238713
  // src/core/site/deploy.ts
238890
238714
  import { randomUUID } from "node:crypto";
238891
238715
  import { tmpdir } from "node:os";
238892
- import { join as join10 } from "node:path";
238716
+ import { join as join9 } from "node:path";
238893
238717
  async function deploySite(siteOutputDir) {
238894
238718
  if (!await pathExists(siteOutputDir)) {
238895
238719
  throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
@@ -238906,7 +238730,7 @@ async function deploySite(siteOutputDir) {
238906
238730
  ]
238907
238731
  });
238908
238732
  }
238909
- const archivePath = join10(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
238733
+ const archivePath = join9(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
238910
238734
  try {
238911
238735
  await createArchive(siteOutputDir, archivePath);
238912
238736
  return await uploadSite(archivePath);
@@ -246591,10 +246415,6 @@ function getDashboardUrl(projectId) {
246591
246415
  const id = projectId ?? getAppConfig().id;
246592
246416
  return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/overview`;
246593
246417
  }
246594
- function getConnectorsUrl(projectId) {
246595
- const id = projectId ?? getAppConfig().id;
246596
- return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/app-connections`;
246597
- }
246598
246418
  // src/cli/utils/yaml.ts
246599
246419
  var import_lodash = __toESM(require_lodash(), 1);
246600
246420
 
@@ -246662,7 +246482,7 @@ function formatYaml(data, options = {}) {
246662
246482
  async function pullAgentsAction() {
246663
246483
  const { project: project2 } = await readProjectConfig();
246664
246484
  const configDir = dirname7(project2.configPath);
246665
- const agentsDir = join11(configDir, project2.agentsDir);
246485
+ const agentsDir = join10(configDir, project2.agentsDir);
246666
246486
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
246667
246487
  return await fetchAgents();
246668
246488
  }, {
@@ -246784,19 +246604,19 @@ function getConnectorsListAvailableCommand(context) {
246784
246604
  }
246785
246605
 
246786
246606
  // src/cli/commands/connectors/pull.ts
246787
- import { dirname as dirname8, join as join12 } from "node:path";
246607
+ import { dirname as dirname8, join as join11 } from "node:path";
246788
246608
  async function pullConnectorsAction() {
246789
246609
  const { project: project2 } = await readProjectConfig();
246790
246610
  const configDir = dirname8(project2.configPath);
246791
- const connectorsDir = join12(configDir, project2.connectorsDir);
246611
+ const connectorsDir = join11(configDir, project2.connectorsDir);
246792
246612
  const remoteConnectors = await runTask("Fetching connectors from Base44", async () => {
246793
- return await pullAllConnectors();
246613
+ return await listConnectors();
246794
246614
  }, {
246795
246615
  successMessage: "Connectors fetched successfully",
246796
246616
  errorMessage: "Failed to fetch connectors"
246797
246617
  });
246798
246618
  const { written, deleted } = await runTask("Syncing connector files", async () => {
246799
- return await writeConnectors(connectorsDir, remoteConnectors);
246619
+ return await writeConnectors(connectorsDir, remoteConnectors.integrations);
246800
246620
  }, {
246801
246621
  successMessage: "Connector files synced successfully",
246802
246622
  errorMessage: "Failed to sync connector files"
@@ -246811,7 +246631,7 @@ async function pullConnectorsAction() {
246811
246631
  R2.info("All connectors are already up to date");
246812
246632
  }
246813
246633
  return {
246814
- outroMessage: `Pulled ${remoteConnectors.length} connectors to ${connectorsDir}`
246634
+ outroMessage: `Pulled ${remoteConnectors.integrations.length} connectors to ${connectorsDir}`
246815
246635
  };
246816
246636
  }
246817
246637
  function getConnectorsPullCommand(context) {
@@ -247430,7 +247250,7 @@ var open_default = open;
247430
247250
  var POLL_INTERVAL_MS = 2000;
247431
247251
  var POLL_TIMEOUT_MS = 2 * 60 * 1000;
247432
247252
  function filterPendingOAuth(results) {
247433
- return results.filter((r) => r.action === "needs_oauth" && !!r.connectionId);
247253
+ return results.filter((r) => r.action === "needs_oauth" && !!r.redirectUrl && !!r.connectionId);
247434
247254
  }
247435
247255
  async function runOAuthFlowWithSkip(connector2) {
247436
247256
  await open_default(connector2.redirectUrl);
@@ -247448,10 +247268,6 @@ async function runOAuthFlowWithSkip(connector2) {
247448
247268
  finalStatus = "SKIPPED";
247449
247269
  return true;
247450
247270
  }
247451
- if (!connector2.connectionId) {
247452
- finalStatus = "FAILED";
247453
- return true;
247454
- }
247455
247271
  const response = await getOAuthStatus(connector2.type, connector2.connectionId);
247456
247272
  finalStatus = response.status;
247457
247273
  return response.status !== "PENDING";
@@ -247514,49 +247330,32 @@ async function promptOAuthFlows(pending, options) {
247514
247330
  function printSummary(results, oauthOutcomes) {
247515
247331
  const synced = [];
247516
247332
  const added = [];
247517
- let provisioned;
247518
247333
  const removed = [];
247519
247334
  const skipped = [];
247520
247335
  const failed = [];
247521
247336
  for (const r of results) {
247522
- switch (r.action) {
247523
- case "provisioned":
247524
- provisioned = r;
247525
- break;
247526
- case "synced":
247527
- synced.push(r.type);
247528
- break;
247529
- case "removed":
247530
- removed.push(r.type);
247531
- break;
247532
- case "error":
247533
- failed.push({ type: r.type, error: r.error });
247534
- break;
247535
- case "needs_oauth": {
247536
- const oauthStatus = oauthOutcomes.get(r.type);
247537
- if (oauthStatus === "ACTIVE") {
247538
- added.push(r.type);
247539
- } else if (oauthStatus === "SKIPPED") {
247540
- skipped.push(r.type);
247541
- } else if (oauthStatus === "PENDING") {
247542
- failed.push({ type: r.type, error: "authorization timed out" });
247543
- } else if (oauthStatus === "FAILED") {
247544
- failed.push({ type: r.type, error: "authorization failed" });
247545
- } else {
247546
- failed.push({ type: r.type, error: "needs authorization" });
247547
- }
247548
- break;
247337
+ const oauthStatus = oauthOutcomes.get(r.type);
247338
+ if (r.action === "synced") {
247339
+ synced.push(r.type);
247340
+ } else if (r.action === "removed") {
247341
+ removed.push(r.type);
247342
+ } else if (r.action === "error") {
247343
+ failed.push({ type: r.type, error: r.error });
247344
+ } else if (r.action === "needs_oauth") {
247345
+ if (oauthStatus === "ACTIVE") {
247346
+ added.push(r.type);
247347
+ } else if (oauthStatus === "SKIPPED") {
247348
+ skipped.push(r.type);
247349
+ } else if (oauthStatus === "PENDING") {
247350
+ failed.push({ type: r.type, error: "authorization timed out" });
247351
+ } else if (oauthStatus === "FAILED") {
247352
+ failed.push({ type: r.type, error: "authorization failed" });
247353
+ } else {
247354
+ failed.push({ type: r.type, error: "needs authorization" });
247549
247355
  }
247550
247356
  }
247551
247357
  }
247552
247358
  R2.info(theme.styles.bold("Summary:"));
247553
- if (provisioned) {
247554
- R2.success("Stripe sandbox provisioned");
247555
- if (provisioned.claimUrl) {
247556
- R2.info(` Claim your Stripe sandbox: ${theme.colors.links(provisioned.claimUrl)}`);
247557
- }
247558
- R2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
247559
- }
247560
247359
  if (synced.length > 0) {
247561
247360
  R2.success(`Synced: ${synced.join(", ")}`);
247562
247361
  }
@@ -247570,7 +247369,7 @@ function printSummary(results, oauthOutcomes) {
247570
247369
  R2.warn(`Skipped: ${skipped.join(", ")}`);
247571
247370
  }
247572
247371
  for (const r of failed) {
247573
- R2.error(`Failed: ${r.type} - ${r.error}`);
247372
+ R2.error(`Failed: ${r.type}${r.error ? ` - ${r.error}` : ""}`);
247574
247373
  }
247575
247374
  }
247576
247375
  async function pushConnectorsAction(isNonInteractive) {
@@ -247657,95 +247456,129 @@ function getEntitiesPushCommand(context) {
247657
247456
  }));
247658
247457
  }
247659
247458
 
247459
+ // src/cli/utils/formatDeployResult.ts
247460
+ function formatDuration(ms) {
247461
+ return `${(ms / 1000).toFixed(1)}s`;
247462
+ }
247463
+ function formatDeployResult(result) {
247464
+ const label = result.name.padEnd(25);
247465
+ if (result.status === "deployed") {
247466
+ const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
247467
+ R2.success(`${label} deployed${timing}`);
247468
+ } else if (result.status === "unchanged") {
247469
+ R2.success(`${label} unchanged`);
247470
+ } else {
247471
+ R2.error(`${label} error: ${result.error}`);
247472
+ }
247473
+ }
247474
+
247475
+ // src/cli/utils/parseNames.ts
247476
+ function parseNames(args) {
247477
+ return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
247478
+ }
247479
+
247660
247480
  // src/cli/commands/functions/deploy.ts
247661
- async function deployFunctionsAction() {
247481
+ function resolveFunctionsToDeploy(names, allFunctions) {
247482
+ if (names.length === 0)
247483
+ return allFunctions;
247484
+ const notFound = names.filter((n2) => !allFunctions.some((f) => f.name === n2));
247485
+ if (notFound.length > 0) {
247486
+ throw new InvalidInputError(`Function${notFound.length > 1 ? "s" : ""} not found in project: ${notFound.join(", ")}`);
247487
+ }
247488
+ return allFunctions.filter((f) => names.includes(f.name));
247489
+ }
247490
+ function formatPruneResults(pruneResults) {
247491
+ for (const pruneResult of pruneResults) {
247492
+ if (pruneResult.deleted) {
247493
+ R2.success(`${pruneResult.name.padEnd(25)} deleted`);
247494
+ } else {
247495
+ R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
247496
+ }
247497
+ }
247498
+ if (pruneResults.length > 0) {
247499
+ const pruned = pruneResults.filter((r) => r.deleted).length;
247500
+ R2.info(`${pruned} function${pruned !== 1 ? "s" : ""} removed`);
247501
+ }
247502
+ }
247503
+ function buildDeploySummary(results) {
247504
+ const deployed = results.filter((r) => r.status !== "error").length;
247505
+ const failed = results.filter((r) => r.status === "error").length;
247506
+ const parts = [];
247507
+ if (deployed > 0)
247508
+ parts.push(`${deployed}/${results.length} deployed`);
247509
+ if (failed > 0)
247510
+ parts.push(`${failed} error${failed !== 1 ? "s" : ""}`);
247511
+ return parts.join(", ") || "No functions deployed";
247512
+ }
247513
+ async function deployFunctionsAction(names, options) {
247514
+ if (options.force && names.length > 0) {
247515
+ throw new InvalidInputError("--force cannot be used when specifying function names");
247516
+ }
247662
247517
  const { functions } = await readProjectConfig();
247663
- if (functions.length === 0) {
247518
+ const toDeploy = resolveFunctionsToDeploy(names, functions);
247519
+ if (toDeploy.length === 0) {
247664
247520
  return {
247665
247521
  outroMessage: "No functions found. Create functions in the 'functions' directory."
247666
247522
  };
247667
247523
  }
247668
- R2.info(`Found ${functions.length} ${functions.length === 1 ? "function" : "functions"} to deploy`);
247669
- const result = await runTask("Deploying functions to Base44", async () => {
247670
- return await pushFunctions(functions);
247671
- }, {
247672
- successMessage: "Functions deployed successfully",
247673
- errorMessage: "Failed to deploy functions"
247524
+ R2.info(`Found ${toDeploy.length} ${toDeploy.length === 1 ? "function" : "functions"} to deploy`);
247525
+ let completed = 0;
247526
+ const total = toDeploy.length;
247527
+ const results = await deployFunctionsSequentially(toDeploy, {
247528
+ onStart: (startNames) => {
247529
+ const label = startNames.length === 1 ? startNames[0] : `${startNames.length} functions`;
247530
+ R2.step(theme.styles.dim(`[${completed + 1}/${total}] Deploying ${label}...`));
247531
+ },
247532
+ onResult: (result) => {
247533
+ completed++;
247534
+ formatDeployResult(result);
247535
+ }
247674
247536
  });
247675
- if (result.deployed.length > 0) {
247676
- R2.success(`Deployed: ${result.deployed.join(", ")}`);
247537
+ if (options.force) {
247538
+ R2.info("Removing remote functions not found locally...");
247539
+ const allLocalNames = functions.map((f) => f.name);
247540
+ const pruneResults = await pruneRemovedFunctions(allLocalNames);
247541
+ formatPruneResults(pruneResults);
247677
247542
  }
247678
- if (result.deleted.length > 0) {
247679
- R2.warn(`Deleted: ${result.deleted.join(", ")}`);
247680
- }
247681
- if (result.errors && result.errors.length > 0) {
247682
- throw new ApiError("Function deployment errors", {
247683
- details: result.errors.map((e2) => `'${e2.name}': ${e2.message}`),
247684
- hints: [
247685
- { message: "Check the function code for syntax errors" },
247686
- { message: "Ensure all imports are valid" }
247687
- ]
247688
- });
247689
- }
247690
- return { outroMessage: "Functions deployed to Base44" };
247543
+ return { outroMessage: buildDeploySummary(results) };
247691
247544
  }
247692
247545
  function getDeployCommand(context) {
247693
- return new Command("deploy").description("Deploy local functions to Base44").action(async () => {
247694
- await runCommand(deployFunctionsAction, { requireAuth: true }, context);
247546
+ 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) => {
247547
+ await runCommand(() => {
247548
+ const names = parseNames(rawNames);
247549
+ return deployFunctionsAction(names, options);
247550
+ }, { requireAuth: true }, context);
247695
247551
  });
247696
247552
  }
247697
247553
 
247698
- // src/cli/commands/functions/pull.ts
247699
- import { dirname as dirname9, join as join13 } from "node:path";
247700
- async function pullFunctionsAction(name2) {
247701
- const { project: project2 } = await readProjectConfig();
247702
- const configDir = dirname9(project2.configPath);
247703
- const functionsDir = join13(configDir, project2.functionsDir);
247704
- const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
247705
- const { functions } = await listDeployedFunctions();
247706
- return functions;
247707
- }, {
247708
- successMessage: "Functions fetched successfully",
247709
- errorMessage: "Failed to fetch functions"
247710
- });
247711
- const toPull = name2 ? remoteFunctions.filter((f) => f.name === name2) : remoteFunctions;
247712
- if (name2 && toPull.length === 0) {
247713
- return {
247714
- outroMessage: `Function "${name2}" not found on remote`
247715
- };
247716
- }
247717
- if (toPull.length === 0) {
247718
- return { outroMessage: "No functions found on remote" };
247719
- }
247720
- const { written, skipped } = await runTask("Writing function files", async () => {
247721
- return await writeFunctions(functionsDir, toPull);
247722
- }, {
247723
- successMessage: "Function files written successfully",
247724
- errorMessage: "Failed to write function files"
247725
- });
247726
- for (const name3 of written) {
247727
- R2.success(`${name3.padEnd(25)} written`);
247554
+ // src/cli/commands/functions/list.ts
247555
+ async function listFunctionsAction() {
247556
+ const { functions } = await runTask("Fetching functions...", async () => listDeployedFunctions());
247557
+ if (functions.length === 0) {
247558
+ return { outroMessage: "No functions on remote" };
247728
247559
  }
247729
- for (const name3 of skipped) {
247730
- R2.info(`${name3.padEnd(25)} unchanged`);
247560
+ for (const fn of functions) {
247561
+ const automationCount = fn.automations.length;
247562
+ const automationLabel = automationCount > 0 ? theme.styles.dim(` (${automationCount} automation${automationCount > 1 ? "s" : ""})`) : "";
247563
+ R2.message(` ${fn.name}${automationLabel}`);
247731
247564
  }
247732
247565
  return {
247733
- outroMessage: `Pulled ${toPull.length} function${toPull.length !== 1 ? "s" : ""} to ${functionsDir}`
247566
+ outroMessage: `${functions.length} function${functions.length !== 1 ? "s" : ""} on remote`
247734
247567
  };
247735
247568
  }
247736
- function getPullCommand(context) {
247737
- return new Command("pull").description("Pull deployed functions from Base44").argument("[name]", "Pull a single function by name").action(async (name2) => {
247738
- await runCommand(() => pullFunctionsAction(name2), { requireAuth: true }, context);
247569
+ function getListCommand(context) {
247570
+ return new Command("list").description("List all deployed functions").action(async () => {
247571
+ await runCommand(listFunctionsAction, { requireAuth: true }, context);
247739
247572
  });
247740
247573
  }
247741
247574
 
247742
247575
  // src/cli/commands/functions/index.ts
247743
247576
  function getFunctionsCommand(context) {
247744
- return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand(context)).addCommand(getPullCommand(context));
247577
+ return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand(context)).addCommand(getListCommand(context));
247745
247578
  }
247746
247579
 
247747
247580
  // src/cli/commands/project/create.ts
247748
- import { basename as basename3, join as join14, resolve as resolve2 } from "node:path";
247581
+ import { basename as basename3, join as join12, resolve as resolve2 } from "node:path";
247749
247582
  var import_kebabCase = __toESM(require_kebabCase(), 1);
247750
247583
  var DEFAULT_TEMPLATE_ID = "backend-only";
247751
247584
  async function getTemplateById(templateId) {
@@ -247881,7 +247714,7 @@ async function executeCreate({
247881
247714
  updateMessage("Building project...");
247882
247715
  await execa({ cwd: resolvedPath, shell: true })`${buildCommand}`;
247883
247716
  updateMessage("Deploying site...");
247884
- return await deploySite(join14(resolvedPath, outputDirectory));
247717
+ return await deploySite(join12(resolvedPath, outputDirectory));
247885
247718
  }, {
247886
247719
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
247887
247720
  errorMessage: "Failed to deploy site"
@@ -247967,11 +247800,15 @@ ${summaryLines.join(`
247967
247800
  successMessage: theme.colors.base44Orange("Deployment completed"),
247968
247801
  errorMessage: "Deployment failed"
247969
247802
  });
247970
- const connectorResults = result.connectorResults ?? [];
247971
- await handleOAuthConnectors(connectorResults, options);
247972
- const stripeResult = connectorResults.find((r) => r.type === "stripe");
247973
- if (stripeResult?.action === "provisioned") {
247974
- printStripeResult(stripeResult);
247803
+ const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
247804
+ if (needsOAuth.length > 0) {
247805
+ const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
247806
+ skipPrompt: options.yes || options.isNonInteractive
247807
+ });
247808
+ const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
247809
+ if (!allAuthorized) {
247810
+ R2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
247811
+ }
247975
247812
  }
247976
247813
  R2.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
247977
247814
  if (result.appUrl) {
@@ -247987,25 +247824,6 @@ function getDeployCommand2(context) {
247987
247824
  }), { requireAuth: true }, context);
247988
247825
  });
247989
247826
  }
247990
- async function handleOAuthConnectors(connectorResults, options) {
247991
- const needsOAuth = filterPendingOAuth(connectorResults);
247992
- if (needsOAuth.length === 0)
247993
- return;
247994
- const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
247995
- skipPrompt: options.yes || options.isNonInteractive
247996
- });
247997
- const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
247998
- if (!allAuthorized) {
247999
- R2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
248000
- }
248001
- }
248002
- function printStripeResult(r) {
248003
- R2.success("Stripe sandbox provisioned");
248004
- if (r.claimUrl) {
248005
- R2.info(` Claim your Stripe sandbox: ${theme.colors.links(r.claimUrl)}`);
248006
- }
248007
- R2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
248008
- }
248009
247827
 
248010
247828
  // src/cli/commands/project/link.ts
248011
247829
  function validateNonInteractiveFlags2(command) {
@@ -248524,10 +248342,10 @@ function toPascalCase(name2) {
248524
248342
  return name2.split(/[-_\s]+/).map((w8) => w8.charAt(0).toUpperCase() + w8.slice(1)).join("");
248525
248343
  }
248526
248344
  // src/core/types/update-project.ts
248527
- import { join as join17 } from "node:path";
248345
+ import { join as join15 } from "node:path";
248528
248346
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
248529
248347
  async function updateProjectConfig(projectRoot) {
248530
- const tsconfigPath = join17(projectRoot, "tsconfig.json");
248348
+ const tsconfigPath = join15(projectRoot, "tsconfig.json");
248531
248349
  if (!await pathExists(tsconfigPath)) {
248532
248350
  return false;
248533
248351
  }
@@ -248570,7 +248388,7 @@ function getTypesCommand(context) {
248570
248388
  }
248571
248389
 
248572
248390
  // src/cli/dev/dev-server/main.ts
248573
- import { dirname as dirname14, join as join20 } from "node:path";
248391
+ import { dirname as dirname13, join as join18 } from "node:path";
248574
248392
  var import_cors = __toESM(require_lib4(), 1);
248575
248393
  var import_express4 = __toESM(require_express(), 1);
248576
248394
 
@@ -250050,9 +249868,9 @@ class NodeFsHandler {
250050
249868
  if (this.fsw.closed) {
250051
249869
  return;
250052
249870
  }
250053
- const dirname13 = sp2.dirname(file2);
249871
+ const dirname12 = sp2.dirname(file2);
250054
249872
  const basename5 = sp2.basename(file2);
250055
- const parent = this.fsw._getWatchedDir(dirname13);
249873
+ const parent = this.fsw._getWatchedDir(dirname12);
250056
249874
  let prevStats = stats;
250057
249875
  if (parent.has(basename5))
250058
249876
  return;
@@ -250079,7 +249897,7 @@ class NodeFsHandler {
250079
249897
  prevStats = newStats2;
250080
249898
  }
250081
249899
  } catch (error48) {
250082
- this.fsw._remove(dirname13, basename5);
249900
+ this.fsw._remove(dirname12, basename5);
250083
249901
  }
250084
249902
  } else if (parent.has(basename5)) {
250085
249903
  const at13 = newStats.atimeMs;
@@ -251100,8 +250918,8 @@ async function createDevServer(options8) {
251100
250918
  broadcastEntityEvent(io6, appId, entityName, event);
251101
250919
  };
251102
250920
  const base44ConfigWatcher = new WatchBase44({
251103
- functions: join20(dirname14(project2.configPath), project2.functionsDir),
251104
- entities: join20(dirname14(project2.configPath), project2.entitiesDir)
250921
+ functions: join18(dirname13(project2.configPath), project2.functionsDir),
250922
+ entities: join18(dirname13(project2.configPath), project2.entitiesDir)
251105
250923
  }, devLogger);
251106
250924
  base44ConfigWatcher.on("change", async (name2) => {
251107
250925
  try {
@@ -251291,7 +251109,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
251291
251109
  import { release, type } from "node:os";
251292
251110
 
251293
251111
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
251294
- import { dirname as dirname15, posix, sep } from "path";
251112
+ import { dirname as dirname14, posix, sep } from "path";
251295
251113
  function createModulerModifier() {
251296
251114
  const getModuleFromFileName = createGetModuleFromFilename();
251297
251115
  return async (frames) => {
@@ -251300,7 +251118,7 @@ function createModulerModifier() {
251300
251118
  return frames;
251301
251119
  };
251302
251120
  }
251303
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname15(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
251121
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname14(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
251304
251122
  const normalizedBase = isWindows5 ? normalizeWindowsPath2(basePath) : basePath;
251305
251123
  return (filename) => {
251306
251124
  if (!filename)
@@ -255489,9 +255307,9 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
255489
255307
  });
255490
255308
  }
255491
255309
  // src/cli/index.ts
255492
- var __dirname4 = dirname16(fileURLToPath6(import.meta.url));
255310
+ var __dirname4 = dirname15(fileURLToPath6(import.meta.url));
255493
255311
  async function runCLI() {
255494
- ensureNpmAssets(join21(__dirname4, "../assets"));
255312
+ ensureNpmAssets(join19(__dirname4, "../assets"));
255495
255313
  const errorReporter = new ErrorReporter;
255496
255314
  errorReporter.registerProcessErrorHandlers();
255497
255315
  const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
@@ -255523,4 +255341,4 @@ export {
255523
255341
  CLIExitError
255524
255342
  };
255525
255343
 
255526
- //# debugId=0427AEEF5EF1A0DD64756E2164756E21
255344
+ //# debugId=85B4298BDB65853464756E2164756E21