@base44-preview/cli 0.0.24-pr.147.be1c0f9 → 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/README.md +2 -0
- package/dist/index.js +542 -120
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -53,6 +53,8 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
|
|
|
53
53
|
| [`entities push`](https://docs.base44.com/developers/references/cli/commands/entities-push) | Push local entity schemas to Base44 |
|
|
54
54
|
| [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy local functions to Base44 |
|
|
55
55
|
| [`site deploy`](https://docs.base44.com/developers/references/cli/commands/site-deploy) | Deploy built site files to Base44 hosting |
|
|
56
|
+
| `connectors add [type]` | Connect an OAuth integration |
|
|
57
|
+
| `connectors remove [type]` | Disconnect an integration |
|
|
56
58
|
|
|
57
59
|
|
|
58
60
|
<!--| [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Create a Base44 backend project from an existing Base44 app | -->
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { EventEmitter, addAbortListener, on, once, setMaxListeners } from "node:
|
|
|
3
3
|
import childProcess, { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
4
4
|
import path, { basename, dirname, join, posix, resolve, win32 } from "node:path";
|
|
5
5
|
import fs, { appendFileSync, createReadStream, createWriteStream, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
6
|
-
import
|
|
6
|
+
import y, { execArgv, execPath, hrtime, platform, stdin, stdout } from "node:process";
|
|
7
7
|
import { aborted, callbackify, debuglog, inspect, promisify, stripVTControlCharacters } from "node:util";
|
|
8
8
|
import * as g from "node:readline";
|
|
9
9
|
import O from "node:readline";
|
|
@@ -893,7 +893,7 @@ var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
893
893
|
const childProcess$1 = __require("node:child_process");
|
|
894
894
|
const path$15 = __require("node:path");
|
|
895
895
|
const fs$10 = __require("node:fs");
|
|
896
|
-
const process$
|
|
896
|
+
const process$3 = __require("node:process");
|
|
897
897
|
const { Argument, humanReadableArgName } = require_argument();
|
|
898
898
|
const { CommanderError } = require_error$1();
|
|
899
899
|
const { Help } = require_help();
|
|
@@ -944,10 +944,10 @@ var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
944
944
|
this._showHelpAfterError = false;
|
|
945
945
|
this._showSuggestionAfterError = true;
|
|
946
946
|
this._outputConfiguration = {
|
|
947
|
-
writeOut: (str) => process$
|
|
948
|
-
writeErr: (str) => process$
|
|
949
|
-
getOutHelpWidth: () => process$
|
|
950
|
-
getErrHelpWidth: () => process$
|
|
947
|
+
writeOut: (str) => process$3.stdout.write(str),
|
|
948
|
+
writeErr: (str) => process$3.stderr.write(str),
|
|
949
|
+
getOutHelpWidth: () => process$3.stdout.isTTY ? process$3.stdout.columns : void 0,
|
|
950
|
+
getErrHelpWidth: () => process$3.stderr.isTTY ? process$3.stderr.columns : void 0,
|
|
951
951
|
outputError: (str, write) => write(str)
|
|
952
952
|
};
|
|
953
953
|
this._hidden = false;
|
|
@@ -1301,7 +1301,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1301
1301
|
*/
|
|
1302
1302
|
_exit(exitCode, code$1, message) {
|
|
1303
1303
|
if (this._exitCallback) this._exitCallback(new CommanderError(exitCode, code$1, message));
|
|
1304
|
-
process$
|
|
1304
|
+
process$3.exit(exitCode);
|
|
1305
1305
|
}
|
|
1306
1306
|
/**
|
|
1307
1307
|
* Register callback `fn` for the command.
|
|
@@ -1640,11 +1640,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1640
1640
|
if (argv !== void 0 && !Array.isArray(argv)) throw new Error("first parameter to parse must be array or undefined");
|
|
1641
1641
|
parseOptions = parseOptions || {};
|
|
1642
1642
|
if (argv === void 0 && parseOptions.from === void 0) {
|
|
1643
|
-
if (process$
|
|
1644
|
-
const execArgv$1 = process$
|
|
1643
|
+
if (process$3.versions?.electron) parseOptions.from = "electron";
|
|
1644
|
+
const execArgv$1 = process$3.execArgv ?? [];
|
|
1645
1645
|
if (execArgv$1.includes("-e") || execArgv$1.includes("--eval") || execArgv$1.includes("-p") || execArgv$1.includes("--print")) parseOptions.from = "eval";
|
|
1646
1646
|
}
|
|
1647
|
-
if (argv === void 0) argv = process$
|
|
1647
|
+
if (argv === void 0) argv = process$3.argv;
|
|
1648
1648
|
this.rawArgs = argv.slice();
|
|
1649
1649
|
let userArgs;
|
|
1650
1650
|
switch (parseOptions.from) {
|
|
@@ -1654,7 +1654,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1654
1654
|
userArgs = argv.slice(2);
|
|
1655
1655
|
break;
|
|
1656
1656
|
case "electron":
|
|
1657
|
-
if (process$
|
|
1657
|
+
if (process$3.defaultApp) {
|
|
1658
1658
|
this._scriptPath = argv[1];
|
|
1659
1659
|
userArgs = argv.slice(2);
|
|
1660
1660
|
} else userArgs = argv.slice(1);
|
|
@@ -1768,15 +1768,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1768
1768
|
}
|
|
1769
1769
|
launchWithNode = sourceExt.includes(path$15.extname(executableFile));
|
|
1770
1770
|
let proc$1;
|
|
1771
|
-
if (process$
|
|
1771
|
+
if (process$3.platform !== "win32") if (launchWithNode) {
|
|
1772
1772
|
args.unshift(executableFile);
|
|
1773
|
-
args = incrementNodeInspectorPort(process$
|
|
1774
|
-
proc$1 = childProcess$1.spawn(process$
|
|
1773
|
+
args = incrementNodeInspectorPort(process$3.execArgv).concat(args);
|
|
1774
|
+
proc$1 = childProcess$1.spawn(process$3.argv[0], args, { stdio: "inherit" });
|
|
1775
1775
|
} else proc$1 = childProcess$1.spawn(executableFile, args, { stdio: "inherit" });
|
|
1776
1776
|
else {
|
|
1777
1777
|
args.unshift(executableFile);
|
|
1778
|
-
args = incrementNodeInspectorPort(process$
|
|
1779
|
-
proc$1 = childProcess$1.spawn(process$
|
|
1778
|
+
args = incrementNodeInspectorPort(process$3.execArgv).concat(args);
|
|
1779
|
+
proc$1 = childProcess$1.spawn(process$3.execPath, args, { stdio: "inherit" });
|
|
1780
1780
|
}
|
|
1781
1781
|
if (!proc$1.killed) [
|
|
1782
1782
|
"SIGUSR1",
|
|
@@ -1785,14 +1785,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1785
1785
|
"SIGINT",
|
|
1786
1786
|
"SIGHUP"
|
|
1787
1787
|
].forEach((signal) => {
|
|
1788
|
-
process$
|
|
1788
|
+
process$3.on(signal, () => {
|
|
1789
1789
|
if (proc$1.killed === false && proc$1.exitCode === null) proc$1.kill(signal);
|
|
1790
1790
|
});
|
|
1791
1791
|
});
|
|
1792
1792
|
const exitCallback = this._exitCallback;
|
|
1793
1793
|
proc$1.on("close", (code$1) => {
|
|
1794
1794
|
code$1 = code$1 ?? 1;
|
|
1795
|
-
if (!exitCallback) process$
|
|
1795
|
+
if (!exitCallback) process$3.exit(code$1);
|
|
1796
1796
|
else exitCallback(new CommanderError(code$1, "commander.executeSubCommandAsync", "(close)"));
|
|
1797
1797
|
});
|
|
1798
1798
|
proc$1.on("error", (err) => {
|
|
@@ -1804,7 +1804,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1804
1804
|
- ${executableDirMessage}`;
|
|
1805
1805
|
throw new Error(executableMissing);
|
|
1806
1806
|
} else if (err.code === "EACCES") throw new Error(`'${executableFile}' not executable`);
|
|
1807
|
-
if (!exitCallback) process$
|
|
1807
|
+
if (!exitCallback) process$3.exit(1);
|
|
1808
1808
|
else {
|
|
1809
1809
|
const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
|
|
1810
1810
|
wrappedError.nestedError = err;
|
|
@@ -2210,13 +2210,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2210
2210
|
*/
|
|
2211
2211
|
_parseOptionsEnv() {
|
|
2212
2212
|
this.options.forEach((option) => {
|
|
2213
|
-
if (option.envVar && option.envVar in process$
|
|
2213
|
+
if (option.envVar && option.envVar in process$3.env) {
|
|
2214
2214
|
const optionKey = option.attributeName();
|
|
2215
2215
|
if (this.getOptionValue(optionKey) === void 0 || [
|
|
2216
2216
|
"default",
|
|
2217
2217
|
"config",
|
|
2218
2218
|
"env"
|
|
2219
|
-
].includes(this.getOptionValueSource(optionKey))) if (option.required || option.optional) this.emit(`optionEnv:${option.name()}`, process$
|
|
2219
|
+
].includes(this.getOptionValueSource(optionKey))) if (option.required || option.optional) this.emit(`optionEnv:${option.name()}`, process$3.env[option.envVar]);
|
|
2220
2220
|
else this.emit(`optionEnv:${option.name()}`);
|
|
2221
2221
|
}
|
|
2222
2222
|
});
|
|
@@ -2595,7 +2595,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2595
2595
|
*/
|
|
2596
2596
|
help(contextOptions) {
|
|
2597
2597
|
this.outputHelp(contextOptions);
|
|
2598
|
-
let exitCode = process$
|
|
2598
|
+
let exitCode = process$3.exitCode || 0;
|
|
2599
2599
|
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) exitCode = 1;
|
|
2600
2600
|
this._exit(exitCode, "commander.help", "(outputHelp)");
|
|
2601
2601
|
}
|
|
@@ -2711,16 +2711,16 @@ var require_src = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2711
2711
|
const CSI = `${ESC}[`;
|
|
2712
2712
|
const beep = "\x07";
|
|
2713
2713
|
const cursor = {
|
|
2714
|
-
to(x$2, y$
|
|
2715
|
-
if (!y$
|
|
2716
|
-
return `${CSI}${y$
|
|
2714
|
+
to(x$2, y$2) {
|
|
2715
|
+
if (!y$2) return `${CSI}${x$2 + 1}G`;
|
|
2716
|
+
return `${CSI}${y$2 + 1};${x$2 + 1}H`;
|
|
2717
2717
|
},
|
|
2718
|
-
move(x$2, y$
|
|
2718
|
+
move(x$2, y$2) {
|
|
2719
2719
|
let ret = "";
|
|
2720
2720
|
if (x$2 < 0) ret += `${CSI}${-x$2}D`;
|
|
2721
2721
|
else if (x$2 > 0) ret += `${CSI}${x$2}C`;
|
|
2722
|
-
if (y$
|
|
2723
|
-
else if (y$
|
|
2722
|
+
if (y$2 < 0) ret += `${CSI}${-y$2}A`;
|
|
2723
|
+
else if (y$2 > 0) ret += `${CSI}${y$2}B`;
|
|
2724
2724
|
return ret;
|
|
2725
2725
|
},
|
|
2726
2726
|
up: (count$1 = 1) => `${CSI}${count$1}A`,
|
|
@@ -3030,13 +3030,13 @@ function rD() {
|
|
|
3030
3030
|
}
|
|
3031
3031
|
}), r;
|
|
3032
3032
|
}
|
|
3033
|
-
const ED = rD(), d$1 = new Set(["\x1B", ""]), oD = 39, y = "\x07", V$1 = "[", nD = "]", G$1 = "m", _$1 = `${nD}8;;`, z = (e$1) => `${d$1.values().next().value}${V$1}${e$1}${G$1}`, K$1 = (e$1) => `${d$1.values().next().value}${_$1}${e$1}${y}`, aD = (e$1) => e$1.split(" ").map((u$2) => p(u$2)), k$1 = (e$1, u$2, t) => {
|
|
3033
|
+
const ED = rD(), d$1 = new Set(["\x1B", ""]), oD = 39, y$1 = "\x07", V$1 = "[", nD = "]", G$1 = "m", _$1 = `${nD}8;;`, z = (e$1) => `${d$1.values().next().value}${V$1}${e$1}${G$1}`, K$1 = (e$1) => `${d$1.values().next().value}${_$1}${e$1}${y$1}`, aD = (e$1) => e$1.split(" ").map((u$2) => p(u$2)), k$1 = (e$1, u$2, t) => {
|
|
3034
3034
|
const F$1 = [...u$2];
|
|
3035
3035
|
let s = !1, i$1 = !1, D$1 = p(P$1(e$1[e$1.length - 1]));
|
|
3036
3036
|
for (const [C$1, n$1] of F$1.entries()) {
|
|
3037
3037
|
const E = p(n$1);
|
|
3038
3038
|
if (D$1 + E <= t ? e$1[e$1.length - 1] += n$1 : (e$1.push(n$1), D$1 = 0), d$1.has(n$1) && (s = !0, i$1 = F$1.slice(C$1 + 1).join("").startsWith(_$1)), s) {
|
|
3039
|
-
i$1 ? n$1 === y && (s = !1, i$1 = !1) : n$1 === G$1 && (s = !1);
|
|
3039
|
+
i$1 ? n$1 === y$1 && (s = !1, i$1 = !1) : n$1 === G$1 && (s = !1);
|
|
3040
3040
|
continue;
|
|
3041
3041
|
}
|
|
3042
3042
|
D$1 += E, D$1 === t && C$1 < F$1.length - 1 && (e$1.push(""), D$1 = 0);
|
|
@@ -3078,7 +3078,7 @@ const ED = rD(), d$1 = new Set(["\x1B", ""]), oD = 39, y = "\x07", V$1 = "[",
|
|
|
3078
3078
|
`)];
|
|
3079
3079
|
for (const [E, a$1] of n$1.entries()) {
|
|
3080
3080
|
if (F$1 += a$1, d$1.has(a$1)) {
|
|
3081
|
-
const { groups: c$1 } = (/* @__PURE__ */ new RegExp(`(?:\\${V$1}(?<code>\\d+)m|\\${_$1}(?<uri>.*)${y})`)).exec(n$1.slice(E).join("")) || { groups: {} };
|
|
3081
|
+
const { groups: c$1 } = (/* @__PURE__ */ new RegExp(`(?:\\${V$1}(?<code>\\d+)m|\\${_$1}(?<uri>.*)${y$1})`)).exec(n$1.slice(E).join("")) || { groups: {} };
|
|
3082
3082
|
if (c$1.code !== void 0) {
|
|
3083
3083
|
const f = Number.parseFloat(c$1.code);
|
|
3084
3084
|
s = f === oD ? void 0 : f;
|
|
@@ -3479,7 +3479,7 @@ var RD = class extends x$1 {
|
|
|
3479
3479
|
//#endregion
|
|
3480
3480
|
//#region node_modules/@clack/prompts/dist/index.mjs
|
|
3481
3481
|
function ce() {
|
|
3482
|
-
return
|
|
3482
|
+
return y.platform !== "win32" ? y.env.TERM !== "linux" : !!y.env.CI || !!y.env.WT_SESSION || !!y.env.TERMINUS_SUBLIME || y.env.ConEmuTask === "{cmd::Cmder}" || y.env.TERM_PROGRAM === "Terminus-Sublime" || y.env.TERM_PROGRAM === "vscode" || y.env.TERM === "xterm-256color" || y.env.TERM === "alacritty" || y.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
3483
3483
|
}
|
|
3484
3484
|
const V = ce(), u$1 = (t, n$1) => V ? t : n$1, le = u$1("◆", "*"), L = u$1("■", "x"), W = u$1("▲", "x"), C = u$1("◇", "o"), ue = u$1("┌", "T"), o$1 = u$1("│", "|"), d = u$1("└", "—"), k = u$1("●", ">"), P = u$1("○", " "), A = u$1("◻", "[•]"), T = u$1("◼", "[+]"), F = u$1("◻", "[ ]"), $e = u$1("▪", "•"), _ = u$1("─", "-"), me = u$1("╮", "+"), de = u$1("├", "+"), pe = u$1("╯", "+"), q = u$1("●", "•"), D = u$1("◆", "*"), U = u$1("▲", "!"), K = u$1("■", "x"), b = (t) => {
|
|
3485
3485
|
switch (t) {
|
|
@@ -6744,7 +6744,7 @@ function initializeContext(params) {
|
|
|
6744
6744
|
external: params?.external ?? void 0
|
|
6745
6745
|
};
|
|
6746
6746
|
}
|
|
6747
|
-
function process$
|
|
6747
|
+
function process$2(schema, ctx, _params = {
|
|
6748
6748
|
path: [],
|
|
6749
6749
|
schemaPath: []
|
|
6750
6750
|
}) {
|
|
@@ -6781,7 +6781,7 @@ function process$3(schema, ctx, _params = {
|
|
|
6781
6781
|
const parent = schema._zod.parent;
|
|
6782
6782
|
if (parent) {
|
|
6783
6783
|
if (!result.ref) result.ref = parent;
|
|
6784
|
-
process$
|
|
6784
|
+
process$2(parent, ctx, params);
|
|
6785
6785
|
ctx.seen.get(parent).isParent = true;
|
|
6786
6786
|
}
|
|
6787
6787
|
}
|
|
@@ -6993,7 +6993,7 @@ const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
|
6993
6993
|
...params,
|
|
6994
6994
|
processors
|
|
6995
6995
|
});
|
|
6996
|
-
process$
|
|
6996
|
+
process$2(schema, ctx);
|
|
6997
6997
|
extractDefs(ctx, schema);
|
|
6998
6998
|
return finalize(ctx, schema);
|
|
6999
6999
|
};
|
|
@@ -7005,7 +7005,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
|
|
|
7005
7005
|
io,
|
|
7006
7006
|
processors
|
|
7007
7007
|
});
|
|
7008
|
-
process$
|
|
7008
|
+
process$2(schema, ctx);
|
|
7009
7009
|
extractDefs(ctx, schema);
|
|
7010
7010
|
return finalize(ctx, schema);
|
|
7011
7011
|
};
|
|
@@ -7092,7 +7092,7 @@ const arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
7092
7092
|
if (typeof minimum === "number") json.minItems = minimum;
|
|
7093
7093
|
if (typeof maximum === "number") json.maxItems = maximum;
|
|
7094
7094
|
json.type = "array";
|
|
7095
|
-
json.items = process$
|
|
7095
|
+
json.items = process$2(def.element, ctx, {
|
|
7096
7096
|
...params,
|
|
7097
7097
|
path: [...params.path, "items"]
|
|
7098
7098
|
});
|
|
@@ -7103,7 +7103,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
7103
7103
|
json.type = "object";
|
|
7104
7104
|
json.properties = {};
|
|
7105
7105
|
const shape = def.shape;
|
|
7106
|
-
for (const key in shape) json.properties[key] = process$
|
|
7106
|
+
for (const key in shape) json.properties[key] = process$2(shape[key], ctx, {
|
|
7107
7107
|
...params,
|
|
7108
7108
|
path: [
|
|
7109
7109
|
...params.path,
|
|
@@ -7121,7 +7121,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
7121
7121
|
if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
|
|
7122
7122
|
else if (!def.catchall) {
|
|
7123
7123
|
if (ctx.io === "output") json.additionalProperties = false;
|
|
7124
|
-
} else if (def.catchall) json.additionalProperties = process$
|
|
7124
|
+
} else if (def.catchall) json.additionalProperties = process$2(def.catchall, ctx, {
|
|
7125
7125
|
...params,
|
|
7126
7126
|
path: [...params.path, "additionalProperties"]
|
|
7127
7127
|
});
|
|
@@ -7129,7 +7129,7 @@ const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
7129
7129
|
const unionProcessor = (schema, ctx, json, params) => {
|
|
7130
7130
|
const def = schema._zod.def;
|
|
7131
7131
|
const isExclusive = def.inclusive === false;
|
|
7132
|
-
const options = def.options.map((x$2, i$1) => process$
|
|
7132
|
+
const options = def.options.map((x$2, i$1) => process$2(x$2, ctx, {
|
|
7133
7133
|
...params,
|
|
7134
7134
|
path: [
|
|
7135
7135
|
...params.path,
|
|
@@ -7142,7 +7142,7 @@ const unionProcessor = (schema, ctx, json, params) => {
|
|
|
7142
7142
|
};
|
|
7143
7143
|
const intersectionProcessor = (schema, ctx, json, params) => {
|
|
7144
7144
|
const def = schema._zod.def;
|
|
7145
|
-
const a$1 = process$
|
|
7145
|
+
const a$1 = process$2(def.left, ctx, {
|
|
7146
7146
|
...params,
|
|
7147
7147
|
path: [
|
|
7148
7148
|
...params.path,
|
|
@@ -7150,7 +7150,7 @@ const intersectionProcessor = (schema, ctx, json, params) => {
|
|
|
7150
7150
|
0
|
|
7151
7151
|
]
|
|
7152
7152
|
});
|
|
7153
|
-
const b$2 = process$
|
|
7153
|
+
const b$2 = process$2(def.right, ctx, {
|
|
7154
7154
|
...params,
|
|
7155
7155
|
path: [
|
|
7156
7156
|
...params.path,
|
|
@@ -7167,7 +7167,7 @@ const tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
7167
7167
|
json.type = "array";
|
|
7168
7168
|
const prefixPath$1 = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
7169
7169
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
7170
|
-
const prefixItems = def.items.map((x$2, i$1) => process$
|
|
7170
|
+
const prefixItems = def.items.map((x$2, i$1) => process$2(x$2, ctx, {
|
|
7171
7171
|
...params,
|
|
7172
7172
|
path: [
|
|
7173
7173
|
...params.path,
|
|
@@ -7175,7 +7175,7 @@ const tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
7175
7175
|
i$1
|
|
7176
7176
|
]
|
|
7177
7177
|
}));
|
|
7178
|
-
const rest = def.rest ? process$
|
|
7178
|
+
const rest = def.rest ? process$2(def.rest, ctx, {
|
|
7179
7179
|
...params,
|
|
7180
7180
|
path: [
|
|
7181
7181
|
...params.path,
|
|
@@ -7206,7 +7206,7 @@ const recordProcessor = (schema, ctx, _json, params) => {
|
|
|
7206
7206
|
const keyType = def.keyType;
|
|
7207
7207
|
const patterns = keyType._zod.bag?.patterns;
|
|
7208
7208
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
7209
|
-
const valueSchema = process$
|
|
7209
|
+
const valueSchema = process$2(def.valueType, ctx, {
|
|
7210
7210
|
...params,
|
|
7211
7211
|
path: [
|
|
7212
7212
|
...params.path,
|
|
@@ -7217,11 +7217,11 @@ const recordProcessor = (schema, ctx, _json, params) => {
|
|
|
7217
7217
|
json.patternProperties = {};
|
|
7218
7218
|
for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
|
|
7219
7219
|
} else {
|
|
7220
|
-
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$
|
|
7220
|
+
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$2(def.keyType, ctx, {
|
|
7221
7221
|
...params,
|
|
7222
7222
|
path: [...params.path, "propertyNames"]
|
|
7223
7223
|
});
|
|
7224
|
-
json.additionalProperties = process$
|
|
7224
|
+
json.additionalProperties = process$2(def.valueType, ctx, {
|
|
7225
7225
|
...params,
|
|
7226
7226
|
path: [...params.path, "additionalProperties"]
|
|
7227
7227
|
});
|
|
@@ -7234,7 +7234,7 @@ const recordProcessor = (schema, ctx, _json, params) => {
|
|
|
7234
7234
|
};
|
|
7235
7235
|
const nullableProcessor = (schema, ctx, json, params) => {
|
|
7236
7236
|
const def = schema._zod.def;
|
|
7237
|
-
const inner = process$
|
|
7237
|
+
const inner = process$2(def.innerType, ctx, params);
|
|
7238
7238
|
const seen = ctx.seen.get(schema);
|
|
7239
7239
|
if (ctx.target === "openapi-3.0") {
|
|
7240
7240
|
seen.ref = def.innerType;
|
|
@@ -7243,27 +7243,27 @@ const nullableProcessor = (schema, ctx, json, params) => {
|
|
|
7243
7243
|
};
|
|
7244
7244
|
const nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
7245
7245
|
const def = schema._zod.def;
|
|
7246
|
-
process$
|
|
7246
|
+
process$2(def.innerType, ctx, params);
|
|
7247
7247
|
const seen = ctx.seen.get(schema);
|
|
7248
7248
|
seen.ref = def.innerType;
|
|
7249
7249
|
};
|
|
7250
7250
|
const defaultProcessor = (schema, ctx, json, params) => {
|
|
7251
7251
|
const def = schema._zod.def;
|
|
7252
|
-
process$
|
|
7252
|
+
process$2(def.innerType, ctx, params);
|
|
7253
7253
|
const seen = ctx.seen.get(schema);
|
|
7254
7254
|
seen.ref = def.innerType;
|
|
7255
7255
|
json.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
7256
7256
|
};
|
|
7257
7257
|
const prefaultProcessor = (schema, ctx, json, params) => {
|
|
7258
7258
|
const def = schema._zod.def;
|
|
7259
|
-
process$
|
|
7259
|
+
process$2(def.innerType, ctx, params);
|
|
7260
7260
|
const seen = ctx.seen.get(schema);
|
|
7261
7261
|
seen.ref = def.innerType;
|
|
7262
7262
|
if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
|
|
7263
7263
|
};
|
|
7264
7264
|
const catchProcessor = (schema, ctx, json, params) => {
|
|
7265
7265
|
const def = schema._zod.def;
|
|
7266
|
-
process$
|
|
7266
|
+
process$2(def.innerType, ctx, params);
|
|
7267
7267
|
const seen = ctx.seen.get(schema);
|
|
7268
7268
|
seen.ref = def.innerType;
|
|
7269
7269
|
let catchValue;
|
|
@@ -7277,20 +7277,20 @@ const catchProcessor = (schema, ctx, json, params) => {
|
|
|
7277
7277
|
const pipeProcessor = (schema, ctx, _json, params) => {
|
|
7278
7278
|
const def = schema._zod.def;
|
|
7279
7279
|
const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
|
|
7280
|
-
process$
|
|
7280
|
+
process$2(innerType, ctx, params);
|
|
7281
7281
|
const seen = ctx.seen.get(schema);
|
|
7282
7282
|
seen.ref = innerType;
|
|
7283
7283
|
};
|
|
7284
7284
|
const readonlyProcessor = (schema, ctx, json, params) => {
|
|
7285
7285
|
const def = schema._zod.def;
|
|
7286
|
-
process$
|
|
7286
|
+
process$2(def.innerType, ctx, params);
|
|
7287
7287
|
const seen = ctx.seen.get(schema);
|
|
7288
7288
|
seen.ref = def.innerType;
|
|
7289
7289
|
json.readOnly = true;
|
|
7290
7290
|
};
|
|
7291
7291
|
const optionalProcessor = (schema, ctx, _json, params) => {
|
|
7292
7292
|
const def = schema._zod.def;
|
|
7293
|
-
process$
|
|
7293
|
+
process$2(def.innerType, ctx, params);
|
|
7294
7294
|
const seen = ctx.seen.get(schema);
|
|
7295
7295
|
seen.ref = def.innerType;
|
|
7296
7296
|
};
|
|
@@ -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
|
|
@@ -16335,7 +16348,7 @@ const createIgnorePredicate = (patterns, cwd, baseDir) => {
|
|
|
16335
16348
|
};
|
|
16336
16349
|
const normalizeOptions$2 = (options = {}) => {
|
|
16337
16350
|
const ignoreOption = options.ignore ? Array.isArray(options.ignore) ? options.ignore : [options.ignore] : [];
|
|
16338
|
-
const cwd = toPath$1(options.cwd) ??
|
|
16351
|
+
const cwd = toPath$1(options.cwd) ?? y.cwd();
|
|
16339
16352
|
const deep = typeof options.deep === "number" ? Math.max(0, options.deep) + 1 : Number.POSITIVE_INFINITY;
|
|
16340
16353
|
return {
|
|
16341
16354
|
cwd,
|
|
@@ -16432,7 +16445,7 @@ const getDirectoryGlob = ({ directoryPath, files, extensions }) => {
|
|
|
16432
16445
|
const extensionGlob = extensions?.length > 0 ? `.${extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0]}` : "";
|
|
16433
16446
|
return files ? files.map((file) => path.posix.join(directoryPath, `**/${path.extname(file) ? file : `${file}${extensionGlob}`}`)) : [path.posix.join(directoryPath, `**${extensionGlob ? `/*${extensionGlob}` : ""}`)];
|
|
16434
16447
|
};
|
|
16435
|
-
const directoryToGlob = async (directoryPaths, { cwd =
|
|
16448
|
+
const directoryToGlob = async (directoryPaths, { cwd = y.cwd(), files, extensions, fs: fsImplementation } = {}) => {
|
|
16436
16449
|
return (await Promise.all(directoryPaths.map(async (directoryPath) => {
|
|
16437
16450
|
if (shouldExpandGlobstarDirectory(isNegativePattern(directoryPath) ? directoryPath.slice(1) : directoryPath)) return getDirectoryGlob({
|
|
16438
16451
|
directoryPath,
|
|
@@ -16446,7 +16459,7 @@ const directoryToGlob = async (directoryPaths, { cwd = process$1.cwd(), files, e
|
|
|
16446
16459
|
}) : directoryPath;
|
|
16447
16460
|
}))).flat();
|
|
16448
16461
|
};
|
|
16449
|
-
const directoryToGlobSync = (directoryPaths, { cwd =
|
|
16462
|
+
const directoryToGlobSync = (directoryPaths, { cwd = y.cwd(), files, extensions, fs: fsImplementation } = {}) => directoryPaths.flatMap((directoryPath) => {
|
|
16450
16463
|
if (shouldExpandGlobstarDirectory(isNegativePattern(directoryPath) ? directoryPath.slice(1) : directoryPath)) return getDirectoryGlob({
|
|
16451
16464
|
directoryPath,
|
|
16452
16465
|
files,
|
|
@@ -16542,7 +16555,7 @@ const applyIgnoreFilesAndGetFilterSync = (options) => {
|
|
|
16542
16555
|
};
|
|
16543
16556
|
const createFilterFunction = (isIgnored, cwd) => {
|
|
16544
16557
|
const seen = /* @__PURE__ */ new Set();
|
|
16545
|
-
const basePath = cwd ||
|
|
16558
|
+
const basePath = cwd || y.cwd();
|
|
16546
16559
|
const pathCache = /* @__PURE__ */ new Map();
|
|
16547
16560
|
return (fastGlobResult) => {
|
|
16548
16561
|
const pathKey$1 = path.normalize(fastGlobResult.path ?? fastGlobResult);
|
|
@@ -16730,7 +16743,10 @@ const FunctionConfigSchema = object({
|
|
|
16730
16743
|
entry: string().min(1, "Entry point cannot be empty"),
|
|
16731
16744
|
triggers: tuple([]).optional()
|
|
16732
16745
|
});
|
|
16733
|
-
const FunctionSchema = FunctionConfigSchema.extend({
|
|
16746
|
+
const FunctionSchema = FunctionConfigSchema.extend({
|
|
16747
|
+
entryPath: string().min(1, "Entry path cannot be empty"),
|
|
16748
|
+
files: array(string()).min(1, "Files array cannot be empty")
|
|
16749
|
+
});
|
|
16734
16750
|
const DeployFunctionsResponseSchema = object({
|
|
16735
16751
|
deployed: array(string()),
|
|
16736
16752
|
deleted: array(string()),
|
|
@@ -16750,11 +16766,17 @@ async function readFunctionConfig(configPath) {
|
|
|
16750
16766
|
}
|
|
16751
16767
|
async function readFunction(configPath) {
|
|
16752
16768
|
const config$1 = await readFunctionConfig(configPath);
|
|
16753
|
-
const
|
|
16754
|
-
|
|
16769
|
+
const functionDir = dirname(configPath);
|
|
16770
|
+
const entryPath = join(functionDir, config$1.entry);
|
|
16771
|
+
if (!await pathExists(entryPath)) throw new Error(`Function entry file not found: ${entryPath} (referenced in ${configPath})`);
|
|
16772
|
+
const files = await globby("*.{js,ts,json}", {
|
|
16773
|
+
cwd: functionDir,
|
|
16774
|
+
absolute: true
|
|
16775
|
+
});
|
|
16755
16776
|
const functionData = {
|
|
16756
16777
|
...config$1,
|
|
16757
|
-
|
|
16778
|
+
entryPath,
|
|
16779
|
+
files
|
|
16758
16780
|
};
|
|
16759
16781
|
const result = FunctionSchema.safeParse(functionData);
|
|
16760
16782
|
if (!result.success) throw new Error(`Invalid function in ${configPath}: ${result.error.message}`);
|
|
@@ -16781,10 +16803,7 @@ function toDeployPayloadItem(fn) {
|
|
|
16781
16803
|
return {
|
|
16782
16804
|
name: fn.name,
|
|
16783
16805
|
entry: fn.entry,
|
|
16784
|
-
files:
|
|
16785
|
-
path: fn.entry,
|
|
16786
|
-
content: fn.code
|
|
16787
|
-
}]
|
|
16806
|
+
files: fn.files
|
|
16788
16807
|
};
|
|
16789
16808
|
}
|
|
16790
16809
|
async function deployFunctions(functions) {
|
|
@@ -16800,10 +16819,16 @@ async function deployFunctions(functions) {
|
|
|
16800
16819
|
//#endregion
|
|
16801
16820
|
//#region src/core/resources/function/deploy.ts
|
|
16802
16821
|
async function loadFunctionCode(fn) {
|
|
16803
|
-
const
|
|
16822
|
+
const loadedFiles = await Promise.all(fn.files.map(async (filePath) => {
|
|
16823
|
+
const content = await readTextFile(filePath);
|
|
16824
|
+
return {
|
|
16825
|
+
path: basename(filePath),
|
|
16826
|
+
content
|
|
16827
|
+
};
|
|
16828
|
+
}));
|
|
16804
16829
|
return {
|
|
16805
16830
|
...fn,
|
|
16806
|
-
|
|
16831
|
+
files: loadedFiles
|
|
16807
16832
|
};
|
|
16808
16833
|
}
|
|
16809
16834
|
async function pushFunctions(functions) {
|
|
@@ -16877,6 +16902,11 @@ async function writeAgents(agentsDir, remoteAgents) {
|
|
|
16877
16902
|
//#endregion
|
|
16878
16903
|
//#region src/core/resources/agent/api.ts
|
|
16879
16904
|
async function pushAgents(agents) {
|
|
16905
|
+
if (agents.length === 0) return {
|
|
16906
|
+
created: [],
|
|
16907
|
+
updated: [],
|
|
16908
|
+
deleted: []
|
|
16909
|
+
};
|
|
16880
16910
|
const response = await getAppClient().put("agent-configs", {
|
|
16881
16911
|
json: agents,
|
|
16882
16912
|
throwHttpErrors: false
|
|
@@ -30600,25 +30630,27 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
30600
30630
|
* Checks if there are any resources to deploy in the project.
|
|
30601
30631
|
*
|
|
30602
30632
|
* @param projectData - The project configuration and resources
|
|
30603
|
-
* @returns true if there are entities, functions, or a configured site to deploy
|
|
30633
|
+
* @returns true if there are entities, functions, agents, or a configured site to deploy
|
|
30604
30634
|
*/
|
|
30605
30635
|
function hasResourcesToDeploy(projectData) {
|
|
30606
|
-
const { project, entities, functions } = projectData;
|
|
30636
|
+
const { project, entities, functions, agents } = projectData;
|
|
30607
30637
|
const hasSite = Boolean(project.site?.outputDirectory);
|
|
30608
30638
|
const hasEntities = entities.length > 0;
|
|
30609
30639
|
const hasFunctions = functions.length > 0;
|
|
30610
|
-
|
|
30640
|
+
const hasAgents = agents.length > 0;
|
|
30641
|
+
return hasEntities || hasFunctions || hasAgents || hasSite;
|
|
30611
30642
|
}
|
|
30612
30643
|
/**
|
|
30613
|
-
* Deploys all project resources (entities, functions, and site) to Base44.
|
|
30644
|
+
* Deploys all project resources (entities, functions, agents, and site) to Base44.
|
|
30614
30645
|
*
|
|
30615
30646
|
* @param projectData - The project configuration and resources to deploy
|
|
30616
30647
|
* @returns The deployment result including app URL if site was deployed
|
|
30617
30648
|
*/
|
|
30618
30649
|
async function deployAll(projectData) {
|
|
30619
|
-
const { project, entities, functions } = projectData;
|
|
30650
|
+
const { project, entities, functions, agents } = projectData;
|
|
30620
30651
|
await entityResource.push(entities);
|
|
30621
30652
|
await functionResource.push(functions);
|
|
30653
|
+
await agentResource.push(agents);
|
|
30622
30654
|
if (project.site?.outputDirectory) {
|
|
30623
30655
|
const { appUrl } = await deploySite(resolve(project.root, project.site.outputDirectory));
|
|
30624
30656
|
return { appUrl };
|
|
@@ -30630,11 +30662,31 @@ async function deployAll(projectData) {
|
|
|
30630
30662
|
//#region src/core/project/app-config.ts
|
|
30631
30663
|
let cache = null;
|
|
30632
30664
|
/**
|
|
30665
|
+
* Load app config from BASE44_CLI_TEST_OVERRIDES env var.
|
|
30666
|
+
* @returns true if override was applied, false otherwise
|
|
30667
|
+
*/
|
|
30668
|
+
function loadFromTestOverrides() {
|
|
30669
|
+
const overrides = process.env.BASE44_CLI_TEST_OVERRIDES;
|
|
30670
|
+
if (!overrides) return false;
|
|
30671
|
+
try {
|
|
30672
|
+
const data = JSON.parse(overrides);
|
|
30673
|
+
if (data.appConfig?.id && data.appConfig?.projectRoot) {
|
|
30674
|
+
cache = {
|
|
30675
|
+
id: data.appConfig.id,
|
|
30676
|
+
projectRoot: data.appConfig.projectRoot
|
|
30677
|
+
};
|
|
30678
|
+
return true;
|
|
30679
|
+
}
|
|
30680
|
+
} catch {}
|
|
30681
|
+
return false;
|
|
30682
|
+
}
|
|
30683
|
+
/**
|
|
30633
30684
|
* Initialize app config by reading from .app.jsonc.
|
|
30634
30685
|
* Must be called before using getAppConfig().
|
|
30635
30686
|
* @throws Error if no project found or .app.jsonc missing
|
|
30636
30687
|
*/
|
|
30637
30688
|
async function initAppConfig() {
|
|
30689
|
+
if (loadFromTestOverrides()) return;
|
|
30638
30690
|
if (cache) return;
|
|
30639
30691
|
const projectRoot = await findProjectRoot();
|
|
30640
30692
|
if (!projectRoot) throw new Error("No Base44 project found. Run this command from a project directory with a config.jsonc file.");
|
|
@@ -30754,7 +30806,7 @@ function getAppClient() {
|
|
|
30754
30806
|
|
|
30755
30807
|
//#endregion
|
|
30756
30808
|
//#region src/core/clients/schemas.ts
|
|
30757
|
-
const ApiErrorSchema = object({
|
|
30809
|
+
const ApiErrorSchema$1 = object({
|
|
30758
30810
|
error_type: string().optional(),
|
|
30759
30811
|
message: union([string(), record(string(), unknown())]).optional(),
|
|
30760
30812
|
detail: union([
|
|
@@ -31014,13 +31066,13 @@ var ansi_styles_default = ansiStyles;
|
|
|
31014
31066
|
|
|
31015
31067
|
//#endregion
|
|
31016
31068
|
//#region node_modules/chalk/source/vendor/supports-color/index.js
|
|
31017
|
-
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args :
|
|
31069
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : y.argv) {
|
|
31018
31070
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
31019
31071
|
const position = argv.indexOf(prefix + flag);
|
|
31020
31072
|
const terminatorPosition = argv.indexOf("--");
|
|
31021
31073
|
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
31022
31074
|
}
|
|
31023
|
-
const { env } =
|
|
31075
|
+
const { env } = y;
|
|
31024
31076
|
let flagForceColor;
|
|
31025
31077
|
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
|
|
31026
31078
|
else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
|
|
@@ -31053,7 +31105,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
31053
31105
|
if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
|
|
31054
31106
|
const min = forceColor || 0;
|
|
31055
31107
|
if (env.TERM === "dumb") return min;
|
|
31056
|
-
if (
|
|
31108
|
+
if (y.platform === "win32") {
|
|
31057
31109
|
const osRelease = os.release().split(".");
|
|
31058
31110
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
31059
31111
|
return 1;
|
|
@@ -31266,7 +31318,10 @@ const theme = {
|
|
|
31266
31318
|
base44OrangeBackground: source_default.bgHex("#E86B3C"),
|
|
31267
31319
|
shinyOrange: source_default.hex("#FFD700"),
|
|
31268
31320
|
links: source_default.hex("#00D4FF"),
|
|
31269
|
-
white: source_default.white
|
|
31321
|
+
white: source_default.white,
|
|
31322
|
+
success: source_default.green,
|
|
31323
|
+
warning: source_default.yellow,
|
|
31324
|
+
error: source_default.red
|
|
31270
31325
|
},
|
|
31271
31326
|
styles: {
|
|
31272
31327
|
header: source_default.dim,
|
|
@@ -31583,7 +31638,8 @@ const logoutCommand = new Command("logout").description("Logout from current dev
|
|
|
31583
31638
|
async function pushEntitiesAction() {
|
|
31584
31639
|
const { entities } = await readProjectConfig();
|
|
31585
31640
|
if (entities.length === 0) return { outroMessage: "No entities found in project" };
|
|
31586
|
-
|
|
31641
|
+
const entityNames = entities.map((e$1) => e$1.name).join(", ");
|
|
31642
|
+
M.info(`Found ${entities.length} entities to push: ${entityNames}`);
|
|
31587
31643
|
const result = await runTask("Pushing entities to Base44", async () => {
|
|
31588
31644
|
return await pushEntities(entities);
|
|
31589
31645
|
}, {
|
|
@@ -31843,9 +31899,9 @@ const getSubprocessResult = ({ stdout: stdout$1 }) => {
|
|
|
31843
31899
|
//#region node_modules/execa/lib/utils/standard-stream.js
|
|
31844
31900
|
const isStandardStream = (stream) => STANDARD_STREAMS.includes(stream);
|
|
31845
31901
|
const STANDARD_STREAMS = [
|
|
31846
|
-
|
|
31847
|
-
|
|
31848
|
-
|
|
31902
|
+
y.stdin,
|
|
31903
|
+
y.stdout,
|
|
31904
|
+
y.stderr
|
|
31849
31905
|
];
|
|
31850
31906
|
const STANDARD_STREAMS_ALIASES = [
|
|
31851
31907
|
"stdin",
|
|
@@ -31970,9 +32026,9 @@ const NO_ESCAPE_REGEXP = /^[\w./-]+$/;
|
|
|
31970
32026
|
//#endregion
|
|
31971
32027
|
//#region node_modules/is-unicode-supported/index.js
|
|
31972
32028
|
function isUnicodeSupported() {
|
|
31973
|
-
const { env: env$1 } =
|
|
32029
|
+
const { env: env$1 } = y;
|
|
31974
32030
|
const { TERM, TERM_PROGRAM } = env$1;
|
|
31975
|
-
if (
|
|
32031
|
+
if (y.platform !== "win32") return TERM !== "linux";
|
|
31976
32032
|
return Boolean(env$1.WT_SESSION) || Boolean(env$1.TERMINUS_SUBLIME) || env$1.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env$1.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
31977
32033
|
}
|
|
31978
32034
|
|
|
@@ -32899,7 +32955,7 @@ const TEN_MEGABYTES_IN_BYTES = 10 * 1024 * 1024;
|
|
|
32899
32955
|
|
|
32900
32956
|
//#endregion
|
|
32901
32957
|
//#region node_modules/npm-run-path/index.js
|
|
32902
|
-
const npmRunPath = ({ cwd =
|
|
32958
|
+
const npmRunPath = ({ cwd = y.cwd(), path: pathOption = y.env[pathKey()], preferLocal = true, execPath: execPath$1 = y.execPath, addExecPath = true } = {}) => {
|
|
32903
32959
|
const cwdPath = path.resolve(toPath(cwd));
|
|
32904
32960
|
const result = [];
|
|
32905
32961
|
const pathParts = pathOption.split(path.delimiter);
|
|
@@ -32917,7 +32973,7 @@ const applyExecPath = (result, pathParts, execPath$1, cwdPath) => {
|
|
|
32917
32973
|
const pathPart = path.resolve(cwdPath, toPath(execPath$1), "..");
|
|
32918
32974
|
if (!pathParts.includes(pathPart)) result.push(pathPart);
|
|
32919
32975
|
};
|
|
32920
|
-
const npmRunPathEnv = ({ env: env$1 =
|
|
32976
|
+
const npmRunPathEnv = ({ env: env$1 = y.env, ...options } = {}) => {
|
|
32921
32977
|
env$1 = { ...env$1 };
|
|
32922
32978
|
const pathName = pathKey({ env: env$1 });
|
|
32923
32979
|
options.path = env$1[pathName];
|
|
@@ -34052,7 +34108,7 @@ const normalizeCwd = (cwd = getDefaultCwd()) => {
|
|
|
34052
34108
|
};
|
|
34053
34109
|
const getDefaultCwd = () => {
|
|
34054
34110
|
try {
|
|
34055
|
-
return
|
|
34111
|
+
return y.cwd();
|
|
34056
34112
|
} catch (error) {
|
|
34057
34113
|
error.message = `The current directory does not exist.\n${error.message}`;
|
|
34058
34114
|
throw error;
|
|
@@ -34087,7 +34143,7 @@ const normalizeOptions = (filePath, rawArguments, rawOptions) => {
|
|
|
34087
34143
|
options.killSignal = normalizeKillSignal(options.killSignal);
|
|
34088
34144
|
options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay);
|
|
34089
34145
|
options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]);
|
|
34090
|
-
if (
|
|
34146
|
+
if (y.platform === "win32" && path.basename(file, ".exe") === "cmd") commandArguments.unshift("/q");
|
|
34091
34147
|
return {
|
|
34092
34148
|
file,
|
|
34093
34149
|
commandArguments,
|
|
@@ -34114,7 +34170,7 @@ const addDefaultOptions = ({ extendEnv = true, preferLocal = false, cwd, localDi
|
|
|
34114
34170
|
});
|
|
34115
34171
|
const getEnv = ({ env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath }) => {
|
|
34116
34172
|
const env$1 = extendEnv ? {
|
|
34117
|
-
...
|
|
34173
|
+
...y.env,
|
|
34118
34174
|
...envOption
|
|
34119
34175
|
} : envOption;
|
|
34120
34176
|
if (preferLocal || node) return npmRunPathEnv({
|
|
@@ -35114,12 +35170,12 @@ const guessStreamDirection = {
|
|
|
35114
35170
|
}
|
|
35115
35171
|
};
|
|
35116
35172
|
const getStandardStreamDirection = (value) => {
|
|
35117
|
-
if ([0,
|
|
35173
|
+
if ([0, y.stdin].includes(value)) return "input";
|
|
35118
35174
|
if ([
|
|
35119
35175
|
1,
|
|
35120
35176
|
2,
|
|
35121
|
-
|
|
35122
|
-
|
|
35177
|
+
y.stdout,
|
|
35178
|
+
y.stderr
|
|
35123
35179
|
].includes(value)) return "output";
|
|
35124
35180
|
};
|
|
35125
35181
|
const DEFAULT_DIRECTION = "output";
|
|
@@ -36183,9 +36239,9 @@ const addIpcMethods = (subprocess, { ipc }) => {
|
|
|
36183
36239
|
Object.assign(subprocess, getIpcMethods(subprocess, false, ipc));
|
|
36184
36240
|
};
|
|
36185
36241
|
const getIpcExport = () => {
|
|
36186
|
-
const anyProcess =
|
|
36242
|
+
const anyProcess = y;
|
|
36187
36243
|
const isSubprocess = true;
|
|
36188
|
-
const ipc =
|
|
36244
|
+
const ipc = y.channel !== void 0;
|
|
36189
36245
|
return {
|
|
36190
36246
|
...getIpcMethods(anyProcess, isSubprocess, ipc),
|
|
36191
36247
|
getCancelSignal: getCancelSignal$1.bind(void 0, {
|
|
@@ -36427,7 +36483,7 @@ if (process.platform === "linux") signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SI
|
|
|
36427
36483
|
|
|
36428
36484
|
//#endregion
|
|
36429
36485
|
//#region node_modules/signal-exit/dist/mjs/index.js
|
|
36430
|
-
const processOk = (process$
|
|
36486
|
+
const processOk = (process$4) => !!process$4 && typeof process$4 === "object" && typeof process$4.removeListener === "function" && typeof process$4.emit === "function" && typeof process$4.reallyExit === "function" && typeof process$4.listeners === "function" && typeof process$4.kill === "function" && typeof process$4.pid === "number" && typeof process$4.on === "function";
|
|
36431
36487
|
const kExitEmitter = Symbol.for("signal-exit emitter");
|
|
36432
36488
|
const global$1 = globalThis;
|
|
36433
36489
|
const ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
@@ -36495,7 +36551,7 @@ var SignalExitFallback = class extends SignalExitBase {
|
|
|
36495
36551
|
};
|
|
36496
36552
|
var SignalExit = class extends SignalExitBase {
|
|
36497
36553
|
/* c8 ignore start */
|
|
36498
|
-
#hupSig = process$
|
|
36554
|
+
#hupSig = process$1.platform === "win32" ? "SIGINT" : "SIGHUP";
|
|
36499
36555
|
/* c8 ignore stop */
|
|
36500
36556
|
#emitter = new Emitter();
|
|
36501
36557
|
#process;
|
|
@@ -36503,15 +36559,15 @@ var SignalExit = class extends SignalExitBase {
|
|
|
36503
36559
|
#originalProcessReallyExit;
|
|
36504
36560
|
#sigListeners = {};
|
|
36505
36561
|
#loaded = false;
|
|
36506
|
-
constructor(process$
|
|
36562
|
+
constructor(process$4) {
|
|
36507
36563
|
super();
|
|
36508
|
-
this.#process = process$
|
|
36564
|
+
this.#process = process$4;
|
|
36509
36565
|
this.#sigListeners = {};
|
|
36510
36566
|
for (const sig of signals) this.#sigListeners[sig] = () => {
|
|
36511
36567
|
const listeners = this.#process.listeners(sig);
|
|
36512
36568
|
let { count: count$1 } = this.#emitter;
|
|
36513
36569
|
/* c8 ignore start */
|
|
36514
|
-
const p$1 = process$
|
|
36570
|
+
const p$1 = process$4;
|
|
36515
36571
|
if (typeof p$1.__signal_exit_emitter__ === "object" && typeof p$1.__signal_exit_emitter__.count === "number") count$1 += p$1.__signal_exit_emitter__.count;
|
|
36516
36572
|
/* c8 ignore stop */
|
|
36517
36573
|
if (listeners.length === count$1) {
|
|
@@ -36519,11 +36575,11 @@ var SignalExit = class extends SignalExitBase {
|
|
|
36519
36575
|
const ret = this.#emitter.emit("exit", null, sig);
|
|
36520
36576
|
/* c8 ignore start */
|
|
36521
36577
|
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
36522
|
-
if (!ret) process$
|
|
36578
|
+
if (!ret) process$4.kill(process$4.pid, s);
|
|
36523
36579
|
}
|
|
36524
36580
|
};
|
|
36525
|
-
this.#originalProcessReallyExit = process$
|
|
36526
|
-
this.#originalProcessEmit = process$
|
|
36581
|
+
this.#originalProcessReallyExit = process$4.reallyExit;
|
|
36582
|
+
this.#originalProcessEmit = process$4.emit;
|
|
36527
36583
|
}
|
|
36528
36584
|
onExit(cb, opts) {
|
|
36529
36585
|
/* c8 ignore start */
|
|
@@ -36590,8 +36646,8 @@ var SignalExit = class extends SignalExitBase {
|
|
|
36590
36646
|
} else return og.call(this.#process, ev, ...args);
|
|
36591
36647
|
}
|
|
36592
36648
|
};
|
|
36593
|
-
const process$
|
|
36594
|
-
const { onExit, load, unload } = signalExitWrap(processOk(process$
|
|
36649
|
+
const process$1 = globalThis.process;
|
|
36650
|
+
const { onExit, load, unload } = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());
|
|
36595
36651
|
|
|
36596
36652
|
//#endregion
|
|
36597
36653
|
//#region node_modules/execa/lib/terminate/cleanup.js
|
|
@@ -38545,7 +38601,7 @@ function isInsideContainer() {
|
|
|
38545
38601
|
//#endregion
|
|
38546
38602
|
//#region node_modules/is-wsl/index.js
|
|
38547
38603
|
const isWsl = () => {
|
|
38548
|
-
if (
|
|
38604
|
+
if (y.platform !== "linux") return false;
|
|
38549
38605
|
if (os.release().toLowerCase().includes("microsoft")) {
|
|
38550
38606
|
if (isInsideContainer()) return false;
|
|
38551
38607
|
return true;
|
|
@@ -38556,12 +38612,12 @@ const isWsl = () => {
|
|
|
38556
38612
|
return false;
|
|
38557
38613
|
}
|
|
38558
38614
|
};
|
|
38559
|
-
var is_wsl_default =
|
|
38615
|
+
var is_wsl_default = y.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
38560
38616
|
|
|
38561
38617
|
//#endregion
|
|
38562
38618
|
//#region node_modules/powershell-utils/index.js
|
|
38563
38619
|
const execFile$2 = promisify(childProcess.execFile);
|
|
38564
|
-
const powerShellPath$1 = () => `${
|
|
38620
|
+
const powerShellPath$1 = () => `${y.env.SYSTEMROOT || y.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
38565
38621
|
const executePowerShell = async (command, options = {}) => {
|
|
38566
38622
|
const { powerShellPath: psPath, ...execFileOptions } = options;
|
|
38567
38623
|
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
@@ -38672,7 +38728,7 @@ function defineLazyProperty(object$1, propertyName, valueGetter) {
|
|
|
38672
38728
|
//#region node_modules/default-browser-id/index.js
|
|
38673
38729
|
const execFileAsync$3 = promisify(execFile);
|
|
38674
38730
|
async function defaultBrowserId() {
|
|
38675
|
-
if (
|
|
38731
|
+
if (y.platform !== "darwin") throw new Error("macOS only");
|
|
38676
38732
|
const { stdout: stdout$1 } = await execFileAsync$3("defaults", [
|
|
38677
38733
|
"read",
|
|
38678
38734
|
"com.apple.LaunchServices/com.apple.launchservices.secure",
|
|
@@ -38687,7 +38743,7 @@ async function defaultBrowserId() {
|
|
|
38687
38743
|
//#region node_modules/run-applescript/index.js
|
|
38688
38744
|
const execFileAsync$2 = promisify(execFile);
|
|
38689
38745
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
38690
|
-
if (
|
|
38746
|
+
if (y.platform !== "darwin") throw new Error("macOS only");
|
|
38691
38747
|
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
38692
38748
|
const execOptions = {};
|
|
38693
38749
|
if (signal) execOptions.signal = signal;
|
|
@@ -38796,14 +38852,14 @@ async function defaultBrowser$1(_execFileAsync = execFileAsync$1) {
|
|
|
38796
38852
|
const execFileAsync = promisify(execFile);
|
|
38797
38853
|
const titleize = (string$2) => string$2.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x$2) => x$2.toUpperCase());
|
|
38798
38854
|
async function defaultBrowser() {
|
|
38799
|
-
if (
|
|
38855
|
+
if (y.platform === "darwin") {
|
|
38800
38856
|
const id = await defaultBrowserId();
|
|
38801
38857
|
return {
|
|
38802
38858
|
name: await bundleName(id),
|
|
38803
38859
|
id
|
|
38804
38860
|
};
|
|
38805
38861
|
}
|
|
38806
|
-
if (
|
|
38862
|
+
if (y.platform === "linux") {
|
|
38807
38863
|
const { stdout: stdout$1 } = await execFileAsync("xdg-mime", [
|
|
38808
38864
|
"query",
|
|
38809
38865
|
"default",
|
|
@@ -38815,13 +38871,13 @@ async function defaultBrowser() {
|
|
|
38815
38871
|
id
|
|
38816
38872
|
};
|
|
38817
38873
|
}
|
|
38818
|
-
if (
|
|
38874
|
+
if (y.platform === "win32") return defaultBrowser$1();
|
|
38819
38875
|
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
38820
38876
|
}
|
|
38821
38877
|
|
|
38822
38878
|
//#endregion
|
|
38823
38879
|
//#region node_modules/is-in-ssh/index.js
|
|
38824
|
-
const isInSsh = Boolean(
|
|
38880
|
+
const isInSsh = Boolean(y.env.SSH_CONNECTION || y.env.SSH_CLIENT || y.env.SSH_TTY);
|
|
38825
38881
|
var is_in_ssh_default = isInSsh;
|
|
38826
38882
|
|
|
38827
38883
|
//#endregion
|
|
@@ -38829,7 +38885,7 @@ var is_in_ssh_default = isInSsh;
|
|
|
38829
38885
|
const fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
38830
38886
|
const __dirname = import.meta.url ? path.dirname(fileURLToPath(import.meta.url)) : "";
|
|
38831
38887
|
const localXdgOpenPath = path.join(__dirname, "xdg-open");
|
|
38832
|
-
const { platform: platform$1, arch } =
|
|
38888
|
+
const { platform: platform$1, arch } = y;
|
|
38833
38889
|
const tryEachApp = async (apps$1, opener) => {
|
|
38834
38890
|
if (apps$1.length === 0) return;
|
|
38835
38891
|
const errors = [];
|
|
@@ -38942,7 +38998,7 @@ const baseOpen = async (options) => {
|
|
|
38942
38998
|
await fs$1.access(localXdgOpenPath, constants$1.X_OK);
|
|
38943
38999
|
exeLocalXdgOpen = true;
|
|
38944
39000
|
} catch {}
|
|
38945
|
-
command =
|
|
39001
|
+
command = y.versions.electron ?? (platform$1 === "android" || isBundled || !exeLocalXdgOpen) ? "xdg-open" : localXdgOpenPath;
|
|
38946
39002
|
}
|
|
38947
39003
|
if (appArguments.length > 0) cliArguments.push(...appArguments);
|
|
38948
39004
|
if (!options.wait) {
|
|
@@ -39046,7 +39102,7 @@ var open_default = open;
|
|
|
39046
39102
|
//#region src/cli/commands/project/dashboard.ts
|
|
39047
39103
|
async function openDashboard() {
|
|
39048
39104
|
const dashboardUrl = getDashboardUrl();
|
|
39049
|
-
await open_default(dashboardUrl);
|
|
39105
|
+
if (!process.env.CI) await open_default(dashboardUrl);
|
|
39050
39106
|
return { outroMessage: `Dashboard opened at ${dashboardUrl}` };
|
|
39051
39107
|
}
|
|
39052
39108
|
const dashboardCommand = new Command("dashboard").description("Open the app dashboard in your browser").action(async () => {
|
|
@@ -39058,10 +39114,11 @@ const dashboardCommand = new Command("dashboard").description("Open the app dash
|
|
|
39058
39114
|
async function deployAction$1(options) {
|
|
39059
39115
|
const projectData = await readProjectConfig();
|
|
39060
39116
|
if (!hasResourcesToDeploy(projectData)) return { outroMessage: "No resources found to deploy" };
|
|
39061
|
-
const { project, entities, functions } = projectData;
|
|
39117
|
+
const { project, entities, functions, agents } = projectData;
|
|
39062
39118
|
const summaryLines = [];
|
|
39063
39119
|
if (entities.length > 0) summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
|
|
39064
39120
|
if (functions.length > 0) summaryLines.push(` - ${functions.length} ${functions.length === 1 ? "function" : "functions"}`);
|
|
39121
|
+
if (agents.length > 0) summaryLines.push(` - ${agents.length} ${agents.length === 1 ? "agent" : "agents"}`);
|
|
39065
39122
|
if (project.site?.outputDirectory) summaryLines.push(` - Site from ${project.site.outputDirectory}`);
|
|
39066
39123
|
if (!options.yes) {
|
|
39067
39124
|
M.warn(`This will update your Base44 app with:\n${summaryLines.join("\n")}`);
|
|
@@ -39078,7 +39135,7 @@ async function deployAction$1(options) {
|
|
|
39078
39135
|
if (result.appUrl) M.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
|
|
39079
39136
|
return { outroMessage: "App deployed successfully" };
|
|
39080
39137
|
}
|
|
39081
|
-
const deployCommand = new Command("deploy").description("Deploy all project resources (entities, functions, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
39138
|
+
const deployCommand = new Command("deploy").description("Deploy all project resources (entities, functions, agents, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
39082
39139
|
await runCommand(() => deployAction$1(options), { requireAuth: true });
|
|
39083
39140
|
});
|
|
39084
39141
|
|
|
@@ -39223,9 +39280,373 @@ const siteDeployCommand = new Command("site").description("Manage site deploymen
|
|
|
39223
39280
|
await runCommand(() => deployAction(options), { requireAuth: true });
|
|
39224
39281
|
}));
|
|
39225
39282
|
|
|
39283
|
+
//#endregion
|
|
39284
|
+
//#region src/core/connectors/schema.ts
|
|
39285
|
+
/**
|
|
39286
|
+
* Response from POST /api/apps/{app_id}/external-auth/initiate
|
|
39287
|
+
*/
|
|
39288
|
+
const InitiateResponseSchema = object({
|
|
39289
|
+
redirect_url: string().nullish(),
|
|
39290
|
+
connection_id: string().nullish(),
|
|
39291
|
+
already_authorized: boolean().nullish(),
|
|
39292
|
+
other_user_email: string().nullish(),
|
|
39293
|
+
error: string().nullish()
|
|
39294
|
+
});
|
|
39295
|
+
/**
|
|
39296
|
+
* Response from GET /api/apps/{app_id}/external-auth/status
|
|
39297
|
+
*/
|
|
39298
|
+
const StatusResponseSchema = object({
|
|
39299
|
+
status: _enum([
|
|
39300
|
+
"ACTIVE",
|
|
39301
|
+
"PENDING",
|
|
39302
|
+
"FAILED"
|
|
39303
|
+
]),
|
|
39304
|
+
account_email: string().nullish(),
|
|
39305
|
+
error: string().nullish()
|
|
39306
|
+
}).transform((data) => ({
|
|
39307
|
+
status: data.status,
|
|
39308
|
+
accountEmail: data.account_email,
|
|
39309
|
+
error: data.error
|
|
39310
|
+
}));
|
|
39311
|
+
/**
|
|
39312
|
+
* A connected integration from the list endpoint
|
|
39313
|
+
*/
|
|
39314
|
+
const ConnectorSchema = object({
|
|
39315
|
+
integration_type: string(),
|
|
39316
|
+
status: string(),
|
|
39317
|
+
connected_at: string().nullish(),
|
|
39318
|
+
account_info: object({
|
|
39319
|
+
email: string().nullish(),
|
|
39320
|
+
name: string().nullish()
|
|
39321
|
+
}).nullish()
|
|
39322
|
+
}).transform((data) => ({
|
|
39323
|
+
integrationType: data.integration_type,
|
|
39324
|
+
status: data.status,
|
|
39325
|
+
connectedAt: data.connected_at,
|
|
39326
|
+
accountInfo: data.account_info
|
|
39327
|
+
}));
|
|
39328
|
+
/**
|
|
39329
|
+
* Response from GET /api/apps/{app_id}/external-auth/list
|
|
39330
|
+
*/
|
|
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
|
+
});
|
|
39339
|
+
|
|
39340
|
+
//#endregion
|
|
39341
|
+
//#region src/core/connectors/api.ts
|
|
39342
|
+
/**
|
|
39343
|
+
* Initiates OAuth flow for a connector integration.
|
|
39344
|
+
* Returns a redirect URL to open in the browser.
|
|
39345
|
+
*/
|
|
39346
|
+
async function initiateOAuth(integrationType, scopes = null) {
|
|
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;
|
|
39363
|
+
}
|
|
39364
|
+
/**
|
|
39365
|
+
* Checks the status of an OAuth connection attempt.
|
|
39366
|
+
*/
|
|
39367
|
+
async function checkOAuthStatus(integrationType, connectionId) {
|
|
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;
|
|
39384
|
+
}
|
|
39385
|
+
/**
|
|
39386
|
+
* Lists all connected integrations for the current app.
|
|
39387
|
+
*/
|
|
39388
|
+
async function listConnectors() {
|
|
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;
|
|
39399
|
+
}
|
|
39400
|
+
/**
|
|
39401
|
+
* Disconnects (soft delete) a connector integration.
|
|
39402
|
+
*/
|
|
39403
|
+
async function disconnectConnector(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
|
+
}
|
|
39411
|
+
}
|
|
39412
|
+
/**
|
|
39413
|
+
* Removes (hard delete) a connector integration.
|
|
39414
|
+
* This permanently removes the connector and cannot be undone.
|
|
39415
|
+
*/
|
|
39416
|
+
async function removeConnector(integrationType) {
|
|
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
|
+
}
|
|
39424
|
+
}
|
|
39425
|
+
|
|
39426
|
+
//#endregion
|
|
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;
|
|
39433
|
+
/**
|
|
39434
|
+
* Supported OAuth connector integrations.
|
|
39435
|
+
* Based on apper/backend/app/external_auth/models/constants.py
|
|
39436
|
+
*/
|
|
39437
|
+
const SUPPORTED_INTEGRATIONS = [
|
|
39438
|
+
"googlecalendar",
|
|
39439
|
+
"googledrive",
|
|
39440
|
+
"gmail",
|
|
39441
|
+
"googlesheets",
|
|
39442
|
+
"googledocs",
|
|
39443
|
+
"googleslides",
|
|
39444
|
+
"slack",
|
|
39445
|
+
"notion",
|
|
39446
|
+
"salesforce",
|
|
39447
|
+
"hubspot",
|
|
39448
|
+
"linkedin",
|
|
39449
|
+
"tiktok"
|
|
39450
|
+
];
|
|
39451
|
+
/**
|
|
39452
|
+
* Display names for integrations (for CLI output)
|
|
39453
|
+
*/
|
|
39454
|
+
const INTEGRATION_DISPLAY_NAMES = {
|
|
39455
|
+
googlecalendar: "Google Calendar",
|
|
39456
|
+
googledrive: "Google Drive",
|
|
39457
|
+
gmail: "Gmail",
|
|
39458
|
+
googlesheets: "Google Sheets",
|
|
39459
|
+
googledocs: "Google Docs",
|
|
39460
|
+
googleslides: "Google Slides",
|
|
39461
|
+
slack: "Slack",
|
|
39462
|
+
notion: "Notion",
|
|
39463
|
+
salesforce: "Salesforce",
|
|
39464
|
+
hubspot: "HubSpot",
|
|
39465
|
+
linkedin: "LinkedIn",
|
|
39466
|
+
tiktok: "TikTok"
|
|
39467
|
+
};
|
|
39468
|
+
function isValidIntegration(type) {
|
|
39469
|
+
return SUPPORTED_INTEGRATIONS.includes(type);
|
|
39470
|
+
}
|
|
39471
|
+
function getIntegrationDisplayName(type) {
|
|
39472
|
+
if (isValidIntegration(type)) return INTEGRATION_DISPLAY_NAMES[type];
|
|
39473
|
+
return type;
|
|
39474
|
+
}
|
|
39475
|
+
|
|
39476
|
+
//#endregion
|
|
39477
|
+
//#region src/core/connectors/oauth.ts
|
|
39478
|
+
/**
|
|
39479
|
+
* Polls for OAuth completion status.
|
|
39480
|
+
* Returns when status becomes ACTIVE or FAILED, or times out.
|
|
39481
|
+
*/
|
|
39482
|
+
async function waitForOAuthCompletion(integrationType, connectionId, options) {
|
|
39483
|
+
let accountEmail;
|
|
39484
|
+
let error;
|
|
39485
|
+
try {
|
|
39486
|
+
await pWaitFor(async () => {
|
|
39487
|
+
const status = await checkOAuthStatus(integrationType, connectionId);
|
|
39488
|
+
if (status.status === "ACTIVE") {
|
|
39489
|
+
accountEmail = status.accountEmail ?? void 0;
|
|
39490
|
+
return true;
|
|
39491
|
+
}
|
|
39492
|
+
if (status.status === "FAILED") {
|
|
39493
|
+
error = status.error || "Authorization failed";
|
|
39494
|
+
throw new Error(error);
|
|
39495
|
+
}
|
|
39496
|
+
options?.onPending?.();
|
|
39497
|
+
return false;
|
|
39498
|
+
}, {
|
|
39499
|
+
interval: OAUTH_POLL_INTERVAL_MS,
|
|
39500
|
+
timeout: OAUTH_POLL_TIMEOUT_MS
|
|
39501
|
+
});
|
|
39502
|
+
return {
|
|
39503
|
+
success: true,
|
|
39504
|
+
accountEmail
|
|
39505
|
+
};
|
|
39506
|
+
} catch (err) {
|
|
39507
|
+
if (err instanceof Error && err.message.includes("timed out")) return {
|
|
39508
|
+
success: false,
|
|
39509
|
+
error: "Authorization timed out. Please try again."
|
|
39510
|
+
};
|
|
39511
|
+
return {
|
|
39512
|
+
success: false,
|
|
39513
|
+
error: error || (err instanceof Error ? err.message : "Unknown error")
|
|
39514
|
+
};
|
|
39515
|
+
}
|
|
39516
|
+
}
|
|
39517
|
+
|
|
39518
|
+
//#endregion
|
|
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
|
+
}
|
|
39527
|
+
async function promptForIntegrationType() {
|
|
39528
|
+
const selected = await ve({
|
|
39529
|
+
message: "Select an integration to connect:",
|
|
39530
|
+
options: SUPPORTED_INTEGRATIONS.map((type) => ({
|
|
39531
|
+
value: type,
|
|
39532
|
+
label: getIntegrationDisplayName(type)
|
|
39533
|
+
}))
|
|
39534
|
+
});
|
|
39535
|
+
if (pD(selected)) {
|
|
39536
|
+
xe("Operation cancelled.");
|
|
39537
|
+
process.exit(0);
|
|
39538
|
+
}
|
|
39539
|
+
return selected;
|
|
39540
|
+
}
|
|
39541
|
+
async function pollForOAuthCompletion(integrationType, connectionId) {
|
|
39542
|
+
return await runTask("Waiting for authorization...", async () => {
|
|
39543
|
+
return await waitForOAuthCompletion(integrationType, connectionId);
|
|
39544
|
+
}, {
|
|
39545
|
+
successMessage: "Authorization completed!",
|
|
39546
|
+
errorMessage: "Authorization failed"
|
|
39547
|
+
});
|
|
39548
|
+
}
|
|
39549
|
+
async function addConnector(integrationType) {
|
|
39550
|
+
const selectedType = integrationType ? validateIntegrationType(integrationType) : await promptForIntegrationType();
|
|
39551
|
+
const displayName = getIntegrationDisplayName(selectedType);
|
|
39552
|
+
const initiateResponse = await runTask(`Initiating ${displayName} connection...`, async () => {
|
|
39553
|
+
return await initiateOAuth(selectedType);
|
|
39554
|
+
}, {
|
|
39555
|
+
successMessage: `${displayName} OAuth initiated`,
|
|
39556
|
+
errorMessage: `Failed to initiate ${displayName} connection`
|
|
39557
|
+
});
|
|
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);
|
|
39563
|
+
if (!result.success) throw new Error(result.error || "Authorization failed");
|
|
39564
|
+
const accountInfo = result.accountEmail ? ` as ${theme.styles.bold(result.accountEmail)}` : "";
|
|
39565
|
+
return { outroMessage: `Successfully connected to ${theme.styles.bold(displayName)}${accountInfo}` };
|
|
39566
|
+
}
|
|
39567
|
+
const connectorsAddCommand = new Command("add").argument("[type]", "Integration type (e.g., slack, notion, googlecalendar)").description("Connect an OAuth integration").action(async (type) => {
|
|
39568
|
+
await runCommand(() => addConnector(type), {
|
|
39569
|
+
requireAuth: true,
|
|
39570
|
+
requireAppConfig: true
|
|
39571
|
+
});
|
|
39572
|
+
});
|
|
39573
|
+
|
|
39574
|
+
//#endregion
|
|
39575
|
+
//#region src/cli/commands/connectors/remove.ts
|
|
39576
|
+
function mapBackendConnectors(connectors) {
|
|
39577
|
+
return connectors.filter((c$1) => isValidIntegration(c$1.integrationType)).map((c$1) => ({
|
|
39578
|
+
type: c$1.integrationType,
|
|
39579
|
+
displayName: getIntegrationDisplayName(c$1.integrationType),
|
|
39580
|
+
accountEmail: (c$1.accountInfo?.email || c$1.accountInfo?.name) ?? void 0
|
|
39581
|
+
}));
|
|
39582
|
+
}
|
|
39583
|
+
function validateConnectorType(type, connectors) {
|
|
39584
|
+
if (!isValidIntegration(type)) throw new Error(`Invalid connector type: ${type}`);
|
|
39585
|
+
const connector = connectors.find((c$1) => c$1.type === type);
|
|
39586
|
+
if (!connector) throw new Error(`No ${getIntegrationDisplayName(type)} connector found`);
|
|
39587
|
+
return connector;
|
|
39588
|
+
}
|
|
39589
|
+
async function promptForConnectorToRemove(connectors) {
|
|
39590
|
+
const selected = await ve({
|
|
39591
|
+
message: "Select a connector to remove:",
|
|
39592
|
+
options: connectors.map((c$1) => {
|
|
39593
|
+
let label = c$1.displayName;
|
|
39594
|
+
if (c$1.accountEmail) label += ` (${c$1.accountEmail})`;
|
|
39595
|
+
return {
|
|
39596
|
+
value: c$1.type,
|
|
39597
|
+
label
|
|
39598
|
+
};
|
|
39599
|
+
})
|
|
39600
|
+
});
|
|
39601
|
+
if (pD(selected)) {
|
|
39602
|
+
xe("Operation cancelled.");
|
|
39603
|
+
process.exit(0);
|
|
39604
|
+
}
|
|
39605
|
+
return connectors.find((c$1) => c$1.type === selected);
|
|
39606
|
+
}
|
|
39607
|
+
async function removeConnectorCommand(integrationType, options = {}) {
|
|
39608
|
+
const isHardDelete = options.hard === true;
|
|
39609
|
+
const connectors = mapBackendConnectors(await runTask("Fetching connectors...", async () => listConnectors(), {
|
|
39610
|
+
successMessage: "Connectors loaded",
|
|
39611
|
+
errorMessage: "Failed to fetch connectors"
|
|
39612
|
+
}));
|
|
39613
|
+
if (connectors.length === 0) return { outroMessage: "No connectors to remove" };
|
|
39614
|
+
const selectedConnector = integrationType ? validateConnectorType(integrationType, connectors) : await promptForConnectorToRemove(connectors);
|
|
39615
|
+
const displayName = selectedConnector.displayName;
|
|
39616
|
+
const accountInfo = selectedConnector.accountEmail ? ` (${selectedConnector.accountEmail})` : "";
|
|
39617
|
+
if (!options.yes) {
|
|
39618
|
+
const shouldRemove = await ye({
|
|
39619
|
+
message: `${isHardDelete ? "Permanently remove" : "Remove"} ${displayName}${accountInfo}?`,
|
|
39620
|
+
initialValue: false
|
|
39621
|
+
});
|
|
39622
|
+
if (pD(shouldRemove) || !shouldRemove) {
|
|
39623
|
+
xe("Operation cancelled.");
|
|
39624
|
+
process.exit(0);
|
|
39625
|
+
}
|
|
39626
|
+
}
|
|
39627
|
+
await runTask(`Removing ${displayName}...`, async () => {
|
|
39628
|
+
if (isHardDelete) await removeConnector(selectedConnector.type);
|
|
39629
|
+
else await disconnectConnector(selectedConnector.type);
|
|
39630
|
+
}, {
|
|
39631
|
+
successMessage: `${displayName} removed`,
|
|
39632
|
+
errorMessage: `Failed to remove ${displayName}`
|
|
39633
|
+
});
|
|
39634
|
+
return { outroMessage: `Successfully removed ${theme.styles.bold(displayName)}` };
|
|
39635
|
+
}
|
|
39636
|
+
const connectorsRemoveCommand = new Command("remove").argument("[type]", "Integration type to remove (e.g., slack, notion)").option("--hard", "Permanently remove the connector (cannot be undone)").option("-y, --yes", "Skip confirmation prompt").description("Remove an OAuth integration").action(async (type, options) => {
|
|
39637
|
+
await runCommand(() => removeConnectorCommand(type, options), {
|
|
39638
|
+
requireAuth: true,
|
|
39639
|
+
requireAppConfig: true
|
|
39640
|
+
});
|
|
39641
|
+
});
|
|
39642
|
+
|
|
39643
|
+
//#endregion
|
|
39644
|
+
//#region src/cli/commands/connectors/index.ts
|
|
39645
|
+
const connectorsCommand = new Command("connectors").description("Manage OAuth connectors").addCommand(connectorsAddCommand).addCommand(connectorsRemoveCommand);
|
|
39646
|
+
|
|
39226
39647
|
//#endregion
|
|
39227
39648
|
//#region package.json
|
|
39228
|
-
var version = "0.0.
|
|
39649
|
+
var version = "0.0.25";
|
|
39229
39650
|
|
|
39230
39651
|
//#endregion
|
|
39231
39652
|
//#region src/cli/program.ts
|
|
@@ -39243,6 +39664,7 @@ program.addCommand(entitiesPushCommand);
|
|
|
39243
39664
|
program.addCommand(agentsCommand);
|
|
39244
39665
|
program.addCommand(functionsDeployCommand);
|
|
39245
39666
|
program.addCommand(siteDeployCommand);
|
|
39667
|
+
program.addCommand(connectorsCommand);
|
|
39246
39668
|
|
|
39247
39669
|
//#endregion
|
|
39248
39670
|
export { CLIExitError, program };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@base44-preview/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25-pr.104.a8520b5",
|
|
4
4
|
"description": "Base44 CLI - Unified interface for managing Base44 applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dev": "./bin/dev.js",
|
|
17
17
|
"start": "./bin/run.js",
|
|
18
18
|
"clean": "rm -rf dist",
|
|
19
|
-
"lint": "eslint src",
|
|
19
|
+
"lint": "eslint src tests",
|
|
20
20
|
"test": "vitest run",
|
|
21
21
|
"test:watch": "vitest"
|
|
22
22
|
},
|
|
@@ -52,9 +52,12 @@
|
|
|
52
52
|
"json5": "^2.2.3",
|
|
53
53
|
"ky": "^1.14.2",
|
|
54
54
|
"lodash.kebabcase": "^4.1.1",
|
|
55
|
+
"msw": "^2.12.7",
|
|
55
56
|
"open": "^11.0.0",
|
|
56
57
|
"p-wait-for": "^6.0.0",
|
|
58
|
+
"strip-ansi": "^7.1.2",
|
|
57
59
|
"tar": "^7.5.4",
|
|
60
|
+
"tmp-promise": "^3.0.3",
|
|
58
61
|
"tsdown": "^0.12.4",
|
|
59
62
|
"tsx": "^4.19.2",
|
|
60
63
|
"typescript": "^5.7.2",
|
|
@@ -64,5 +67,8 @@
|
|
|
64
67
|
},
|
|
65
68
|
"engines": {
|
|
66
69
|
"node": ">=20.19.0"
|
|
70
|
+
},
|
|
71
|
+
"optionalDependencies": {
|
|
72
|
+
"@rollup/rollup-linux-x64-gnu": "^4.56.0"
|
|
67
73
|
}
|
|
68
74
|
}
|