@base44-preview/cli 0.0.32-pr.249.38b7e86 → 0.0.32-pr.249.42818fe
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/LICENSE +21 -0
- package/README.md +9 -5
- package/dist/cli/index.js +147 -146
- package/dist/cli/index.js.map +17 -17
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 base44
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -43,19 +43,23 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
|
|
|
43
43
|
|
|
44
44
|
| Command | Description |
|
|
45
45
|
| ------- | ----------- |
|
|
46
|
-
| [`create`](https://docs.base44.com/developers/references/cli/commands/create) | Create a new Base44 project
|
|
47
|
-
| [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy resources and site to Base44 |
|
|
48
|
-
| [`link`](https://docs.base44.com/developers/references/cli/commands/link) | Link a local project to a project
|
|
46
|
+
| [`create`](https://docs.base44.com/developers/references/cli/commands/create) | Create a new Base44 project |
|
|
47
|
+
| [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy all project resources and site to Base44 |
|
|
48
|
+
| [`link`](https://docs.base44.com/developers/references/cli/commands/link) | Link a local project to a Base44 project (create new or link existing) |
|
|
49
|
+
| [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Download the code for an existing Base44 project |
|
|
49
50
|
| [`dashboard open`](https://docs.base44.com/developers/references/cli/commands/dashboard) | Open the app dashboard in your browser |
|
|
50
51
|
| [`login`](https://docs.base44.com/developers/references/cli/commands/login) | Authenticate with Base44 |
|
|
51
|
-
| [`logout`](https://docs.base44.com/developers/references/cli/commands/logout) |
|
|
52
|
+
| [`logout`](https://docs.base44.com/developers/references/cli/commands/logout) | Logout from current device |
|
|
52
53
|
| [`whoami`](https://docs.base44.com/developers/references/cli/commands/whoami) | Display the current authenticated user |
|
|
53
54
|
| [`agents pull`](https://docs.base44.com/developers/references/cli/commands/agents-pull) | Pull agents from Base44 to local files |
|
|
54
55
|
| [`agents push`](https://docs.base44.com/developers/references/cli/commands/agents-push) | Push local agents to Base44 |
|
|
55
|
-
| [`
|
|
56
|
+
| [`connectors pull`](https://docs.base44.com/developers/references/cli/commands/connectors-pull) | Pull connectors from Base44 to local files |
|
|
57
|
+
| [`connectors push`](https://docs.base44.com/developers/references/cli/commands/connectors-push) | Push local connectors to Base44 |
|
|
58
|
+
| [`entities push`](https://docs.base44.com/developers/references/cli/commands/entities-push) | Push local entities to Base44 |
|
|
56
59
|
| [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy local functions to Base44 |
|
|
57
60
|
| [`site deploy`](https://docs.base44.com/developers/references/cli/commands/site-deploy) | Deploy built site files to Base44 hosting |
|
|
58
61
|
| [`site open`](https://docs.base44.com/developers/references/cli/commands/site-open) | Open the published site in your browser |
|
|
62
|
+
| [`types generate`](https://docs.base44.com/developers/references/cli/commands/types-generate) | Generate TypeScript types from project resources |
|
|
59
63
|
|
|
60
64
|
|
|
61
65
|
<!--| [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Create a Base44 backend project from an existing Base44 app | -->
|
package/dist/cli/index.js
CHANGED
|
@@ -178102,6 +178102,18 @@ class InvalidInputError extends UserError {
|
|
|
178102
178102
|
code = "INVALID_INPUT";
|
|
178103
178103
|
}
|
|
178104
178104
|
|
|
178105
|
+
class DependencyNotFoundError extends UserError {
|
|
178106
|
+
code = "DEPENDENCY_NOT_FOUND";
|
|
178107
|
+
constructor(message, options) {
|
|
178108
|
+
super(message, {
|
|
178109
|
+
hints: options?.hints ?? [
|
|
178110
|
+
{ message: "Install the required dependency and try again" }
|
|
178111
|
+
],
|
|
178112
|
+
cause: options?.cause
|
|
178113
|
+
});
|
|
178114
|
+
}
|
|
178115
|
+
}
|
|
178116
|
+
|
|
178105
178117
|
class ApiError extends SystemError {
|
|
178106
178118
|
code = "API_ERROR";
|
|
178107
178119
|
statusCode;
|
|
@@ -178217,6 +178229,21 @@ class FileReadError extends SystemError {
|
|
|
178217
178229
|
});
|
|
178218
178230
|
}
|
|
178219
178231
|
}
|
|
178232
|
+
|
|
178233
|
+
class InternalError extends SystemError {
|
|
178234
|
+
code = "INTERNAL_ERROR";
|
|
178235
|
+
constructor(message, options) {
|
|
178236
|
+
super(message, {
|
|
178237
|
+
hints: options?.hints ?? [
|
|
178238
|
+
{
|
|
178239
|
+
message: "This is an unexpected error. Please report it if it persists."
|
|
178240
|
+
}
|
|
178241
|
+
],
|
|
178242
|
+
cause: options?.cause
|
|
178243
|
+
});
|
|
178244
|
+
}
|
|
178245
|
+
}
|
|
178246
|
+
|
|
178220
178247
|
class TypeGenerationError extends SystemError {
|
|
178221
178248
|
code = "TYPE_GENERATION_ERROR";
|
|
178222
178249
|
entityName;
|
|
@@ -186654,7 +186681,9 @@ var theme = {
|
|
|
186654
186681
|
styles: {
|
|
186655
186682
|
header: source_default.dim,
|
|
186656
186683
|
bold: source_default.bold,
|
|
186657
|
-
dim: source_default.dim
|
|
186684
|
+
dim: source_default.dim,
|
|
186685
|
+
error: source_default.red,
|
|
186686
|
+
warn: source_default.yellow
|
|
186658
186687
|
},
|
|
186659
186688
|
format: {
|
|
186660
186689
|
errorContext(ctx) {
|
|
@@ -186756,12 +186785,12 @@ var BANNER_LINES = [
|
|
|
186756
186785
|
"██████╔╝██║ ██║███████║███████╗ ██║ ██║",
|
|
186757
186786
|
"╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
|
|
186758
186787
|
];
|
|
186759
|
-
async function printBanner() {
|
|
186760
|
-
if (
|
|
186761
|
-
await printAnimatedLines(BANNER_LINES);
|
|
186762
|
-
} else {
|
|
186788
|
+
async function printBanner(isNonInteractive) {
|
|
186789
|
+
if (isNonInteractive) {
|
|
186763
186790
|
console.log(theme.colors.base44Orange(BANNER_LINES.join(`
|
|
186764
186791
|
`)));
|
|
186792
|
+
} else {
|
|
186793
|
+
await printAnimatedLines(BANNER_LINES);
|
|
186765
186794
|
}
|
|
186766
186795
|
}
|
|
186767
186796
|
// src/cli/errors.ts
|
|
@@ -193466,7 +193495,7 @@ var package_default = {
|
|
|
193466
193495
|
"command-line"
|
|
193467
193496
|
],
|
|
193468
193497
|
author: "",
|
|
193469
|
-
license: "
|
|
193498
|
+
license: "MIT",
|
|
193470
193499
|
repository: {
|
|
193471
193500
|
type: "git",
|
|
193472
193501
|
url: "https://github.com/base44/cli"
|
|
@@ -193566,7 +193595,7 @@ async function printUpgradeNotificationIfAvailable() {
|
|
|
193566
193595
|
async function runCommand(commandFn, options, context) {
|
|
193567
193596
|
console.log();
|
|
193568
193597
|
if (options?.fullBanner) {
|
|
193569
|
-
await printBanner();
|
|
193598
|
+
await printBanner(context.isNonInteractive);
|
|
193570
193599
|
Ie("");
|
|
193571
193600
|
} else {
|
|
193572
193601
|
Ie(theme.colors.base44OrangeBackground(" Base 44 "));
|
|
@@ -194496,7 +194525,7 @@ function printSummary(results, oauthOutcomes) {
|
|
|
194496
194525
|
M2.error(`Failed: ${r2.type}${r2.error ? ` - ${r2.error}` : ""}`);
|
|
194497
194526
|
}
|
|
194498
194527
|
}
|
|
194499
|
-
async function pushConnectorsAction() {
|
|
194528
|
+
async function pushConnectorsAction(isNonInteractive) {
|
|
194500
194529
|
const { connectors } = await readProjectConfig();
|
|
194501
194530
|
if (connectors.length === 0) {
|
|
194502
194531
|
M2.info("No local connectors found - checking for remote connectors to remove");
|
|
@@ -194510,18 +194539,18 @@ async function pushConnectorsAction() {
|
|
|
194510
194539
|
const needsOAuth = filterPendingOAuth(results);
|
|
194511
194540
|
let outroMessage = "Connectors pushed to Base44";
|
|
194512
194541
|
const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
|
|
194513
|
-
skipPrompt:
|
|
194542
|
+
skipPrompt: isNonInteractive
|
|
194514
194543
|
});
|
|
194515
194544
|
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
194516
194545
|
if (needsOAuth.length > 0 && !allAuthorized) {
|
|
194517
|
-
outroMessage =
|
|
194546
|
+
outroMessage = isNonInteractive ? "Skipped OAuth in non-interactive mode. Run 'base44 connectors push' locally or open the links above to authorize." : "Some connectors still require authorization. Run 'base44 connectors push' or open the links above to authorize.";
|
|
194518
194547
|
}
|
|
194519
194548
|
printSummary(results, oauthOutcomes);
|
|
194520
194549
|
return { outroMessage };
|
|
194521
194550
|
}
|
|
194522
194551
|
function getConnectorsPushCommand(context) {
|
|
194523
194552
|
return new Command("push").description("Push local connectors to Base44 (overwrites connectors on Base44)").action(async () => {
|
|
194524
|
-
await runCommand(pushConnectorsAction, { requireAuth: true }, context);
|
|
194553
|
+
await runCommand(() => pushConnectorsAction(context.isNonInteractive), { requireAuth: true }, context);
|
|
194525
194554
|
});
|
|
194526
194555
|
}
|
|
194527
194556
|
|
|
@@ -194531,16 +194560,16 @@ function getConnectorsCommand(context) {
|
|
|
194531
194560
|
}
|
|
194532
194561
|
|
|
194533
194562
|
// src/cli/commands/dashboard/open.ts
|
|
194534
|
-
async function openDashboard() {
|
|
194563
|
+
async function openDashboard(isNonInteractive) {
|
|
194535
194564
|
const dashboardUrl = getDashboardUrl();
|
|
194536
|
-
if (!
|
|
194565
|
+
if (!isNonInteractive) {
|
|
194537
194566
|
await open_default(dashboardUrl);
|
|
194538
194567
|
}
|
|
194539
194568
|
return { outroMessage: `Dashboard opened at ${dashboardUrl}` };
|
|
194540
194569
|
}
|
|
194541
194570
|
function getDashboardOpenCommand(context) {
|
|
194542
194571
|
return new Command("open").description("Open the app dashboard in your browser").action(async () => {
|
|
194543
|
-
await runCommand(openDashboard, { requireAuth: true }, context);
|
|
194572
|
+
await runCommand(() => openDashboard(context.isNonInteractive), { requireAuth: true }, context);
|
|
194544
194573
|
});
|
|
194545
194574
|
}
|
|
194546
194575
|
|
|
@@ -194846,7 +194875,7 @@ ${summaryLines.join(`
|
|
|
194846
194875
|
const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
|
|
194847
194876
|
if (needsOAuth.length > 0) {
|
|
194848
194877
|
const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
|
|
194849
|
-
skipPrompt: options.yes ||
|
|
194878
|
+
skipPrompt: options.yes || options.isNonInteractive
|
|
194850
194879
|
});
|
|
194851
194880
|
const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
|
|
194852
194881
|
if (!allAuthorized) {
|
|
@@ -194861,7 +194890,10 @@ ${summaryLines.join(`
|
|
|
194861
194890
|
}
|
|
194862
194891
|
function getDeployCommand(context) {
|
|
194863
194892
|
return new Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
194864
|
-
await runCommand(() => deployAction(
|
|
194893
|
+
await runCommand(() => deployAction({
|
|
194894
|
+
...options,
|
|
194895
|
+
isNonInteractive: context.isNonInteractive
|
|
194896
|
+
}), { requireAuth: true }, context);
|
|
194865
194897
|
});
|
|
194866
194898
|
}
|
|
194867
194899
|
|
|
@@ -195043,21 +195075,24 @@ async function deployAction2(options) {
|
|
|
195043
195075
|
}
|
|
195044
195076
|
function getSiteDeployCommand(context) {
|
|
195045
195077
|
return new Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
195046
|
-
await runCommand(() => deployAction2(
|
|
195078
|
+
await runCommand(() => deployAction2({
|
|
195079
|
+
...options,
|
|
195080
|
+
isNonInteractive: context.isNonInteractive
|
|
195081
|
+
}), { requireAuth: true }, context);
|
|
195047
195082
|
});
|
|
195048
195083
|
}
|
|
195049
195084
|
|
|
195050
195085
|
// src/cli/commands/site/open.ts
|
|
195051
|
-
async function openAction() {
|
|
195086
|
+
async function openAction(isNonInteractive) {
|
|
195052
195087
|
const siteUrl = await getSiteUrl();
|
|
195053
|
-
if (!
|
|
195088
|
+
if (!isNonInteractive) {
|
|
195054
195089
|
await open_default(siteUrl);
|
|
195055
195090
|
}
|
|
195056
195091
|
return { outroMessage: `Site opened at ${siteUrl}` };
|
|
195057
195092
|
}
|
|
195058
195093
|
function getSiteOpenCommand(context) {
|
|
195059
195094
|
return new Command("open").description("Open the published site in your browser").action(async () => {
|
|
195060
|
-
await runCommand(openAction, { requireAuth: true }, context);
|
|
195095
|
+
await runCommand(() => openAction(context.isNonInteractive), { requireAuth: true }, context);
|
|
195061
195096
|
});
|
|
195062
195097
|
}
|
|
195063
195098
|
|
|
@@ -195198,9 +195233,9 @@ function getTypesCommand(context) {
|
|
|
195198
195233
|
}
|
|
195199
195234
|
|
|
195200
195235
|
// src/cli/dev/dev-server/main.ts
|
|
195236
|
+
import { dirname as dirname12, join as join16 } from "node:path";
|
|
195201
195237
|
var import_cors = __toESM(require_lib4(), 1);
|
|
195202
195238
|
var import_express2 = __toESM(require_express(), 1);
|
|
195203
|
-
import { dirname as dirname12, join as join16 } from "node:path";
|
|
195204
195239
|
|
|
195205
195240
|
// node_modules/get-port/index.js
|
|
195206
195241
|
import net from "node:net";
|
|
@@ -195317,49 +195352,20 @@ async function getPorts(options8) {
|
|
|
195317
195352
|
}
|
|
195318
195353
|
|
|
195319
195354
|
// src/cli/dev/dev-server/main.ts
|
|
195320
|
-
var
|
|
195355
|
+
var import_http_proxy_middleware2 = __toESM(require_dist2(), 1);
|
|
195321
195356
|
|
|
195322
195357
|
// src/cli/dev/createDevLogger.ts
|
|
195323
|
-
var dateTimeFormat = new Intl.DateTimeFormat([], {
|
|
195324
|
-
hour: "2-digit",
|
|
195325
|
-
minute: "2-digit",
|
|
195326
|
-
second: "2-digit",
|
|
195327
|
-
hour12: false
|
|
195328
|
-
});
|
|
195329
195358
|
var colorByType = {
|
|
195330
|
-
error:
|
|
195331
|
-
warn:
|
|
195359
|
+
error: theme.styles.error,
|
|
195360
|
+
warn: theme.styles.warn,
|
|
195332
195361
|
log: (text) => text
|
|
195333
195362
|
};
|
|
195334
|
-
function createDevLogger(
|
|
195363
|
+
function createDevLogger() {
|
|
195335
195364
|
const print = (type, msg) => {
|
|
195336
195365
|
const colorize = colorByType[type];
|
|
195337
|
-
|
|
195338
|
-
case "error":
|
|
195339
|
-
console.error(colorize(msg));
|
|
195340
|
-
break;
|
|
195341
|
-
case "warn":
|
|
195342
|
-
console.warn(colorize(msg));
|
|
195343
|
-
break;
|
|
195344
|
-
default:
|
|
195345
|
-
console.log(msg);
|
|
195346
|
-
}
|
|
195347
|
-
};
|
|
195348
|
-
const prefixedLog = (type, msg) => {
|
|
195349
|
-
const timestamp = dateTimeFormat.format(new Date);
|
|
195350
|
-
const colorize = colorByType[type];
|
|
195351
|
-
console.log(`${source_default.gray(timestamp)} ${colorize(msg)}`);
|
|
195366
|
+
console[type](colorize(msg));
|
|
195352
195367
|
};
|
|
195353
|
-
return
|
|
195354
|
-
log: (msg) => prefixedLog("log", msg),
|
|
195355
|
-
error: (msg, err) => {
|
|
195356
|
-
prefixedLog("error", msg);
|
|
195357
|
-
if (err) {
|
|
195358
|
-
prefixedLog("error", String(err));
|
|
195359
|
-
}
|
|
195360
|
-
},
|
|
195361
|
-
warn: (msg) => prefixedLog("warn", msg)
|
|
195362
|
-
} : {
|
|
195368
|
+
return {
|
|
195363
195369
|
log: (msg) => print("log", msg),
|
|
195364
195370
|
error: (msg, err) => {
|
|
195365
195371
|
print("error", msg);
|
|
@@ -195372,7 +195378,7 @@ function createDevLogger(isPrefixed = true) {
|
|
|
195372
195378
|
}
|
|
195373
195379
|
|
|
195374
195380
|
// src/cli/dev/dev-server/function-manager.ts
|
|
195375
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
195381
|
+
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
195376
195382
|
import { dirname as dirname11, join as join15 } from "node:path";
|
|
195377
195383
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
195378
195384
|
var __dirname5 = dirname11(fileURLToPath7(import.meta.url));
|
|
@@ -195382,35 +195388,49 @@ var READY_TIMEOUT = 30000;
|
|
|
195382
195388
|
class FunctionManager {
|
|
195383
195389
|
functions;
|
|
195384
195390
|
running = new Map;
|
|
195391
|
+
starting = new Map;
|
|
195385
195392
|
logger;
|
|
195386
195393
|
constructor(functions, logger) {
|
|
195387
195394
|
this.functions = new Map(functions.map((f7) => [f7.name, f7]));
|
|
195388
195395
|
this.logger = logger;
|
|
195389
195396
|
}
|
|
195390
|
-
|
|
195397
|
+
getFunctionNames() {
|
|
195391
195398
|
return Array.from(this.functions.keys());
|
|
195392
195399
|
}
|
|
195393
195400
|
verifyDenoIsInstalled() {
|
|
195394
195401
|
if (this.functions.size > 0) {
|
|
195395
|
-
|
|
195396
|
-
|
|
195397
|
-
|
|
195398
|
-
|
|
195402
|
+
const result = spawnSync2("deno", ["--version"]);
|
|
195403
|
+
if (result.error) {
|
|
195404
|
+
throw new DependencyNotFoundError("Deno is required to run functions", {
|
|
195405
|
+
hints: [{ message: "Install Deno from https://deno.com/download" }]
|
|
195406
|
+
});
|
|
195399
195407
|
}
|
|
195400
195408
|
}
|
|
195401
195409
|
}
|
|
195402
195410
|
async ensureRunning(name2) {
|
|
195411
|
+
const backendFunction = this.functions.get(name2);
|
|
195412
|
+
if (!backendFunction) {
|
|
195413
|
+
throw new InvalidInputError(`Function "${name2}" not found`, {
|
|
195414
|
+
hints: [{ message: "Check available functions in your project" }]
|
|
195415
|
+
});
|
|
195416
|
+
}
|
|
195403
195417
|
const existing = this.running.get(name2);
|
|
195404
195418
|
if (existing?.ready) {
|
|
195405
195419
|
return existing.port;
|
|
195406
195420
|
}
|
|
195407
|
-
const
|
|
195408
|
-
if (
|
|
195409
|
-
|
|
195421
|
+
const pending = this.starting.get(name2);
|
|
195422
|
+
if (pending) {
|
|
195423
|
+
return pending;
|
|
195410
195424
|
}
|
|
195411
|
-
|
|
195412
|
-
|
|
195425
|
+
const promise2 = this.startFunction(name2, backendFunction);
|
|
195426
|
+
this.starting.set(name2, promise2);
|
|
195427
|
+
try {
|
|
195428
|
+
return await promise2;
|
|
195429
|
+
} finally {
|
|
195430
|
+
this.starting.delete(name2);
|
|
195413
195431
|
}
|
|
195432
|
+
}
|
|
195433
|
+
async startFunction(name2, backendFunction) {
|
|
195414
195434
|
const port = await this.allocatePort();
|
|
195415
195435
|
const process21 = this.spawnFunction(backendFunction, port);
|
|
195416
195436
|
const runningFunc = {
|
|
@@ -195422,16 +195442,13 @@ class FunctionManager {
|
|
|
195422
195442
|
this.setupProcessHandlers(name2, process21);
|
|
195423
195443
|
return this.waitForReady(name2, runningFunc);
|
|
195424
195444
|
}
|
|
195425
|
-
getPort(name2) {
|
|
195426
|
-
const running = this.running.get(name2);
|
|
195427
|
-
return running?.ready ? running.port : undefined;
|
|
195428
|
-
}
|
|
195429
195445
|
stopAll() {
|
|
195430
195446
|
for (const [name2, { process: process21 }] of this.running) {
|
|
195431
195447
|
this.logger.log(`[dev-server] Stopping function: ${name2}`);
|
|
195432
195448
|
process21.kill();
|
|
195433
195449
|
}
|
|
195434
195450
|
this.running.clear();
|
|
195451
|
+
this.starting.clear();
|
|
195435
195452
|
}
|
|
195436
195453
|
stop(name2) {
|
|
195437
195454
|
const running = this.running.get(name2);
|
|
@@ -195484,8 +195501,21 @@ class FunctionManager {
|
|
|
195484
195501
|
}
|
|
195485
195502
|
waitForReady(name2, runningFunc) {
|
|
195486
195503
|
return new Promise((resolve5, reject) => {
|
|
195504
|
+
runningFunc.process.on("exit", (code2) => {
|
|
195505
|
+
if (!runningFunc.ready) {
|
|
195506
|
+
clearTimeout(timeout3);
|
|
195507
|
+
reject(new InternalError(`Function "${name2}" exited with code ${code2}`, {
|
|
195508
|
+
hints: [{ message: "Check the function code for errors" }]
|
|
195509
|
+
}));
|
|
195510
|
+
}
|
|
195511
|
+
});
|
|
195487
195512
|
const timeout3 = setTimeout(() => {
|
|
195488
|
-
|
|
195513
|
+
runningFunc.process.kill();
|
|
195514
|
+
reject(new InternalError(`Function "${name2}" failed to start within ${READY_TIMEOUT / 1000}s timeout`, {
|
|
195515
|
+
hints: [
|
|
195516
|
+
{ message: "Check the function code for startup errors" }
|
|
195517
|
+
]
|
|
195518
|
+
}));
|
|
195489
195519
|
}, READY_TIMEOUT);
|
|
195490
195520
|
const onData = (data) => {
|
|
195491
195521
|
const output = data.toString();
|
|
@@ -195497,86 +195527,54 @@ class FunctionManager {
|
|
|
195497
195527
|
}
|
|
195498
195528
|
};
|
|
195499
195529
|
runningFunc.process.stdout?.on("data", onData);
|
|
195500
|
-
runningFunc.process.on("exit", (code2) => {
|
|
195501
|
-
if (!runningFunc.ready) {
|
|
195502
|
-
clearTimeout(timeout3);
|
|
195503
|
-
reject(new Error(`Function "${name2}" exited with code ${code2}`));
|
|
195504
|
-
}
|
|
195505
|
-
});
|
|
195506
195530
|
});
|
|
195507
195531
|
}
|
|
195508
195532
|
}
|
|
195509
195533
|
|
|
195510
195534
|
// src/cli/dev/dev-server/routes/functions.ts
|
|
195511
195535
|
var import_express = __toESM(require_express(), 1);
|
|
195512
|
-
|
|
195513
|
-
|
|
195536
|
+
var import_http_proxy_middleware = __toESM(require_dist2(), 1);
|
|
195537
|
+
import { ServerResponse } from "node:http";
|
|
195538
|
+
function createFunctionRouter(manager, logger) {
|
|
195514
195539
|
const router = import_express.Router({ mergeParams: true });
|
|
195515
|
-
|
|
195540
|
+
const portsByRequest = new WeakMap;
|
|
195541
|
+
const proxy = import_http_proxy_middleware.createProxyMiddleware({
|
|
195542
|
+
router: (req) => `http://localhost:${portsByRequest.get(req)}`,
|
|
195543
|
+
changeOrigin: true,
|
|
195544
|
+
on: {
|
|
195545
|
+
proxyReq: (proxyReq, req) => {
|
|
195546
|
+
const xAppId = req.headers["x-app-id"];
|
|
195547
|
+
if (xAppId) {
|
|
195548
|
+
proxyReq.setHeader("Base44-App-Id", xAppId);
|
|
195549
|
+
}
|
|
195550
|
+
proxyReq.setHeader("Base44-Api-Url", `${req.protocol}://${req.headers.host}`);
|
|
195551
|
+
},
|
|
195552
|
+
error: (err, _req, res) => {
|
|
195553
|
+
logger.error("Function proxy error:", err);
|
|
195554
|
+
if (res instanceof ServerResponse && !res.headersSent) {
|
|
195555
|
+
res.writeHead(502, { "Content-Type": "application/json" });
|
|
195556
|
+
res.end(JSON.stringify({
|
|
195557
|
+
error: "Failed to proxy request to function",
|
|
195558
|
+
details: err.message
|
|
195559
|
+
}));
|
|
195560
|
+
}
|
|
195561
|
+
}
|
|
195562
|
+
}
|
|
195563
|
+
});
|
|
195564
|
+
router.all("/:functionName", async (req, res, next) => {
|
|
195516
195565
|
const { functionName } = req.params;
|
|
195517
195566
|
try {
|
|
195518
|
-
const func = manager.getFunction(functionName);
|
|
195519
|
-
if (!func) {
|
|
195520
|
-
res.status(404).json({
|
|
195521
|
-
error: `Function "${functionName}" not found`
|
|
195522
|
-
});
|
|
195523
|
-
return;
|
|
195524
|
-
}
|
|
195525
195567
|
const port = await manager.ensureRunning(functionName);
|
|
195526
|
-
|
|
195568
|
+
portsByRequest.set(req, port);
|
|
195569
|
+
next();
|
|
195527
195570
|
} catch (error48) {
|
|
195528
|
-
logger.error(
|
|
195571
|
+
logger.error("Function error:", error48);
|
|
195529
195572
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
195530
195573
|
res.status(500).json({ error: message });
|
|
195531
195574
|
}
|
|
195532
|
-
});
|
|
195575
|
+
}, proxy);
|
|
195533
195576
|
return router;
|
|
195534
195577
|
}
|
|
195535
|
-
function proxyRequest(req, res, port, logger) {
|
|
195536
|
-
return new Promise((resolve5, reject) => {
|
|
195537
|
-
const headers = {
|
|
195538
|
-
...req.headers
|
|
195539
|
-
};
|
|
195540
|
-
delete headers.host;
|
|
195541
|
-
if (headers["x-app-id"]) {
|
|
195542
|
-
headers["Base44-App-Id"] = headers["x-app-id"];
|
|
195543
|
-
}
|
|
195544
|
-
headers["Base44-Api-Url"] = `${req.protocol}://${req.get("host")}`;
|
|
195545
|
-
const options8 = {
|
|
195546
|
-
hostname: "localhost",
|
|
195547
|
-
port,
|
|
195548
|
-
path: req.url,
|
|
195549
|
-
method: req.method,
|
|
195550
|
-
headers
|
|
195551
|
-
};
|
|
195552
|
-
const proxyReq = httpRequest(options8, (proxyRes) => {
|
|
195553
|
-
res.status(proxyRes.statusCode || 200);
|
|
195554
|
-
for (const [key2, value] of Object.entries(proxyRes.headers)) {
|
|
195555
|
-
if (value !== undefined) {
|
|
195556
|
-
res.setHeader(key2, value);
|
|
195557
|
-
}
|
|
195558
|
-
}
|
|
195559
|
-
proxyRes.pipe(res);
|
|
195560
|
-
proxyRes.on("end", () => {
|
|
195561
|
-
resolve5();
|
|
195562
|
-
});
|
|
195563
|
-
proxyRes.on("error", (error48) => {
|
|
195564
|
-
reject(error48);
|
|
195565
|
-
});
|
|
195566
|
-
});
|
|
195567
|
-
proxyReq.on("error", (error48) => {
|
|
195568
|
-
logger.error(`Function proxy error:`, error48);
|
|
195569
|
-
if (!res.headersSent) {
|
|
195570
|
-
res.status(502).json({
|
|
195571
|
-
error: "Failed to proxy request to function",
|
|
195572
|
-
details: error48.message
|
|
195573
|
-
});
|
|
195574
|
-
}
|
|
195575
|
-
resolve5();
|
|
195576
|
-
});
|
|
195577
|
-
req.pipe(proxyReq);
|
|
195578
|
-
});
|
|
195579
|
-
}
|
|
195580
195578
|
|
|
195581
195579
|
// src/cli/dev/dev-server/main.ts
|
|
195582
195580
|
var DEFAULT_PORT = 4400;
|
|
@@ -195587,7 +195585,7 @@ async function createDevServer(options8) {
|
|
|
195587
195585
|
const { project: project2 } = await readProjectConfig();
|
|
195588
195586
|
const configDir = dirname12(project2.configPath);
|
|
195589
195587
|
const app = import_express2.default();
|
|
195590
|
-
const remoteProxy =
|
|
195588
|
+
const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
|
|
195591
195589
|
target: BASE44_APP_URL,
|
|
195592
195590
|
changeOrigin: true
|
|
195593
195591
|
});
|
|
@@ -195603,13 +195601,14 @@ async function createDevServer(options8) {
|
|
|
195603
195601
|
}
|
|
195604
195602
|
next();
|
|
195605
195603
|
});
|
|
195606
|
-
const
|
|
195607
|
-
|
|
195608
|
-
]);
|
|
195609
|
-
const devLogger = createDevLogger(false);
|
|
195604
|
+
const functions = await functionResource.readAll(join16(configDir, project2.functionsDir));
|
|
195605
|
+
const devLogger = createDevLogger();
|
|
195610
195606
|
const functionManager = new FunctionManager(functions, devLogger);
|
|
195611
195607
|
functionManager.verifyDenoIsInstalled();
|
|
195612
|
-
|
|
195608
|
+
if (functionManager.getFunctionNames().length > 0) {
|
|
195609
|
+
M2.info(`Loaded functions: ${functionManager.getFunctionNames().join(", ")}`);
|
|
195610
|
+
}
|
|
195611
|
+
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
195613
195612
|
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
195614
195613
|
app.use((req, res, next) => {
|
|
195615
195614
|
return remoteProxy(req, res, next);
|
|
@@ -195622,12 +195621,13 @@ async function createDevServer(options8) {
|
|
|
195622
195621
|
} else {
|
|
195623
195622
|
reject(err);
|
|
195624
195623
|
}
|
|
195624
|
+
} else {
|
|
195625
195625
|
const shutdown = () => {
|
|
195626
195626
|
functionManager.stopAll();
|
|
195627
|
+
server.close();
|
|
195627
195628
|
};
|
|
195628
195629
|
process.on("SIGINT", shutdown);
|
|
195629
195630
|
process.on("SIGTERM", shutdown);
|
|
195630
|
-
} else {
|
|
195631
195631
|
resolve5({
|
|
195632
195632
|
port,
|
|
195633
195633
|
server
|
|
@@ -195740,7 +195740,7 @@ async function eject(options8) {
|
|
|
195740
195740
|
}
|
|
195741
195741
|
function getEjectCommand(context) {
|
|
195742
195742
|
return new Command("eject").description("Download the code for an existing Base44 project").option("-p, --path <path>", "Path where to write the project").option("--project-id <id>", "Project ID to eject (skips interactive selection)").option("-y, --yes", "Skip confirmation prompts").action(async (options8) => {
|
|
195743
|
-
await runCommand(() => eject(options8), { requireAuth: true, requireAppConfig: false }, context);
|
|
195743
|
+
await runCommand(() => eject({ ...options8, isNonInteractive: context.isNonInteractive }), { requireAuth: true, requireAppConfig: false }, context);
|
|
195744
195744
|
});
|
|
195745
195745
|
}
|
|
195746
195746
|
|
|
@@ -200007,7 +200007,8 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
|
|
|
200007
200007
|
async function runCLI() {
|
|
200008
200008
|
const errorReporter = new ErrorReporter;
|
|
200009
200009
|
errorReporter.registerProcessErrorHandlers();
|
|
200010
|
-
const
|
|
200010
|
+
const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
200011
|
+
const context = { errorReporter, isNonInteractive };
|
|
200011
200012
|
const program2 = createProgram(context);
|
|
200012
200013
|
try {
|
|
200013
200014
|
const userInfo = await readAuth();
|
|
@@ -200032,4 +200033,4 @@ export {
|
|
|
200032
200033
|
CLIExitError
|
|
200033
200034
|
};
|
|
200034
200035
|
|
|
200035
|
-
//# debugId=
|
|
200036
|
+
//# debugId=B4C79353BCDBC07064756E2164756E21
|