@base44-preview/cli 0.0.31-pr.214.25a02b0 → 0.0.31-pr.214.27ce774
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 +126 -67
- package/dist/cli/index.js.map +9 -8
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -184888,7 +184888,7 @@ var ToolConfigSchema = exports_external.union([
|
|
|
184888
184888
|
BackendFunctionToolConfigSchema
|
|
184889
184889
|
]);
|
|
184890
184890
|
var AgentConfigSchema = exports_external.looseObject({
|
|
184891
|
-
name: exports_external.string().
|
|
184891
|
+
name: exports_external.string().trim().min(1).max(100),
|
|
184892
184892
|
description: exports_external.string().trim().min(1, "Description is required"),
|
|
184893
184893
|
instructions: exports_external.string().trim().min(1, "Instructions are required"),
|
|
184894
184894
|
tool_configs: exports_external.array(ToolConfigSchema).optional().default([]),
|
|
@@ -184944,6 +184944,9 @@ async function fetchAgents() {
|
|
|
184944
184944
|
}
|
|
184945
184945
|
// src/core/resources/agent/config.ts
|
|
184946
184946
|
import { join as join3 } from "node:path";
|
|
184947
|
+
function toFileSlug(name2) {
|
|
184948
|
+
return name2.toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
184949
|
+
}
|
|
184947
184950
|
async function readAgentFile(agentPath) {
|
|
184948
184951
|
const parsed = await readJsonFile(agentPath);
|
|
184949
184952
|
const result = AgentConfigSchema.safeParse(parsed);
|
|
@@ -184975,7 +184978,8 @@ async function writeAgents(agentsDir, remoteAgents) {
|
|
|
184975
184978
|
const newNames = new Set(remoteAgents.map((a) => a.name));
|
|
184976
184979
|
const toDelete = existingAgents.filter((a) => !newNames.has(a.name));
|
|
184977
184980
|
for (const agent of toDelete) {
|
|
184978
|
-
const
|
|
184981
|
+
const slug = toFileSlug(agent.name);
|
|
184982
|
+
const files = await globby(`${slug}.${CONFIG_FILE_EXTENSION_GLOB}`, {
|
|
184979
184983
|
cwd: agentsDir,
|
|
184980
184984
|
absolute: true
|
|
184981
184985
|
});
|
|
@@ -184984,7 +184988,8 @@ async function writeAgents(agentsDir, remoteAgents) {
|
|
|
184984
184988
|
}
|
|
184985
184989
|
}
|
|
184986
184990
|
for (const agent of remoteAgents) {
|
|
184987
|
-
const
|
|
184991
|
+
const slug = toFileSlug(agent.name);
|
|
184992
|
+
const filePath = join3(agentsDir, `${slug}.${CONFIG_FILE_EXTENSION}`);
|
|
184988
184993
|
await writeJsonFile(filePath, agent);
|
|
184989
184994
|
}
|
|
184990
184995
|
const written = remoteAgents.map((a) => a.name);
|
|
@@ -185973,24 +185978,26 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
185973
185978
|
}
|
|
185974
185979
|
// src/core/project/deploy.ts
|
|
185975
185980
|
function hasResourcesToDeploy(projectData) {
|
|
185976
|
-
const { project, entities, functions, agents } = projectData;
|
|
185981
|
+
const { project, entities, functions, agents, connectors } = projectData;
|
|
185977
185982
|
const hasSite = Boolean(project.site?.outputDirectory);
|
|
185978
185983
|
const hasEntities = entities.length > 0;
|
|
185979
185984
|
const hasFunctions = functions.length > 0;
|
|
185980
185985
|
const hasAgents = agents.length > 0;
|
|
185981
|
-
|
|
185986
|
+
const hasConnectors = connectors.length > 0;
|
|
185987
|
+
return hasEntities || hasFunctions || hasAgents || hasConnectors || hasSite;
|
|
185982
185988
|
}
|
|
185983
185989
|
async function deployAll(projectData) {
|
|
185984
|
-
const { project, entities, functions, agents } = projectData;
|
|
185990
|
+
const { project, entities, functions, agents, connectors } = projectData;
|
|
185985
185991
|
await entityResource.push(entities);
|
|
185986
185992
|
await functionResource.push(functions);
|
|
185987
185993
|
await agentResource.push(agents);
|
|
185994
|
+
const { results: connectorResults } = await pushConnectors(connectors);
|
|
185988
185995
|
if (project.site?.outputDirectory) {
|
|
185989
185996
|
const outputDir = resolve(project.root, project.site.outputDirectory);
|
|
185990
185997
|
const { appUrl } = await deploySite(outputDir);
|
|
185991
|
-
return { appUrl };
|
|
185998
|
+
return { appUrl, connectorResults };
|
|
185992
185999
|
}
|
|
185993
|
-
return {};
|
|
186000
|
+
return { connectorResults };
|
|
185994
186001
|
}
|
|
185995
186002
|
// src/core/clients/base44-client.ts
|
|
185996
186003
|
var retriedRequests = new WeakSet;
|
|
@@ -194368,14 +194375,94 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
|
194368
194375
|
}));
|
|
194369
194376
|
var open_default = open;
|
|
194370
194377
|
|
|
194371
|
-
// src/cli/commands/connectors/
|
|
194372
|
-
|
|
194373
|
-
|
|
194378
|
+
// src/cli/commands/connectors/oauth-prompt.ts
|
|
194379
|
+
var POLL_INTERVAL_MS = 2000;
|
|
194380
|
+
var POLL_TIMEOUT_MS = 2 * 60 * 1000;
|
|
194381
|
+
function filterPendingOAuth(results) {
|
|
194382
|
+
return results.filter((r2) => r2.action === "needs_oauth" && !!r2.redirectUrl && !!r2.connectionId);
|
|
194383
|
+
}
|
|
194384
|
+
async function runOAuthFlowWithSkip(connector2) {
|
|
194385
|
+
await open_default(connector2.redirectUrl);
|
|
194386
|
+
let finalStatus = "PENDING";
|
|
194387
|
+
let skipped = false;
|
|
194388
|
+
const s = Y2();
|
|
194389
|
+
const originalExit = process.exit;
|
|
194390
|
+
process.exit = () => {
|
|
194391
|
+
skipped = true;
|
|
194392
|
+
s.stop(`${connector2.type} skipped`);
|
|
194393
|
+
};
|
|
194394
|
+
s.start(`Waiting for ${connector2.type} authorization... (Esc to skip)`);
|
|
194395
|
+
try {
|
|
194396
|
+
await pWaitFor(async () => {
|
|
194397
|
+
if (skipped) {
|
|
194398
|
+
finalStatus = "SKIPPED";
|
|
194399
|
+
return true;
|
|
194400
|
+
}
|
|
194401
|
+
const response = await getOAuthStatus(connector2.type, connector2.connectionId);
|
|
194402
|
+
finalStatus = response.status;
|
|
194403
|
+
return response.status !== "PENDING";
|
|
194404
|
+
}, {
|
|
194405
|
+
interval: POLL_INTERVAL_MS,
|
|
194406
|
+
timeout: POLL_TIMEOUT_MS
|
|
194407
|
+
});
|
|
194408
|
+
} catch (err) {
|
|
194409
|
+
if (err instanceof TimeoutError2) {
|
|
194410
|
+
finalStatus = "PENDING";
|
|
194411
|
+
} else {
|
|
194412
|
+
throw err;
|
|
194413
|
+
}
|
|
194414
|
+
} finally {
|
|
194415
|
+
process.exit = originalExit;
|
|
194416
|
+
if (!skipped) {
|
|
194417
|
+
if (finalStatus === "ACTIVE") {
|
|
194418
|
+
s.stop(`${connector2.type} authorization complete`);
|
|
194419
|
+
} else if (finalStatus === "FAILED") {
|
|
194420
|
+
s.stop(`${connector2.type} authorization failed`);
|
|
194421
|
+
} else {
|
|
194422
|
+
s.stop(`${connector2.type} authorization timed out`);
|
|
194423
|
+
}
|
|
194424
|
+
}
|
|
194425
|
+
}
|
|
194426
|
+
return finalStatus;
|
|
194427
|
+
}
|
|
194428
|
+
async function promptOAuthFlows(pending, options) {
|
|
194429
|
+
const outcomes = new Map;
|
|
194430
|
+
if (pending.length === 0) {
|
|
194431
|
+
return outcomes;
|
|
194432
|
+
}
|
|
194433
|
+
M2.warn(`${pending.length} connector(s) require authorization in your browser:`);
|
|
194434
|
+
for (const connector2 of pending) {
|
|
194435
|
+
M2.info(` ${connector2.type}: ${theme.styles.dim(connector2.redirectUrl)}`);
|
|
194436
|
+
}
|
|
194437
|
+
if (options?.skipPrompt) {
|
|
194438
|
+
return outcomes;
|
|
194439
|
+
}
|
|
194440
|
+
const shouldAuth = await ye({
|
|
194441
|
+
message: "Open browser to authorize now?"
|
|
194442
|
+
});
|
|
194443
|
+
if (pD(shouldAuth) || !shouldAuth) {
|
|
194444
|
+
return outcomes;
|
|
194445
|
+
}
|
|
194446
|
+
for (const connector2 of pending) {
|
|
194447
|
+
try {
|
|
194448
|
+
M2.info(`
|
|
194449
|
+
Opening browser for ${connector2.type}...`);
|
|
194450
|
+
const status = await runOAuthFlowWithSkip(connector2);
|
|
194451
|
+
outcomes.set(connector2.type, status);
|
|
194452
|
+
} catch (err) {
|
|
194453
|
+
M2.error(`Failed to authorize ${connector2.type}: ${err instanceof Error ? err.message : String(err)}`);
|
|
194454
|
+
outcomes.set(connector2.type, "FAILED");
|
|
194455
|
+
}
|
|
194456
|
+
}
|
|
194457
|
+
return outcomes;
|
|
194374
194458
|
}
|
|
194459
|
+
|
|
194460
|
+
// src/cli/commands/connectors/push.ts
|
|
194375
194461
|
function printSummary(results, oauthOutcomes) {
|
|
194376
194462
|
const synced = [];
|
|
194377
194463
|
const added = [];
|
|
194378
194464
|
const removed = [];
|
|
194465
|
+
const skipped = [];
|
|
194379
194466
|
const failed = [];
|
|
194380
194467
|
for (const r2 of results) {
|
|
194381
194468
|
const oauthStatus = oauthOutcomes.get(r2.type);
|
|
@@ -194388,6 +194475,8 @@ function printSummary(results, oauthOutcomes) {
|
|
|
194388
194475
|
} else if (r2.action === "needs_oauth") {
|
|
194389
194476
|
if (oauthStatus === "ACTIVE") {
|
|
194390
194477
|
added.push(r2.type);
|
|
194478
|
+
} else if (oauthStatus === "SKIPPED") {
|
|
194479
|
+
skipped.push(r2.type);
|
|
194391
194480
|
} else if (oauthStatus === "PENDING") {
|
|
194392
194481
|
failed.push({ type: r2.type, error: "authorization timed out" });
|
|
194393
194482
|
} else if (oauthStatus === "FAILED") {
|
|
@@ -194397,7 +194486,6 @@ function printSummary(results, oauthOutcomes) {
|
|
|
194397
194486
|
}
|
|
194398
194487
|
}
|
|
194399
194488
|
}
|
|
194400
|
-
M2.info("");
|
|
194401
194489
|
M2.info(theme.styles.bold("Summary:"));
|
|
194402
194490
|
if (synced.length > 0) {
|
|
194403
194491
|
M2.success(`Synced: ${synced.join(", ")}`);
|
|
@@ -194408,6 +194496,9 @@ function printSummary(results, oauthOutcomes) {
|
|
|
194408
194496
|
if (removed.length > 0) {
|
|
194409
194497
|
M2.info(theme.styles.dim(`Removed: ${removed.join(", ")}`));
|
|
194410
194498
|
}
|
|
194499
|
+
if (skipped.length > 0) {
|
|
194500
|
+
M2.warn(`Skipped: ${skipped.join(", ")}`);
|
|
194501
|
+
}
|
|
194411
194502
|
for (const r2 of failed) {
|
|
194412
194503
|
M2.error(`Failed: ${r2.type}${r2.error ? ` - ${r2.error}` : ""}`);
|
|
194413
194504
|
}
|
|
@@ -194423,59 +194514,14 @@ async function pushConnectorsAction() {
|
|
|
194423
194514
|
const { results } = await runTask("Pushing connectors to Base44", async () => {
|
|
194424
194515
|
return await pushConnectors(connectors);
|
|
194425
194516
|
});
|
|
194426
|
-
const
|
|
194427
|
-
const needsOAuth = results.filter(isPendingOAuth);
|
|
194517
|
+
const needsOAuth = filterPendingOAuth(results);
|
|
194428
194518
|
let outroMessage = "Connectors pushed to Base44";
|
|
194429
|
-
|
|
194430
|
-
|
|
194431
|
-
|
|
194432
|
-
|
|
194433
|
-
|
|
194434
|
-
|
|
194435
|
-
M2.info(` '${connector2.type}': ${theme.styles.dim(connector2.redirectUrl)}`);
|
|
194436
|
-
}
|
|
194437
|
-
const pending = needsOAuth.map((c3) => c3.type).join(", ");
|
|
194438
|
-
if (process.env.CI) {
|
|
194439
|
-
outroMessage = `Skipped OAuth in CI. Pending: ${pending}. Run 'base44 connectors push' locally to authorize.`;
|
|
194440
|
-
} else {
|
|
194441
|
-
const shouldAuth = await ye({
|
|
194442
|
-
message: "Open browser to authorize now?"
|
|
194443
|
-
});
|
|
194444
|
-
if (pD(shouldAuth) || !shouldAuth) {
|
|
194445
|
-
outroMessage = `Authorization skipped. Pending: ${pending}. Run 'base44 connectors push' again to complete.`;
|
|
194446
|
-
} else {
|
|
194447
|
-
for (const connector2 of needsOAuth) {
|
|
194448
|
-
try {
|
|
194449
|
-
M2.info(`
|
|
194450
|
-
Opening browser for '${connector2.type}'...`);
|
|
194451
|
-
await open_default(connector2.redirectUrl);
|
|
194452
|
-
let finalStatus = "PENDING";
|
|
194453
|
-
await runTask(`Waiting for '${connector2.type}' authorization...`, async () => {
|
|
194454
|
-
await pWaitFor(async () => {
|
|
194455
|
-
const response = await getOAuthStatus(connector2.type, connector2.connectionId);
|
|
194456
|
-
finalStatus = response.status;
|
|
194457
|
-
return response.status !== "PENDING";
|
|
194458
|
-
}, {
|
|
194459
|
-
interval: 2000,
|
|
194460
|
-
timeout: 2 * 60 * 1000
|
|
194461
|
-
});
|
|
194462
|
-
}, {
|
|
194463
|
-
successMessage: `'${connector2.type}' authorization complete`,
|
|
194464
|
-
errorMessage: `'${connector2.type}' authorization failed`
|
|
194465
|
-
}).catch((err) => {
|
|
194466
|
-
if (err instanceof TimeoutError2) {
|
|
194467
|
-
finalStatus = "PENDING";
|
|
194468
|
-
} else {
|
|
194469
|
-
throw err;
|
|
194470
|
-
}
|
|
194471
|
-
});
|
|
194472
|
-
oauthOutcomes.set(connector2.type, finalStatus);
|
|
194473
|
-
} catch (err) {
|
|
194474
|
-
M2.error(`Failed to authorize '${connector2.type}': ${err instanceof Error ? err.message : String(err)}`);
|
|
194475
|
-
oauthOutcomes.set(connector2.type, "FAILED");
|
|
194476
|
-
}
|
|
194477
|
-
}
|
|
194478
|
-
}
|
|
194519
|
+
const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
|
|
194520
|
+
skipPrompt: !!process.env.CI
|
|
194521
|
+
});
|
|
194522
|
+
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
194523
|
+
if (needsOAuth.length > 0 && !allAuthorized) {
|
|
194524
|
+
outroMessage = process.env.CI ? "Skipped OAuth in CI. Run 'base44 connectors push' locally or open the links above to authorize." : "Some connectors still require authorization. Run 'base44 connectors push' or open the links above to authorize.";
|
|
194479
194525
|
}
|
|
194480
194526
|
printSummary(results, oauthOutcomes);
|
|
194481
194527
|
return { outroMessage };
|
|
@@ -194766,7 +194812,7 @@ async function deployAction(options) {
|
|
|
194766
194812
|
outroMessage: "No resources found to deploy"
|
|
194767
194813
|
};
|
|
194768
194814
|
}
|
|
194769
|
-
const { project: project2, entities, functions, agents } = projectData;
|
|
194815
|
+
const { project: project2, entities, functions, agents, connectors } = projectData;
|
|
194770
194816
|
const summaryLines = [];
|
|
194771
194817
|
if (entities.length > 0) {
|
|
194772
194818
|
summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
|
|
@@ -194777,6 +194823,9 @@ async function deployAction(options) {
|
|
|
194777
194823
|
if (agents.length > 0) {
|
|
194778
194824
|
summaryLines.push(` - ${agents.length} ${agents.length === 1 ? "agent" : "agents"}`);
|
|
194779
194825
|
}
|
|
194826
|
+
if (connectors.length > 0) {
|
|
194827
|
+
summaryLines.push(` - ${connectors.length} ${connectors.length === 1 ? "connector" : "connectors"}`);
|
|
194828
|
+
}
|
|
194780
194829
|
if (project2.site?.outputDirectory) {
|
|
194781
194830
|
summaryLines.push(` - Site from ${project2.site.outputDirectory}`);
|
|
194782
194831
|
}
|
|
@@ -194801,6 +194850,16 @@ ${summaryLines.join(`
|
|
|
194801
194850
|
successMessage: theme.colors.base44Orange("Deployment completed"),
|
|
194802
194851
|
errorMessage: "Deployment failed"
|
|
194803
194852
|
});
|
|
194853
|
+
const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
|
|
194854
|
+
if (needsOAuth.length > 0) {
|
|
194855
|
+
const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
|
|
194856
|
+
skipPrompt: options.yes || !!process.env.CI
|
|
194857
|
+
});
|
|
194858
|
+
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
194859
|
+
if (!allAuthorized) {
|
|
194860
|
+
M2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
|
|
194861
|
+
}
|
|
194862
|
+
}
|
|
194804
194863
|
M2.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
|
|
194805
194864
|
if (result.appUrl) {
|
|
194806
194865
|
M2.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
|
|
@@ -194808,7 +194867,7 @@ ${summaryLines.join(`
|
|
|
194808
194867
|
return { outroMessage: "App deployed successfully" };
|
|
194809
194868
|
}
|
|
194810
194869
|
function getDeployCommand(context) {
|
|
194811
|
-
return new Command("deploy").description("Deploy all project resources (entities, functions, agents, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
194870
|
+
return new Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
194812
194871
|
await runCommand(() => deployAction(options), { requireAuth: true }, context);
|
|
194813
194872
|
});
|
|
194814
194873
|
}
|
|
@@ -199699,4 +199758,4 @@ export {
|
|
|
199699
199758
|
CLIExitError
|
|
199700
199759
|
};
|
|
199701
199760
|
|
|
199702
|
-
//# debugId=
|
|
199761
|
+
//# debugId=F8EEF50D0741958B64756E2164756E21
|