@base44-preview/cli 0.0.32-pr.250.8053fb1 → 0.0.32-pr.251.2056a80

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
@@ -17468,7 +17468,7 @@ var require_lodash2 = __commonJS((exports, module) => {
17468
17468
  function nth(array2, n2) {
17469
17469
  return array2 && array2.length ? baseNth(array2, toInteger(n2)) : undefined2;
17470
17470
  }
17471
- var pull = baseRest(pullAll);
17471
+ var pull2 = baseRest(pullAll);
17472
17472
  function pullAll(array2, values2) {
17473
17473
  return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2) : array2;
17474
17474
  }
@@ -19233,7 +19233,7 @@ __p += '`;
19233
19233
  lodash.pickBy = pickBy;
19234
19234
  lodash.property = property;
19235
19235
  lodash.propertyOf = propertyOf;
19236
- lodash.pull = pull;
19236
+ lodash.pull = pull2;
19237
19237
  lodash.pullAll = pullAll;
19238
19238
  lodash.pullAllBy = pullAllBy;
19239
19239
  lodash.pullAllWith = pullAllWith;
@@ -185051,6 +185051,10 @@ var TikTokConnectorSchema = exports_external.object({
185051
185051
  type: exports_external.literal("tiktok"),
185052
185052
  scopes: exports_external.array(exports_external.string()).default([])
185053
185053
  });
185054
+ var StripeConnectorSchema = exports_external.object({
185055
+ type: exports_external.literal("stripe"),
185056
+ scopes: exports_external.array(exports_external.string()).default([])
185057
+ });
185054
185058
  var CustomTypeSchema = exports_external.string().min(1).regex(/^[a-z0-9_-]+$/i);
185055
185059
  var GenericConnectorSchema = exports_external.object({
185056
185060
  type: CustomTypeSchema,
@@ -185069,6 +185073,7 @@ var ConnectorResourceSchema = exports_external.union([
185069
185073
  HubspotConnectorSchema,
185070
185074
  LinkedInConnectorSchema,
185071
185075
  TikTokConnectorSchema,
185076
+ StripeConnectorSchema,
185072
185077
  GenericConnectorSchema
185073
185078
  ]);
185074
185079
  var KnownIntegrationTypes = [
@@ -185083,7 +185088,8 @@ var KnownIntegrationTypes = [
185083
185088
  "salesforce",
185084
185089
  "hubspot",
185085
185090
  "linkedin",
185086
- "tiktok"
185091
+ "tiktok",
185092
+ "stripe"
185087
185093
  ];
185088
185094
  var IntegrationTypeSchema = exports_external.union([
185089
185095
  exports_external.enum(KnownIntegrationTypes),
@@ -185136,6 +185142,18 @@ var RemoveConnectorResponseSchema = exports_external.object({
185136
185142
  status: data.status,
185137
185143
  integrationType: data.integration_type
185138
185144
  }));
185145
+ var STRIPE_CONNECTOR_TYPE = "stripe";
185146
+ var InstallStripeResponseSchema = exports_external.object({
185147
+ already_installed: exports_external.boolean(),
185148
+ claim_url: exports_external.string().nullable()
185149
+ });
185150
+ var StripeStatusResponseSchema = exports_external.object({
185151
+ stripe_mode: exports_external.enum(["sandbox", "live"]).nullable(),
185152
+ sandbox_claim_url: exports_external.string().nullable().optional()
185153
+ });
185154
+ var RemoveStripeResponseSchema = exports_external.object({
185155
+ success: exports_external.boolean()
185156
+ });
185139
185157
 
185140
185158
  // src/core/resources/connector/api.ts
185141
185159
  async function listConnectors() {
@@ -185203,6 +185221,54 @@ async function removeConnector(integrationType) {
185203
185221
  }
185204
185222
  return result.data;
185205
185223
  }
185224
+ async function installStripe() {
185225
+ const appClient = getAppClient();
185226
+ let response;
185227
+ try {
185228
+ response = await appClient.post("payments/stripe/install", {
185229
+ timeout: 60000
185230
+ });
185231
+ } catch (error48) {
185232
+ throw await ApiError.fromHttpError(error48, "installing Stripe");
185233
+ }
185234
+ const result = InstallStripeResponseSchema.safeParse(await response.json());
185235
+ if (!result.success) {
185236
+ throw new SchemaValidationError("Invalid response from server", result.error);
185237
+ }
185238
+ return result.data;
185239
+ }
185240
+ async function getStripeStatus() {
185241
+ const appClient = getAppClient();
185242
+ let response;
185243
+ try {
185244
+ response = await appClient.get("payments/stripe/status", {
185245
+ timeout: 60000
185246
+ });
185247
+ } catch (error48) {
185248
+ throw await ApiError.fromHttpError(error48, "checking Stripe integration status");
185249
+ }
185250
+ const result = StripeStatusResponseSchema.safeParse(await response.json());
185251
+ if (!result.success) {
185252
+ throw new SchemaValidationError("Invalid response from server", result.error);
185253
+ }
185254
+ return result.data;
185255
+ }
185256
+ async function removeStripe() {
185257
+ const appClient = getAppClient();
185258
+ let response;
185259
+ try {
185260
+ response = await appClient.delete("payments/stripe", {
185261
+ timeout: 60000
185262
+ });
185263
+ } catch (error48) {
185264
+ throw await ApiError.fromHttpError(error48, "removing Stripe integration");
185265
+ }
185266
+ const result = RemoveStripeResponseSchema.safeParse(await response.json());
185267
+ if (!result.success) {
185268
+ throw new SchemaValidationError("Invalid response from server", result.error);
185269
+ }
185270
+ return result.data;
185271
+ }
185206
185272
  // src/core/resources/connector/config.ts
185207
185273
  import { join as join4 } from "node:path";
185208
185274
  import { isDeepStrictEqual } from "node:util";
@@ -185251,7 +185317,7 @@ async function readAllConnectors(connectorsDir) {
185251
185317
  async function writeConnectors(connectorsDir, remoteConnectors) {
185252
185318
  const entries = await readConnectorFiles(connectorsDir);
185253
185319
  const typeToEntry = buildTypeToEntryMap(entries);
185254
- const newTypes = new Set(remoteConnectors.map((c) => c.integrationType));
185320
+ const newTypes = new Set(remoteConnectors.map((c) => c.type));
185255
185321
  const deleted = [];
185256
185322
  for (const [type, entry] of typeToEntry) {
185257
185323
  if (!newTypes.has(type)) {
@@ -185261,22 +185327,44 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
185261
185327
  }
185262
185328
  const written = [];
185263
185329
  for (const connector of remoteConnectors) {
185264
- const existing = typeToEntry.get(connector.integrationType);
185265
- const localConnector = {
185266
- type: connector.integrationType,
185267
- scopes: connector.scopes
185268
- };
185269
- if (existing && isDeepStrictEqual(existing.data, localConnector)) {
185330
+ const existing = typeToEntry.get(connector.type);
185331
+ if (existing && isDeepStrictEqual(existing.data, connector)) {
185270
185332
  continue;
185271
185333
  }
185272
- const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.integrationType}.${CONFIG_FILE_EXTENSION}`);
185273
- await writeJsonFile(filePath, localConnector);
185274
- written.push(connector.integrationType);
185334
+ const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
185335
+ await writeJsonFile(filePath, connector);
185336
+ written.push(connector.type);
185275
185337
  }
185276
185338
  return { written, deleted };
185277
185339
  }
185340
+ // src/core/resources/connector/pull.ts
185341
+ async function pullAllConnectors() {
185342
+ const [oauthResponse, stripeStatus] = await Promise.all([
185343
+ listConnectors(),
185344
+ getStripeStatus()
185345
+ ]);
185346
+ const connectors = oauthResponse.integrations.map((i) => ({
185347
+ type: i.integrationType,
185348
+ scopes: i.scopes
185349
+ }));
185350
+ if (stripeStatus.stripe_mode !== null) {
185351
+ connectors.push({ type: STRIPE_CONNECTOR_TYPE, scopes: [] });
185352
+ }
185353
+ return connectors;
185354
+ }
185278
185355
  // src/core/resources/connector/push.ts
185279
185356
  async function pushConnectors(connectors) {
185357
+ const stripeConnector = connectors.find((c) => c.type === STRIPE_CONNECTOR_TYPE);
185358
+ const oauthConnectors = connectors.filter((c) => c.type !== STRIPE_CONNECTOR_TYPE);
185359
+ const oauthResults = await syncOAuthConnectors(oauthConnectors);
185360
+ const stripeResult = await syncStripeConnector(stripeConnector);
185361
+ const results = [...oauthResults];
185362
+ if (stripeResult) {
185363
+ results.push(stripeResult);
185364
+ }
185365
+ return { results };
185366
+ }
185367
+ async function syncOAuthConnectors(connectors) {
185280
185368
  const results = [];
185281
185369
  const upstream = await listConnectors();
185282
185370
  const localTypes = new Set(connectors.map((c) => c.type));
@@ -185309,7 +185397,69 @@ async function pushConnectors(connectors) {
185309
185397
  }
185310
185398
  }
185311
185399
  }
185312
- return { results };
185400
+ return results;
185401
+ }
185402
+ async function syncStripeConnector(localStripe) {
185403
+ const remoteStatus = await fetchStripeRemoteStatus();
185404
+ if (remoteStatus === "error") {
185405
+ return localStripe ? stripeError("Failed to check Stripe integration status") : null;
185406
+ }
185407
+ const isRemoteInstalled = remoteStatus.stripe_mode !== null;
185408
+ const needsInstall = localStripe && !isRemoteInstalled;
185409
+ const alreadySynced = localStripe && isRemoteInstalled;
185410
+ const needsRemoval = !localStripe && isRemoteInstalled;
185411
+ if (needsInstall) {
185412
+ return handleStripeInstall();
185413
+ }
185414
+ if (alreadySynced) {
185415
+ const mode = remoteStatus.stripe_mode;
185416
+ const hasUnclaimedSandbox = mode === "sandbox" && remoteStatus.sandbox_claim_url;
185417
+ return hasUnclaimedSandbox ? stripeProvisioned(mode, remoteStatus.sandbox_claim_url ?? undefined) : stripeSynced();
185418
+ }
185419
+ if (needsRemoval) {
185420
+ return handleStripeRemoval();
185421
+ }
185422
+ return null;
185423
+ }
185424
+ async function fetchStripeRemoteStatus() {
185425
+ try {
185426
+ const status = await getStripeStatus();
185427
+ if (!status)
185428
+ return "error";
185429
+ return status;
185430
+ } catch {
185431
+ return "error";
185432
+ }
185433
+ }
185434
+ async function handleStripeInstall() {
185435
+ try {
185436
+ const result = await installStripe();
185437
+ const status = await fetchStripeRemoteStatus();
185438
+ const mode = status !== "error" && status.stripe_mode ? status.stripe_mode : "sandbox";
185439
+ return stripeProvisioned(mode, result.claim_url ?? undefined);
185440
+ } catch (err) {
185441
+ return stripeError(err instanceof Error ? err.message : String(err));
185442
+ }
185443
+ }
185444
+ async function handleStripeRemoval() {
185445
+ try {
185446
+ await removeStripe();
185447
+ return stripeRemoved();
185448
+ } catch (err) {
185449
+ return stripeError(err instanceof Error ? err.message : String(err));
185450
+ }
185451
+ }
185452
+ function stripeSynced() {
185453
+ return { type: STRIPE_CONNECTOR_TYPE, action: "synced" };
185454
+ }
185455
+ function stripeProvisioned(mode, claimUrl) {
185456
+ return { type: STRIPE_CONNECTOR_TYPE, action: "provisioned", mode, claimUrl };
185457
+ }
185458
+ function stripeRemoved() {
185459
+ return { type: STRIPE_CONNECTOR_TYPE, action: "removed" };
185460
+ }
185461
+ function stripeError(error48) {
185462
+ return { type: STRIPE_CONNECTOR_TYPE, action: "error", error: error48 };
185313
185463
  }
185314
185464
  function getConnectorSyncResult(type, response) {
185315
185465
  if (response.error === "different_user") {
@@ -185327,7 +185477,7 @@ function getConnectorSyncResult(type, response) {
185327
185477
  type,
185328
185478
  action: "needs_oauth",
185329
185479
  redirectUrl: response.redirectUrl,
185330
- connectionId: response.connectionId ?? undefined
185480
+ connectionId: response.connectionId ?? ""
185331
185481
  };
185332
185482
  }
185333
185483
  return { type, action: "synced" };
@@ -193636,6 +193786,10 @@ function getDashboardUrl(projectId) {
193636
193786
  const id = projectId ?? getAppConfig().id;
193637
193787
  return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/overview`;
193638
193788
  }
193789
+ function getConnectorsUrl(projectId) {
193790
+ const id = projectId ?? getAppConfig().id;
193791
+ return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/app-connections`;
193792
+ }
193639
193793
  // src/cli/commands/agents/pull.ts
193640
193794
  async function pullAgentsAction() {
193641
193795
  const { project: project2 } = await readProjectConfig();
@@ -193740,13 +193894,13 @@ async function pullConnectorsAction() {
193740
193894
  const configDir = dirname8(project2.configPath);
193741
193895
  const connectorsDir = join10(configDir, project2.connectorsDir);
193742
193896
  const remoteConnectors = await runTask("Fetching connectors from Base44", async () => {
193743
- return await listConnectors();
193897
+ return await pullAllConnectors();
193744
193898
  }, {
193745
193899
  successMessage: "Connectors fetched successfully",
193746
193900
  errorMessage: "Failed to fetch connectors"
193747
193901
  });
193748
193902
  const { written, deleted } = await runTask("Syncing connector files", async () => {
193749
- return await writeConnectors(connectorsDir, remoteConnectors.integrations);
193903
+ return await writeConnectors(connectorsDir, remoteConnectors);
193750
193904
  }, {
193751
193905
  successMessage: "Connector files synced successfully",
193752
193906
  errorMessage: "Failed to sync connector files"
@@ -193761,7 +193915,7 @@ async function pullConnectorsAction() {
193761
193915
  M2.info("All connectors are already up to date");
193762
193916
  }
193763
193917
  return {
193764
- outroMessage: `Pulled ${remoteConnectors.integrations.length} connectors to ${connectorsDir}`
193918
+ outroMessage: `Pulled ${remoteConnectors.length} connectors to ${connectorsDir}`
193765
193919
  };
193766
193920
  }
193767
193921
  function getConnectorsPullCommand(context) {
@@ -194380,7 +194534,7 @@ var open_default = open;
194380
194534
  var POLL_INTERVAL_MS = 2000;
194381
194535
  var POLL_TIMEOUT_MS = 2 * 60 * 1000;
194382
194536
  function filterPendingOAuth(results) {
194383
- return results.filter((r2) => r2.action === "needs_oauth" && !!r2.redirectUrl && !!r2.connectionId);
194537
+ return results.filter((r2) => r2.action === "needs_oauth");
194384
194538
  }
194385
194539
  async function runOAuthFlowWithSkip(connector2) {
194386
194540
  await open_default(connector2.redirectUrl);
@@ -194462,32 +194616,49 @@ Opening browser for ${connector2.type}...`);
194462
194616
  function printSummary(results, oauthOutcomes) {
194463
194617
  const synced = [];
194464
194618
  const added = [];
194619
+ const provisioned = [];
194465
194620
  const removed = [];
194466
194621
  const skipped = [];
194467
194622
  const failed = [];
194468
194623
  for (const r2 of results) {
194469
- const oauthStatus = oauthOutcomes.get(r2.type);
194470
- if (r2.action === "synced") {
194471
- synced.push(r2.type);
194472
- } else if (r2.action === "removed") {
194473
- removed.push(r2.type);
194474
- } else if (r2.action === "error") {
194475
- failed.push({ type: r2.type, error: r2.error });
194476
- } else if (r2.action === "needs_oauth") {
194477
- if (oauthStatus === "ACTIVE") {
194478
- added.push(r2.type);
194479
- } else if (oauthStatus === "SKIPPED") {
194480
- skipped.push(r2.type);
194481
- } else if (oauthStatus === "PENDING") {
194482
- failed.push({ type: r2.type, error: "authorization timed out" });
194483
- } else if (oauthStatus === "FAILED") {
194484
- failed.push({ type: r2.type, error: "authorization failed" });
194485
- } else {
194486
- failed.push({ type: r2.type, error: "needs authorization" });
194624
+ switch (r2.action) {
194625
+ case "provisioned":
194626
+ provisioned.push(r2);
194627
+ break;
194628
+ case "synced":
194629
+ synced.push(r2.type);
194630
+ break;
194631
+ case "removed":
194632
+ removed.push(r2.type);
194633
+ break;
194634
+ case "error":
194635
+ failed.push({ type: r2.type, error: r2.error });
194636
+ break;
194637
+ case "needs_oauth": {
194638
+ const oauthStatus = oauthOutcomes.get(r2.type);
194639
+ if (oauthStatus === "ACTIVE") {
194640
+ added.push(r2.type);
194641
+ } else if (oauthStatus === "SKIPPED") {
194642
+ skipped.push(r2.type);
194643
+ } else if (oauthStatus === "PENDING") {
194644
+ failed.push({ type: r2.type, error: "authorization timed out" });
194645
+ } else if (oauthStatus === "FAILED") {
194646
+ failed.push({ type: r2.type, error: "authorization failed" });
194647
+ } else {
194648
+ failed.push({ type: r2.type, error: "needs authorization" });
194649
+ }
194650
+ break;
194487
194651
  }
194488
194652
  }
194489
194653
  }
194490
194654
  M2.info(theme.styles.bold("Summary:"));
194655
+ for (const i2 of provisioned) {
194656
+ M2.success(`Provisioned: ${i2.type} (${i2.mode})`);
194657
+ if (i2.claimUrl) {
194658
+ M2.info(` Claim your Stripe account: ${theme.colors.links(i2.claimUrl)}`);
194659
+ }
194660
+ M2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
194661
+ }
194491
194662
  if (synced.length > 0) {
194492
194663
  M2.success(`Synced: ${synced.join(", ")}`);
194493
194664
  }
@@ -194501,7 +194672,7 @@ function printSummary(results, oauthOutcomes) {
194501
194672
  M2.warn(`Skipped: ${skipped.join(", ")}`);
194502
194673
  }
194503
194674
  for (const r2 of failed) {
194504
- M2.error(`Failed: ${r2.type}${r2.error ? ` - ${r2.error}` : ""}`);
194675
+ M2.error(`Failed: ${r2.type} - ${r2.error}`);
194505
194676
  }
194506
194677
  }
194507
194678
  async function pushConnectorsAction() {
@@ -194535,7 +194706,7 @@ function getConnectorsPushCommand(context) {
194535
194706
 
194536
194707
  // src/cli/commands/connectors/index.ts
194537
194708
  function getConnectorsCommand(context) {
194538
- return new Command("connectors").description("Manage project connectors (OAuth integrations)").addCommand(getConnectorsPullCommand(context)).addCommand(getConnectorsPushCommand(context));
194709
+ return new Command("connectors").description("Manage project connectors").addCommand(getConnectorsPullCommand(context)).addCommand(getConnectorsPushCommand(context));
194539
194710
  }
194540
194711
 
194541
194712
  // src/cli/commands/dashboard/open.ts
@@ -194851,15 +195022,11 @@ ${summaryLines.join(`
194851
195022
  successMessage: theme.colors.base44Orange("Deployment completed"),
194852
195023
  errorMessage: "Deployment failed"
194853
195024
  });
194854
- const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
194855
- if (needsOAuth.length > 0) {
194856
- const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
194857
- skipPrompt: options.yes || !!process.env.CI
194858
- });
194859
- const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
194860
- if (!allAuthorized) {
194861
- M2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
194862
- }
195025
+ const connectorResults = result.connectorResults ?? [];
195026
+ await handleOAuthConnectors(connectorResults, options);
195027
+ const stripeResult = connectorResults.find((r2) => r2.action === "provisioned");
195028
+ if (stripeResult) {
195029
+ printStripeResult(stripeResult);
194863
195030
  }
194864
195031
  M2.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
194865
195032
  if (result.appUrl) {
@@ -194872,6 +195039,25 @@ function getDeployCommand(context) {
194872
195039
  await runCommand(() => deployAction(options), { requireAuth: true }, context);
194873
195040
  });
194874
195041
  }
195042
+ async function handleOAuthConnectors(connectorResults, options) {
195043
+ const needsOAuth = filterPendingOAuth(connectorResults);
195044
+ if (needsOAuth.length === 0)
195045
+ return;
195046
+ const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
195047
+ skipPrompt: options.yes || !!process.env.CI
195048
+ });
195049
+ const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
195050
+ if (!allAuthorized) {
195051
+ M2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
195052
+ }
195053
+ }
195054
+ function printStripeResult(r2) {
195055
+ M2.success(`Provisioned: Stripe (${r2.mode})`);
195056
+ if (r2.claimUrl) {
195057
+ M2.info(` Claim your Stripe account: ${theme.colors.links(r2.claimUrl)}`);
195058
+ }
195059
+ M2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
195060
+ }
194875
195061
 
194876
195062
  // src/cli/commands/project/link.ts
194877
195063
  function validateNonInteractiveFlags2(command) {
@@ -199760,4 +199946,4 @@ export {
199760
199946
  CLIExitError
199761
199947
  };
199762
199948
 
199763
- //# debugId=06A844C7F693D30164756E2164756E21
199949
+ //# debugId=52C00CE37DAE994264756E2164756E21