@base44-preview/cli 0.0.41-pr.398.11ec41f → 0.0.42-pr.404.3bbaa16
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 +299 -67
- package/dist/cli/index.js.map +18 -16
- package/package.json +3 -2
package/dist/cli/index.js
CHANGED
|
@@ -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
|
|
16484
|
+
var pull2 = 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 =
|
|
18249
|
+
lodash.pull = pull2;
|
|
18250
18250
|
lodash.pullAll = pullAll;
|
|
18251
18251
|
lodash.pullAllBy = pullAllBy;
|
|
18252
18252
|
lodash.pullAllWith = pullAllWith;
|
|
@@ -161575,7 +161575,7 @@ var require_is_promise = __commonJS((exports, module) => {
|
|
|
161575
161575
|
}
|
|
161576
161576
|
});
|
|
161577
161577
|
|
|
161578
|
-
// ../../node_modules/
|
|
161578
|
+
// ../../node_modules/path-to-regexp/dist/index.js
|
|
161579
161579
|
var require_dist = __commonJS((exports) => {
|
|
161580
161580
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
161581
161581
|
exports.PathError = exports.TokenData = undefined;
|
|
@@ -237514,6 +237514,10 @@ 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
|
+
});
|
|
237517
237521
|
var CustomTypeSchema = exports_external.string().min(1).regex(/^[a-z0-9_-]+$/i);
|
|
237518
237522
|
var GenericConnectorSchema = exports_external.object({
|
|
237519
237523
|
type: CustomTypeSchema,
|
|
@@ -237533,6 +237537,7 @@ var ConnectorResourceSchema = exports_external.union([
|
|
|
237533
237537
|
HubspotConnectorSchema,
|
|
237534
237538
|
LinkedInConnectorSchema,
|
|
237535
237539
|
TikTokConnectorSchema,
|
|
237540
|
+
StripeConnectorSchema,
|
|
237536
237541
|
GenericConnectorSchema
|
|
237537
237542
|
]);
|
|
237538
237543
|
var KnownIntegrationTypes = [
|
|
@@ -237548,7 +237553,8 @@ var KnownIntegrationTypes = [
|
|
|
237548
237553
|
"salesforce",
|
|
237549
237554
|
"hubspot",
|
|
237550
237555
|
"linkedin",
|
|
237551
|
-
"tiktok"
|
|
237556
|
+
"tiktok",
|
|
237557
|
+
"stripe"
|
|
237552
237558
|
];
|
|
237553
237559
|
var IntegrationTypeSchema = exports_external.union([
|
|
237554
237560
|
exports_external.enum(KnownIntegrationTypes),
|
|
@@ -237601,6 +237607,24 @@ var RemoveConnectorResponseSchema = exports_external.object({
|
|
|
237601
237607
|
status: data.status,
|
|
237602
237608
|
integrationType: data.integration_type
|
|
237603
237609
|
}));
|
|
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
|
+
});
|
|
237604
237628
|
var ConnectionConfigFieldSchema = exports_external.object({
|
|
237605
237629
|
name: exports_external.string(),
|
|
237606
237630
|
display_name: exports_external.string(),
|
|
@@ -237715,6 +237739,54 @@ async function removeConnector(integrationType) {
|
|
|
237715
237739
|
}
|
|
237716
237740
|
return result.data;
|
|
237717
237741
|
}
|
|
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
|
+
}
|
|
237718
237790
|
// src/core/resources/connector/config.ts
|
|
237719
237791
|
import { join as join4 } from "node:path";
|
|
237720
237792
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
@@ -237763,7 +237835,7 @@ async function readAllConnectors(connectorsDir) {
|
|
|
237763
237835
|
async function writeConnectors(connectorsDir, remoteConnectors) {
|
|
237764
237836
|
const entries = await readConnectorFiles(connectorsDir);
|
|
237765
237837
|
const typeToEntry = buildTypeToEntryMap(entries);
|
|
237766
|
-
const newTypes = new Set(remoteConnectors.map((c) => c.
|
|
237838
|
+
const newTypes = new Set(remoteConnectors.map((c) => c.type));
|
|
237767
237839
|
const deleted = [];
|
|
237768
237840
|
for (const [type, entry] of typeToEntry) {
|
|
237769
237841
|
if (!newTypes.has(type)) {
|
|
@@ -237773,22 +237845,105 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
|
|
|
237773
237845
|
}
|
|
237774
237846
|
const written = [];
|
|
237775
237847
|
for (const connector of remoteConnectors) {
|
|
237776
|
-
const existing = typeToEntry.get(connector.
|
|
237777
|
-
|
|
237778
|
-
type: connector.integrationType,
|
|
237779
|
-
scopes: connector.scopes
|
|
237780
|
-
};
|
|
237781
|
-
if (existing && isDeepStrictEqual2(existing.data, localConnector)) {
|
|
237848
|
+
const existing = typeToEntry.get(connector.type);
|
|
237849
|
+
if (existing && isDeepStrictEqual2(existing.data, connector)) {
|
|
237782
237850
|
continue;
|
|
237783
237851
|
}
|
|
237784
|
-
const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.
|
|
237785
|
-
await writeJsonFile(filePath,
|
|
237786
|
-
written.push(connector.
|
|
237852
|
+
const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
|
|
237853
|
+
await writeJsonFile(filePath, connector);
|
|
237854
|
+
written.push(connector.type);
|
|
237787
237855
|
}
|
|
237788
237856
|
return { written, deleted };
|
|
237789
237857
|
}
|
|
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
|
+
}
|
|
237790
237934
|
// src/core/resources/connector/push.ts
|
|
237791
237935
|
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) {
|
|
237792
237947
|
const results = [];
|
|
237793
237948
|
const upstream = await listConnectors();
|
|
237794
237949
|
const localTypes = new Set(connectors.map((c) => c.type));
|
|
@@ -237821,7 +237976,7 @@ async function pushConnectors(connectors) {
|
|
|
237821
237976
|
}
|
|
237822
237977
|
}
|
|
237823
237978
|
}
|
|
237824
|
-
return
|
|
237979
|
+
return results;
|
|
237825
237980
|
}
|
|
237826
237981
|
function getConnectorSyncResult(type, response) {
|
|
237827
237982
|
if (response.error === "different_user") {
|
|
@@ -238402,7 +238557,7 @@ import { join as join7 } from "node:path";
|
|
|
238402
238557
|
// package.json
|
|
238403
238558
|
var package_default = {
|
|
238404
238559
|
name: "base44",
|
|
238405
|
-
version: "0.0.
|
|
238560
|
+
version: "0.0.42",
|
|
238406
238561
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
238407
238562
|
type: "module",
|
|
238408
238563
|
bin: {
|
|
@@ -238421,6 +238576,8 @@ var package_default = {
|
|
|
238421
238576
|
start: "./bin/run.js",
|
|
238422
238577
|
clean: "rm -rf dist && mkdir -p dist",
|
|
238423
238578
|
test: "vitest run",
|
|
238579
|
+
"test:npm": "CLI_TEST_RUNNER=npm vitest run",
|
|
238580
|
+
"test:binary": "CLI_TEST_RUNNER=binary vitest run",
|
|
238424
238581
|
"test:watch": "vitest",
|
|
238425
238582
|
lint: "cd ../.. && bun run lint",
|
|
238426
238583
|
"lint:fix": "cd ../.. && bun run lint:fix",
|
|
@@ -238469,7 +238626,6 @@ var package_default = {
|
|
|
238469
238626
|
json5: "^2.2.3",
|
|
238470
238627
|
ky: "^1.14.2",
|
|
238471
238628
|
lodash: "^4.17.23",
|
|
238472
|
-
msw: "^2.12.10",
|
|
238473
238629
|
multer: "^2.0.0",
|
|
238474
238630
|
nanoid: "^5.1.6",
|
|
238475
238631
|
open: "^11.0.0",
|
|
@@ -246336,6 +246492,10 @@ function getDashboardUrl(projectId) {
|
|
|
246336
246492
|
const id = projectId ?? getAppConfig().id;
|
|
246337
246493
|
return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/overview`;
|
|
246338
246494
|
}
|
|
246495
|
+
function getConnectorsUrl(projectId) {
|
|
246496
|
+
const id = projectId ?? getAppConfig().id;
|
|
246497
|
+
return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/app-connections`;
|
|
246498
|
+
}
|
|
246339
246499
|
// src/cli/utils/yaml.ts
|
|
246340
246500
|
var import_lodash = __toESM(require_lodash(), 1);
|
|
246341
246501
|
|
|
@@ -246531,13 +246691,13 @@ async function pullConnectorsAction() {
|
|
|
246531
246691
|
const configDir = dirname8(project2.configPath);
|
|
246532
246692
|
const connectorsDir = join11(configDir, project2.connectorsDir);
|
|
246533
246693
|
const remoteConnectors = await runTask("Fetching connectors from Base44", async () => {
|
|
246534
|
-
return await
|
|
246694
|
+
return await pullAllConnectors();
|
|
246535
246695
|
}, {
|
|
246536
246696
|
successMessage: "Connectors fetched successfully",
|
|
246537
246697
|
errorMessage: "Failed to fetch connectors"
|
|
246538
246698
|
});
|
|
246539
246699
|
const { written, deleted } = await runTask("Syncing connector files", async () => {
|
|
246540
|
-
return await writeConnectors(connectorsDir, remoteConnectors
|
|
246700
|
+
return await writeConnectors(connectorsDir, remoteConnectors);
|
|
246541
246701
|
}, {
|
|
246542
246702
|
successMessage: "Connector files synced successfully",
|
|
246543
246703
|
errorMessage: "Failed to sync connector files"
|
|
@@ -246552,7 +246712,7 @@ async function pullConnectorsAction() {
|
|
|
246552
246712
|
R2.info("All connectors are already up to date");
|
|
246553
246713
|
}
|
|
246554
246714
|
return {
|
|
246555
|
-
outroMessage: `Pulled ${remoteConnectors.
|
|
246715
|
+
outroMessage: `Pulled ${remoteConnectors.length} connectors to ${connectorsDir}`
|
|
246556
246716
|
};
|
|
246557
246717
|
}
|
|
246558
246718
|
function getConnectorsPullCommand(context) {
|
|
@@ -247171,7 +247331,7 @@ var open_default = open;
|
|
|
247171
247331
|
var POLL_INTERVAL_MS = 2000;
|
|
247172
247332
|
var POLL_TIMEOUT_MS = 2 * 60 * 1000;
|
|
247173
247333
|
function filterPendingOAuth(results) {
|
|
247174
|
-
return results.filter((r) => r.action === "needs_oauth" && !!r.
|
|
247334
|
+
return results.filter((r) => r.action === "needs_oauth" && !!r.connectionId);
|
|
247175
247335
|
}
|
|
247176
247336
|
async function runOAuthFlowWithSkip(connector2) {
|
|
247177
247337
|
await open_default(connector2.redirectUrl);
|
|
@@ -247189,6 +247349,10 @@ async function runOAuthFlowWithSkip(connector2) {
|
|
|
247189
247349
|
finalStatus = "SKIPPED";
|
|
247190
247350
|
return true;
|
|
247191
247351
|
}
|
|
247352
|
+
if (!connector2.connectionId) {
|
|
247353
|
+
finalStatus = "FAILED";
|
|
247354
|
+
return true;
|
|
247355
|
+
}
|
|
247192
247356
|
const response = await getOAuthStatus(connector2.type, connector2.connectionId);
|
|
247193
247357
|
finalStatus = response.status;
|
|
247194
247358
|
return response.status !== "PENDING";
|
|
@@ -247251,32 +247415,49 @@ async function promptOAuthFlows(pending, options) {
|
|
|
247251
247415
|
function printSummary(results, oauthOutcomes) {
|
|
247252
247416
|
const synced = [];
|
|
247253
247417
|
const added = [];
|
|
247418
|
+
let provisioned;
|
|
247254
247419
|
const removed = [];
|
|
247255
247420
|
const skipped = [];
|
|
247256
247421
|
const failed = [];
|
|
247257
247422
|
for (const r of results) {
|
|
247258
|
-
|
|
247259
|
-
|
|
247260
|
-
|
|
247261
|
-
|
|
247262
|
-
|
|
247263
|
-
|
|
247264
|
-
|
|
247265
|
-
|
|
247266
|
-
|
|
247267
|
-
|
|
247268
|
-
|
|
247269
|
-
|
|
247270
|
-
|
|
247271
|
-
|
|
247272
|
-
|
|
247273
|
-
|
|
247274
|
-
|
|
247275
|
-
|
|
247423
|
+
switch (r.action) {
|
|
247424
|
+
case "provisioned":
|
|
247425
|
+
provisioned = r;
|
|
247426
|
+
break;
|
|
247427
|
+
case "synced":
|
|
247428
|
+
synced.push(r.type);
|
|
247429
|
+
break;
|
|
247430
|
+
case "removed":
|
|
247431
|
+
removed.push(r.type);
|
|
247432
|
+
break;
|
|
247433
|
+
case "error":
|
|
247434
|
+
failed.push({ type: r.type, error: r.error });
|
|
247435
|
+
break;
|
|
247436
|
+
case "needs_oauth": {
|
|
247437
|
+
const oauthStatus = oauthOutcomes.get(r.type);
|
|
247438
|
+
if (oauthStatus === "ACTIVE") {
|
|
247439
|
+
added.push(r.type);
|
|
247440
|
+
} else if (oauthStatus === "SKIPPED") {
|
|
247441
|
+
skipped.push(r.type);
|
|
247442
|
+
} else if (oauthStatus === "PENDING") {
|
|
247443
|
+
failed.push({ type: r.type, error: "authorization timed out" });
|
|
247444
|
+
} else if (oauthStatus === "FAILED") {
|
|
247445
|
+
failed.push({ type: r.type, error: "authorization failed" });
|
|
247446
|
+
} else {
|
|
247447
|
+
failed.push({ type: r.type, error: "needs authorization" });
|
|
247448
|
+
}
|
|
247449
|
+
break;
|
|
247276
247450
|
}
|
|
247277
247451
|
}
|
|
247278
247452
|
}
|
|
247279
247453
|
R2.info(theme.styles.bold("Summary:"));
|
|
247454
|
+
if (provisioned) {
|
|
247455
|
+
R2.success("Stripe sandbox provisioned");
|
|
247456
|
+
if (provisioned.claimUrl) {
|
|
247457
|
+
R2.info(` Claim your Stripe sandbox: ${theme.colors.links(provisioned.claimUrl)}`);
|
|
247458
|
+
}
|
|
247459
|
+
R2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
247460
|
+
}
|
|
247280
247461
|
if (synced.length > 0) {
|
|
247281
247462
|
R2.success(`Synced: ${synced.join(", ")}`);
|
|
247282
247463
|
}
|
|
@@ -247290,7 +247471,7 @@ function printSummary(results, oauthOutcomes) {
|
|
|
247290
247471
|
R2.warn(`Skipped: ${skipped.join(", ")}`);
|
|
247291
247472
|
}
|
|
247292
247473
|
for (const r of failed) {
|
|
247293
|
-
R2.error(`Failed: ${r.type}
|
|
247474
|
+
R2.error(`Failed: ${r.type} - ${r.error}`);
|
|
247294
247475
|
}
|
|
247295
247476
|
}
|
|
247296
247477
|
async function pushConnectorsAction(isNonInteractive) {
|
|
@@ -247638,15 +247819,11 @@ ${summaryLines.join(`
|
|
|
247638
247819
|
successMessage: theme.colors.base44Orange("Deployment completed"),
|
|
247639
247820
|
errorMessage: "Deployment failed"
|
|
247640
247821
|
});
|
|
247641
|
-
const
|
|
247642
|
-
|
|
247643
|
-
|
|
247644
|
-
|
|
247645
|
-
|
|
247646
|
-
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
247647
|
-
if (!allAuthorized) {
|
|
247648
|
-
R2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
|
|
247649
|
-
}
|
|
247822
|
+
const connectorResults = result.connectorResults ?? [];
|
|
247823
|
+
await handleOAuthConnectors(connectorResults, options);
|
|
247824
|
+
const stripeResult = connectorResults.find((r) => r.type === "stripe");
|
|
247825
|
+
if (stripeResult?.action === "provisioned") {
|
|
247826
|
+
printStripeResult(stripeResult);
|
|
247650
247827
|
}
|
|
247651
247828
|
R2.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
|
|
247652
247829
|
if (result.appUrl) {
|
|
@@ -247662,6 +247839,25 @@ function getDeployCommand(context) {
|
|
|
247662
247839
|
}), { requireAuth: true }, context);
|
|
247663
247840
|
});
|
|
247664
247841
|
}
|
|
247842
|
+
async function handleOAuthConnectors(connectorResults, options) {
|
|
247843
|
+
const needsOAuth = filterPendingOAuth(connectorResults);
|
|
247844
|
+
if (needsOAuth.length === 0)
|
|
247845
|
+
return;
|
|
247846
|
+
const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
|
|
247847
|
+
skipPrompt: options.yes || options.isNonInteractive
|
|
247848
|
+
});
|
|
247849
|
+
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
247850
|
+
if (!allAuthorized) {
|
|
247851
|
+
R2.info("Some connectors still require authorization. Run 'base44 connectors push' or open the links above in your browser.");
|
|
247852
|
+
}
|
|
247853
|
+
}
|
|
247854
|
+
function printStripeResult(r) {
|
|
247855
|
+
R2.success("Stripe sandbox provisioned");
|
|
247856
|
+
if (r.claimUrl) {
|
|
247857
|
+
R2.info(` Claim your Stripe sandbox: ${theme.colors.links(r.claimUrl)}`);
|
|
247858
|
+
}
|
|
247859
|
+
R2.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
247860
|
+
}
|
|
247665
247861
|
|
|
247666
247862
|
// src/cli/commands/project/link.ts
|
|
247667
247863
|
function validateNonInteractiveFlags2(command) {
|
|
@@ -247900,7 +248096,16 @@ async function getAllFunctionNames() {
|
|
|
247900
248096
|
const { functions } = await readProjectConfig();
|
|
247901
248097
|
return functions.map((fn) => fn.name);
|
|
247902
248098
|
}
|
|
248099
|
+
function validateLimit(limit) {
|
|
248100
|
+
if (limit === undefined)
|
|
248101
|
+
return;
|
|
248102
|
+
const n2 = Number.parseInt(limit, 10);
|
|
248103
|
+
if (Number.isNaN(n2) || n2 < 1 || n2 > 1000) {
|
|
248104
|
+
throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
|
|
248105
|
+
}
|
|
248106
|
+
}
|
|
247903
248107
|
async function logsAction(options) {
|
|
248108
|
+
validateLimit(options.limit);
|
|
247904
248109
|
const specifiedFunctions = parseFunctionNames(options.function);
|
|
247905
248110
|
const allProjectFunctions = await getAllFunctionNames();
|
|
247906
248111
|
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
|
|
@@ -247917,13 +248122,7 @@ async function logsAction(options) {
|
|
|
247917
248122
|
return { outroMessage: "Fetched logs", stdout: logsOutput };
|
|
247918
248123
|
}
|
|
247919
248124
|
function getLogsCommand(context) {
|
|
247920
|
-
return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)", normalizeDatetime).option("--until <datetime>", "Show logs until this time (ISO format)", normalizeDatetime).addOption(new Option("--level <level>", "Filter by log level").choices([...LogLevelSchema.options]).hideHelp()).option("-n, --limit <n>", "Results per page (1-1000, default: 50)", (
|
|
247921
|
-
const n2 = Number.parseInt(v, 10);
|
|
247922
|
-
if (Number.isNaN(n2) || n2 < 1 || n2 > 1000) {
|
|
247923
|
-
throw new InvalidInputError(`Invalid limit: "${v}". Must be a number between 1 and 1000.`);
|
|
247924
|
-
}
|
|
247925
|
-
return v;
|
|
247926
|
-
}).addOption(new Option("--order <order>", "Sort order").choices(["asc", "desc"])).action(async (options) => {
|
|
248125
|
+
return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)", normalizeDatetime).option("--until <datetime>", "Show logs until this time (ISO format)", normalizeDatetime).addOption(new Option("--level <level>", "Filter by log level").choices([...LogLevelSchema.options]).hideHelp()).option("-n, --limit <n>", "Results per page (1-1000, default: 50)").addOption(new Option("--order <order>", "Sort order").choices(["asc", "desc"])).action(async (options) => {
|
|
247927
248126
|
await runCommand(() => logsAction(options), { requireAuth: true }, context);
|
|
247928
248127
|
});
|
|
247929
248128
|
}
|
|
@@ -247989,11 +248188,9 @@ function parseEntries(entries) {
|
|
|
247989
248188
|
}
|
|
247990
248189
|
return secrets;
|
|
247991
248190
|
}
|
|
247992
|
-
function validateInput(
|
|
247993
|
-
const entries = command.args;
|
|
247994
|
-
const { envFile } = command.opts();
|
|
248191
|
+
function validateInput(entries, options) {
|
|
247995
248192
|
const hasEntries = entries.length > 0;
|
|
247996
|
-
const hasEnvFile = Boolean(envFile);
|
|
248193
|
+
const hasEnvFile = Boolean(options.envFile);
|
|
247997
248194
|
if (!hasEntries && !hasEnvFile) {
|
|
247998
248195
|
throw new InvalidInputError("Provide KEY=VALUE pairs or use --env-file. Example: base44 secrets set KEY1=VALUE1 KEY2=VALUE2");
|
|
247999
248196
|
}
|
|
@@ -248002,6 +248199,7 @@ function validateInput(command) {
|
|
|
248002
248199
|
}
|
|
248003
248200
|
}
|
|
248004
248201
|
async function setSecretsAction(entries, options) {
|
|
248202
|
+
validateInput(entries, options);
|
|
248005
248203
|
let secrets;
|
|
248006
248204
|
if (options.envFile) {
|
|
248007
248205
|
secrets = await parseEnvFile(resolve3(options.envFile));
|
|
@@ -248024,7 +248222,7 @@ async function setSecretsAction(entries, options) {
|
|
|
248024
248222
|
};
|
|
248025
248223
|
}
|
|
248026
248224
|
function getSecretsSetCommand(context) {
|
|
248027
|
-
return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. KEY1=VALUE1 KEY2=VALUE2)").option("--env-file <path>", "Path to .env file").
|
|
248225
|
+
return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. KEY1=VALUE1 KEY2=VALUE2)").option("--env-file <path>", "Path to .env file").action(async (entries, options) => {
|
|
248028
248226
|
await runCommand(() => setSecretsAction(entries, options), { requireAuth: true }, context);
|
|
248029
248227
|
});
|
|
248030
248228
|
}
|
|
@@ -248885,13 +249083,19 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
248885
249083
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
248886
249084
|
var import_express3 = __toESM(require_express(), 1);
|
|
248887
249085
|
var import_multer = __toESM(require_multer(), 1);
|
|
248888
|
-
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
249086
|
+
import { createHash, randomUUID as randomUUID4 } from "node:crypto";
|
|
248889
249087
|
import fs28 from "node:fs";
|
|
248890
249088
|
import path18 from "node:path";
|
|
249089
|
+
function createFileToken(fileUri) {
|
|
249090
|
+
return createHash("sha256").update(fileUri).digest("hex");
|
|
249091
|
+
}
|
|
248891
249092
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
248892
249093
|
const router = import_express3.Router({ mergeParams: true });
|
|
248893
249094
|
const parseBody = import_express3.json();
|
|
249095
|
+
const privateFilesDir = path18.join(mediaFilesDir, "private");
|
|
248894
249096
|
fs28.mkdirSync(mediaFilesDir, { recursive: true });
|
|
249097
|
+
fs28.mkdirSync(privateFilesDir, { recursive: true });
|
|
249098
|
+
const MAX_FILE_SIZE = 50 * 1024 * 1024;
|
|
248895
249099
|
const storage = import_multer.default.diskStorage({
|
|
248896
249100
|
destination: mediaFilesDir,
|
|
248897
249101
|
filename: (_req, file2, cb2) => {
|
|
@@ -248899,8 +249103,18 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
248899
249103
|
cb2(null, `${randomUUID4()}${ext}`);
|
|
248900
249104
|
}
|
|
248901
249105
|
});
|
|
248902
|
-
const
|
|
249106
|
+
const privateStorage = import_multer.default.diskStorage({
|
|
249107
|
+
destination: privateFilesDir,
|
|
249108
|
+
filename: (_req, file2, cb2) => {
|
|
249109
|
+
const ext = path18.extname(file2.originalname);
|
|
249110
|
+
cb2(null, `${randomUUID4()}${ext}`);
|
|
249111
|
+
}
|
|
249112
|
+
});
|
|
248903
249113
|
const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
|
|
249114
|
+
const privateUpload = import_multer.default({
|
|
249115
|
+
storage: privateStorage,
|
|
249116
|
+
limits: { fileSize: MAX_FILE_SIZE }
|
|
249117
|
+
});
|
|
248904
249118
|
router.post("/Core/UploadFile", upload.single("file"), (req, res) => {
|
|
248905
249119
|
if (!req.file) {
|
|
248906
249120
|
res.status(400).json({ error: "No file uploaded" });
|
|
@@ -248909,7 +249123,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
248909
249123
|
const file_url = `${baseUrl}/media/${req.file.filename}`;
|
|
248910
249124
|
res.json({ file_url });
|
|
248911
249125
|
});
|
|
248912
|
-
router.post("/Core/UploadPrivateFile",
|
|
249126
|
+
router.post("/Core/UploadPrivateFile", privateUpload.single("file"), (req, res) => {
|
|
248913
249127
|
if (!req.file) {
|
|
248914
249128
|
res.status(400).json({ error: "No file uploaded" });
|
|
248915
249129
|
return;
|
|
@@ -248923,8 +249137,8 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
248923
249137
|
res.status(400).json({ error: "file_uri is required" });
|
|
248924
249138
|
return;
|
|
248925
249139
|
}
|
|
248926
|
-
const
|
|
248927
|
-
const signed_url = `${baseUrl}/media/${file_uri}?
|
|
249140
|
+
const token2 = createFileToken(file_uri);
|
|
249141
|
+
const signed_url = `${baseUrl}/media/private/${file_uri}?token=${token2}`;
|
|
248928
249142
|
res.json({ signed_url });
|
|
248929
249143
|
});
|
|
248930
249144
|
router.post("/Core/:endpointName", (req, res, next) => {
|
|
@@ -250693,6 +250907,24 @@ async function createDevServer(options8) {
|
|
|
250693
250907
|
const entityRoutes = createEntityRoutes(db2, devLogger, remoteProxy, (...args) => emitEntityEvent(...args));
|
|
250694
250908
|
app.use("/api/apps/:appId/entities", entityRoutes);
|
|
250695
250909
|
const { path: mediaFilesDir } = await $dir();
|
|
250910
|
+
app.use("/media/private/:fileUri", (req, res, next) => {
|
|
250911
|
+
const { fileUri } = req.params;
|
|
250912
|
+
const token2 = req.query.token;
|
|
250913
|
+
if (!token2) {
|
|
250914
|
+
res.status(401).json({ error: "Missing token" });
|
|
250915
|
+
return;
|
|
250916
|
+
}
|
|
250917
|
+
const expectedToken = createFileToken(fileUri);
|
|
250918
|
+
if (token2 !== expectedToken) {
|
|
250919
|
+
res.status(400).json({
|
|
250920
|
+
error: "InvalidJWT",
|
|
250921
|
+
message: "signature verification failed",
|
|
250922
|
+
statusCode: "400"
|
|
250923
|
+
});
|
|
250924
|
+
return;
|
|
250925
|
+
}
|
|
250926
|
+
next();
|
|
250927
|
+
});
|
|
250696
250928
|
app.use("/media", import_express4.default.static(mediaFilesDir));
|
|
250697
250929
|
const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
|
|
250698
250930
|
app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
|
|
@@ -255143,4 +255375,4 @@ export {
|
|
|
255143
255375
|
CLIExitError
|
|
255144
255376
|
};
|
|
255145
255377
|
|
|
255146
|
-
//# debugId=
|
|
255378
|
+
//# debugId=384DD458B8CE578E64756E2164756E21
|