@base44-preview/cli 0.0.25-pr.104.089a20e → 0.0.25-pr.104.a8520b5
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/index.js +106 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8038,6 +8038,19 @@ var AuthValidationError = class extends Error {
|
|
|
8038
8038
|
this.name = "AuthValidationError";
|
|
8039
8039
|
}
|
|
8040
8040
|
};
|
|
8041
|
+
var ConnectorApiError = class extends Error {
|
|
8042
|
+
constructor(message, cause) {
|
|
8043
|
+
super(message);
|
|
8044
|
+
this.cause = cause;
|
|
8045
|
+
this.name = "ConnectorApiError";
|
|
8046
|
+
}
|
|
8047
|
+
};
|
|
8048
|
+
var ConnectorValidationError = class extends Error {
|
|
8049
|
+
constructor(message) {
|
|
8050
|
+
super(message);
|
|
8051
|
+
this.name = "ConnectorValidationError";
|
|
8052
|
+
}
|
|
8053
|
+
};
|
|
8041
8054
|
|
|
8042
8055
|
//#endregion
|
|
8043
8056
|
//#region src/core/consts.ts
|
|
@@ -30793,7 +30806,7 @@ function getAppClient() {
|
|
|
30793
30806
|
|
|
30794
30807
|
//#endregion
|
|
30795
30808
|
//#region src/core/clients/schemas.ts
|
|
30796
|
-
const ApiErrorSchema = object({
|
|
30809
|
+
const ApiErrorSchema$1 = object({
|
|
30797
30810
|
error_type: string().optional(),
|
|
30798
30811
|
message: union([string(), record(string(), unknown())]).optional(),
|
|
30799
30812
|
detail: union([
|
|
@@ -39278,13 +39291,7 @@ const InitiateResponseSchema = object({
|
|
|
39278
39291
|
already_authorized: boolean().nullish(),
|
|
39279
39292
|
other_user_email: string().nullish(),
|
|
39280
39293
|
error: string().nullish()
|
|
39281
|
-
})
|
|
39282
|
-
redirectUrl: data.redirect_url,
|
|
39283
|
-
connectionId: data.connection_id,
|
|
39284
|
-
alreadyAuthorized: data.already_authorized,
|
|
39285
|
-
otherUserEmail: data.other_user_email,
|
|
39286
|
-
error: data.error
|
|
39287
|
-
}));
|
|
39294
|
+
});
|
|
39288
39295
|
/**
|
|
39289
39296
|
* Response from GET /api/apps/{app_id}/external-auth/status
|
|
39290
39297
|
*/
|
|
@@ -39322,6 +39329,13 @@ const ConnectorSchema = object({
|
|
|
39322
39329
|
* Response from GET /api/apps/{app_id}/external-auth/list
|
|
39323
39330
|
*/
|
|
39324
39331
|
const ListResponseSchema = object({ integrations: array(ConnectorSchema) });
|
|
39332
|
+
/**
|
|
39333
|
+
* Generic API error response
|
|
39334
|
+
*/
|
|
39335
|
+
const ApiErrorSchema = object({
|
|
39336
|
+
error: string(),
|
|
39337
|
+
detail: string().nullish()
|
|
39338
|
+
});
|
|
39325
39339
|
|
|
39326
39340
|
//#endregion
|
|
39327
39341
|
//#region src/core/connectors/api.ts
|
|
@@ -39330,45 +39344,92 @@ const ListResponseSchema = object({ integrations: array(ConnectorSchema) });
|
|
|
39330
39344
|
* Returns a redirect URL to open in the browser.
|
|
39331
39345
|
*/
|
|
39332
39346
|
async function initiateOAuth(integrationType, scopes = null) {
|
|
39333
|
-
const
|
|
39334
|
-
|
|
39335
|
-
|
|
39336
|
-
|
|
39337
|
-
|
|
39347
|
+
const response = await getAppClient().post("external-auth/initiate", {
|
|
39348
|
+
json: {
|
|
39349
|
+
integration_type: integrationType,
|
|
39350
|
+
scopes
|
|
39351
|
+
},
|
|
39352
|
+
throwHttpErrors: false
|
|
39353
|
+
});
|
|
39354
|
+
const json = await response.json();
|
|
39355
|
+
if (!response.ok) {
|
|
39356
|
+
const errorResult = ApiErrorSchema.safeParse(json);
|
|
39357
|
+
if (errorResult.success) throw new ConnectorApiError(errorResult.data.error);
|
|
39358
|
+
throw new ConnectorApiError(`Failed to initiate OAuth: ${response.status} ${response.statusText}`);
|
|
39359
|
+
}
|
|
39360
|
+
const result = InitiateResponseSchema.safeParse(json);
|
|
39361
|
+
if (!result.success) throw new ConnectorValidationError(`Invalid initiate response from server: ${result.error.message}`);
|
|
39362
|
+
return result.data;
|
|
39338
39363
|
}
|
|
39339
39364
|
/**
|
|
39340
39365
|
* Checks the status of an OAuth connection attempt.
|
|
39341
39366
|
*/
|
|
39342
39367
|
async function checkOAuthStatus(integrationType, connectionId) {
|
|
39343
|
-
const
|
|
39344
|
-
|
|
39345
|
-
|
|
39346
|
-
|
|
39347
|
-
|
|
39368
|
+
const response = await getAppClient().get("external-auth/status", {
|
|
39369
|
+
searchParams: {
|
|
39370
|
+
integration_type: integrationType,
|
|
39371
|
+
connection_id: connectionId
|
|
39372
|
+
},
|
|
39373
|
+
throwHttpErrors: false
|
|
39374
|
+
});
|
|
39375
|
+
const json = await response.json();
|
|
39376
|
+
if (!response.ok) {
|
|
39377
|
+
const errorResult = ApiErrorSchema.safeParse(json);
|
|
39378
|
+
if (errorResult.success) throw new ConnectorApiError(errorResult.data.error);
|
|
39379
|
+
throw new ConnectorApiError(`Failed to check OAuth status: ${response.status} ${response.statusText}`);
|
|
39380
|
+
}
|
|
39381
|
+
const result = StatusResponseSchema.safeParse(json);
|
|
39382
|
+
if (!result.success) throw new ConnectorValidationError(`Invalid status response from server: ${result.error.message}`);
|
|
39383
|
+
return result.data;
|
|
39348
39384
|
}
|
|
39349
39385
|
/**
|
|
39350
39386
|
* Lists all connected integrations for the current app.
|
|
39351
39387
|
*/
|
|
39352
39388
|
async function listConnectors() {
|
|
39353
|
-
const
|
|
39354
|
-
|
|
39389
|
+
const response = await getAppClient().get("external-auth/list", { throwHttpErrors: false });
|
|
39390
|
+
const json = await response.json();
|
|
39391
|
+
if (!response.ok) {
|
|
39392
|
+
const errorResult = ApiErrorSchema.safeParse(json);
|
|
39393
|
+
if (errorResult.success) throw new ConnectorApiError(errorResult.data.error);
|
|
39394
|
+
throw new ConnectorApiError(`Failed to list connectors: ${response.status} ${response.statusText}`);
|
|
39395
|
+
}
|
|
39396
|
+
const result = ListResponseSchema.safeParse(json);
|
|
39397
|
+
if (!result.success) throw new ConnectorValidationError(`Invalid list response from server: ${result.error.message}`);
|
|
39398
|
+
return result.data.integrations;
|
|
39355
39399
|
}
|
|
39356
39400
|
/**
|
|
39357
39401
|
* Disconnects (soft delete) a connector integration.
|
|
39358
39402
|
*/
|
|
39359
39403
|
async function disconnectConnector(integrationType) {
|
|
39360
|
-
await getAppClient().delete(`external-auth/integrations/${integrationType}
|
|
39404
|
+
const response = await getAppClient().delete(`external-auth/integrations/${integrationType}`, { throwHttpErrors: false });
|
|
39405
|
+
if (!response.ok) {
|
|
39406
|
+
const json = await response.json();
|
|
39407
|
+
const errorResult = ApiErrorSchema.safeParse(json);
|
|
39408
|
+
if (errorResult.success) throw new ConnectorApiError(errorResult.data.error);
|
|
39409
|
+
throw new ConnectorApiError(`Failed to disconnect connector: ${response.status} ${response.statusText}`);
|
|
39410
|
+
}
|
|
39361
39411
|
}
|
|
39362
39412
|
/**
|
|
39363
39413
|
* Removes (hard delete) a connector integration.
|
|
39364
39414
|
* This permanently removes the connector and cannot be undone.
|
|
39365
39415
|
*/
|
|
39366
39416
|
async function removeConnector(integrationType) {
|
|
39367
|
-
await getAppClient().delete(`external-auth/integrations/${integrationType}/remove
|
|
39417
|
+
const response = await getAppClient().delete(`external-auth/integrations/${integrationType}/remove`, { throwHttpErrors: false });
|
|
39418
|
+
if (!response.ok) {
|
|
39419
|
+
const json = await response.json();
|
|
39420
|
+
const errorResult = ApiErrorSchema.safeParse(json);
|
|
39421
|
+
if (errorResult.success) throw new ConnectorApiError(errorResult.data.error);
|
|
39422
|
+
throw new ConnectorApiError(`Failed to remove connector: ${response.status} ${response.statusText}`);
|
|
39423
|
+
}
|
|
39368
39424
|
}
|
|
39369
39425
|
|
|
39370
39426
|
//#endregion
|
|
39371
|
-
//#region src/core/connectors/
|
|
39427
|
+
//#region src/core/connectors/constants.ts
|
|
39428
|
+
/**
|
|
39429
|
+
* OAuth polling configuration
|
|
39430
|
+
*/
|
|
39431
|
+
const OAUTH_POLL_INTERVAL_MS = 2e3;
|
|
39432
|
+
const OAUTH_POLL_TIMEOUT_MS = 300 * 1e3;
|
|
39372
39433
|
/**
|
|
39373
39434
|
* Supported OAuth connector integrations.
|
|
39374
39435
|
* Based on apper/backend/app/external_auth/models/constants.py
|
|
@@ -39408,13 +39469,12 @@ function isValidIntegration(type) {
|
|
|
39408
39469
|
return SUPPORTED_INTEGRATIONS.includes(type);
|
|
39409
39470
|
}
|
|
39410
39471
|
function getIntegrationDisplayName(type) {
|
|
39411
|
-
return INTEGRATION_DISPLAY_NAMES[type]
|
|
39472
|
+
if (isValidIntegration(type)) return INTEGRATION_DISPLAY_NAMES[type];
|
|
39473
|
+
return type;
|
|
39412
39474
|
}
|
|
39413
39475
|
|
|
39414
39476
|
//#endregion
|
|
39415
|
-
//#region src/
|
|
39416
|
-
const OAUTH_POLL_INTERVAL_MS = 2e3;
|
|
39417
|
-
const OAUTH_POLL_TIMEOUT_MS = 300 * 1e3;
|
|
39477
|
+
//#region src/core/connectors/oauth.ts
|
|
39418
39478
|
/**
|
|
39419
39479
|
* Polls for OAuth completion status.
|
|
39420
39480
|
* Returns when status becomes ACTIVE or FAILED, or times out.
|
|
@@ -39454,24 +39514,22 @@ async function waitForOAuthCompletion(integrationType, connectionId, options) {
|
|
|
39454
39514
|
};
|
|
39455
39515
|
}
|
|
39456
39516
|
}
|
|
39457
|
-
/**
|
|
39458
|
-
* Asserts that a string is a valid integration type, throwing if not.
|
|
39459
|
-
*/
|
|
39460
|
-
function assertValidIntegrationType(type, supportedIntegrations) {
|
|
39461
|
-
if (!supportedIntegrations.includes(type)) {
|
|
39462
|
-
const supportedList = supportedIntegrations.join(", ");
|
|
39463
|
-
throw new Error(`Unsupported connector: ${type}\nSupported connectors: ${supportedList}`);
|
|
39464
|
-
}
|
|
39465
|
-
}
|
|
39466
39517
|
|
|
39467
39518
|
//#endregion
|
|
39468
39519
|
//#region src/cli/commands/connectors/add.ts
|
|
39520
|
+
function validateIntegrationType(type) {
|
|
39521
|
+
if (!isValidIntegration(type)) {
|
|
39522
|
+
const supportedList = SUPPORTED_INTEGRATIONS.join(", ");
|
|
39523
|
+
throw new Error(`Unsupported connector: ${type}\nSupported connectors: ${supportedList}`);
|
|
39524
|
+
}
|
|
39525
|
+
return type;
|
|
39526
|
+
}
|
|
39469
39527
|
async function promptForIntegrationType() {
|
|
39470
39528
|
const selected = await ve({
|
|
39471
39529
|
message: "Select an integration to connect:",
|
|
39472
|
-
options:
|
|
39530
|
+
options: SUPPORTED_INTEGRATIONS.map((type) => ({
|
|
39473
39531
|
value: type,
|
|
39474
|
-
label:
|
|
39532
|
+
label: getIntegrationDisplayName(type)
|
|
39475
39533
|
}))
|
|
39476
39534
|
});
|
|
39477
39535
|
if (pD(selected)) {
|
|
@@ -39489,11 +39547,7 @@ async function pollForOAuthCompletion(integrationType, connectionId) {
|
|
|
39489
39547
|
});
|
|
39490
39548
|
}
|
|
39491
39549
|
async function addConnector(integrationType) {
|
|
39492
|
-
|
|
39493
|
-
if (integrationType) {
|
|
39494
|
-
assertValidIntegrationType(integrationType, SUPPORTED_INTEGRATIONS);
|
|
39495
|
-
selectedType = integrationType;
|
|
39496
|
-
} else selectedType = await promptForIntegrationType();
|
|
39550
|
+
const selectedType = integrationType ? validateIntegrationType(integrationType) : await promptForIntegrationType();
|
|
39497
39551
|
const displayName = getIntegrationDisplayName(selectedType);
|
|
39498
39552
|
const initiateResponse = await runTask(`Initiating ${displayName} connection...`, async () => {
|
|
39499
39553
|
return await initiateOAuth(selectedType);
|
|
@@ -39501,11 +39555,11 @@ async function addConnector(integrationType) {
|
|
|
39501
39555
|
successMessage: `${displayName} OAuth initiated`,
|
|
39502
39556
|
errorMessage: `Failed to initiate ${displayName} connection`
|
|
39503
39557
|
});
|
|
39504
|
-
if (initiateResponse.
|
|
39505
|
-
if (initiateResponse.error === "different_user" && initiateResponse.
|
|
39506
|
-
if (!initiateResponse.
|
|
39507
|
-
M.info(`Please authorize ${displayName} at:\n${theme.colors.links(initiateResponse.
|
|
39508
|
-
const result = await pollForOAuthCompletion(selectedType, initiateResponse.
|
|
39558
|
+
if (initiateResponse.already_authorized) return { outroMessage: `Already connected to ${theme.styles.bold(displayName)}` };
|
|
39559
|
+
if (initiateResponse.error === "different_user" && initiateResponse.other_user_email) throw new Error(`This app is already connected to ${displayName} by ${initiateResponse.other_user_email}`);
|
|
39560
|
+
if (!initiateResponse.redirect_url || !initiateResponse.connection_id) throw new Error("Invalid response from server: missing redirect URL or connection ID");
|
|
39561
|
+
M.info(`Please authorize ${displayName} at:\n${theme.colors.links(initiateResponse.redirect_url)}`);
|
|
39562
|
+
const result = await pollForOAuthCompletion(selectedType, initiateResponse.connection_id);
|
|
39509
39563
|
if (!result.success) throw new Error(result.error || "Authorization failed");
|
|
39510
39564
|
const accountInfo = result.accountEmail ? ` as ${theme.styles.bold(result.accountEmail)}` : "";
|
|
39511
39565
|
return { outroMessage: `Successfully connected to ${theme.styles.bold(displayName)}${accountInfo}` };
|
|
@@ -39561,7 +39615,10 @@ async function removeConnectorCommand(integrationType, options = {}) {
|
|
|
39561
39615
|
const displayName = selectedConnector.displayName;
|
|
39562
39616
|
const accountInfo = selectedConnector.accountEmail ? ` (${selectedConnector.accountEmail})` : "";
|
|
39563
39617
|
if (!options.yes) {
|
|
39564
|
-
const shouldRemove = await ye({
|
|
39618
|
+
const shouldRemove = await ye({
|
|
39619
|
+
message: `${isHardDelete ? "Permanently remove" : "Remove"} ${displayName}${accountInfo}?`,
|
|
39620
|
+
initialValue: false
|
|
39621
|
+
});
|
|
39565
39622
|
if (pD(shouldRemove) || !shouldRemove) {
|
|
39566
39623
|
xe("Operation cancelled.");
|
|
39567
39624
|
process.exit(0);
|