@base44-preview/cli 0.0.32-pr.271.5d60e7b → 0.0.33-pr.225.299669a
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 +9 -7
- package/dist/cli/index.js +507 -16
- package/dist/cli/index.js.map +15 -11
- package/dist/deno-runtime/main.js +31 -0
- package/dist/deno-runtime/main.js.map +10 -0
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -136896,12 +136896,12 @@ var require_linker = __commonJS((exports) => {
|
|
|
136896
136896
|
var require_optionValidator = __commonJS((exports) => {
|
|
136897
136897
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
136898
136898
|
exports.validateOptions = undefined;
|
|
136899
|
-
function
|
|
136899
|
+
function validateOptions3({ maxItems }) {
|
|
136900
136900
|
if (maxItems !== undefined && maxItems < -1) {
|
|
136901
136901
|
throw RangeError(`Expected options.maxItems to be >= -1, but was given ${maxItems}.`);
|
|
136902
136902
|
}
|
|
136903
136903
|
}
|
|
136904
|
-
exports.validateOptions =
|
|
136904
|
+
exports.validateOptions = validateOptions3;
|
|
136905
136905
|
});
|
|
136906
136906
|
|
|
136907
136907
|
// node_modules/json-schema-to-typescript/dist/src/index.js
|
|
@@ -178514,6 +178514,18 @@ class InvalidInputError extends UserError {
|
|
|
178514
178514
|
code = "INVALID_INPUT";
|
|
178515
178515
|
}
|
|
178516
178516
|
|
|
178517
|
+
class DependencyNotFoundError extends UserError {
|
|
178518
|
+
code = "DEPENDENCY_NOT_FOUND";
|
|
178519
|
+
constructor(message, options) {
|
|
178520
|
+
super(message, {
|
|
178521
|
+
hints: options?.hints ?? [
|
|
178522
|
+
{ message: "Install the required dependency and try again" }
|
|
178523
|
+
],
|
|
178524
|
+
cause: options?.cause
|
|
178525
|
+
});
|
|
178526
|
+
}
|
|
178527
|
+
}
|
|
178528
|
+
|
|
178517
178529
|
class ApiError extends SystemError {
|
|
178518
178530
|
code = "API_ERROR";
|
|
178519
178531
|
statusCode;
|
|
@@ -178629,6 +178641,39 @@ class FileReadError extends SystemError {
|
|
|
178629
178641
|
});
|
|
178630
178642
|
}
|
|
178631
178643
|
}
|
|
178644
|
+
|
|
178645
|
+
class FunctionNotFoundError extends ApiError {
|
|
178646
|
+
constructor(functionName, cause) {
|
|
178647
|
+
super(`Function "${functionName}" was not found in this app`, {
|
|
178648
|
+
statusCode: 404,
|
|
178649
|
+
cause,
|
|
178650
|
+
hints: [
|
|
178651
|
+
{
|
|
178652
|
+
message: "Make sure the function name is correct and has been deployed",
|
|
178653
|
+
command: "base44 functions deploy"
|
|
178654
|
+
},
|
|
178655
|
+
{
|
|
178656
|
+
message: "List project functions by checking the base44/functions/ directory"
|
|
178657
|
+
}
|
|
178658
|
+
]
|
|
178659
|
+
});
|
|
178660
|
+
}
|
|
178661
|
+
}
|
|
178662
|
+
|
|
178663
|
+
class InternalError extends SystemError {
|
|
178664
|
+
code = "INTERNAL_ERROR";
|
|
178665
|
+
constructor(message, options) {
|
|
178666
|
+
super(message, {
|
|
178667
|
+
hints: options?.hints ?? [
|
|
178668
|
+
{
|
|
178669
|
+
message: "This is an unexpected error. Please report it if it persists."
|
|
178670
|
+
}
|
|
178671
|
+
],
|
|
178672
|
+
cause: options?.cause
|
|
178673
|
+
});
|
|
178674
|
+
}
|
|
178675
|
+
}
|
|
178676
|
+
|
|
178632
178677
|
class TypeGenerationError extends SystemError {
|
|
178633
178678
|
code = "TYPE_GENERATION_ERROR";
|
|
178634
178679
|
constructor(message, entityName, cause) {
|
|
@@ -185985,6 +186030,13 @@ var DeployFunctionsResponseSchema = exports_external.object({
|
|
|
185985
186030
|
skipped: exports_external.array(exports_external.string()).optional().nullable(),
|
|
185986
186031
|
errors: exports_external.array(exports_external.object({ name: exports_external.string(), message: exports_external.string() })).nullable()
|
|
185987
186032
|
});
|
|
186033
|
+
var LogLevelSchema = exports_external.enum(["log", "info", "warn", "error", "debug"]);
|
|
186034
|
+
var FunctionLogEntrySchema = exports_external.object({
|
|
186035
|
+
time: exports_external.string(),
|
|
186036
|
+
level: LogLevelSchema,
|
|
186037
|
+
message: exports_external.string()
|
|
186038
|
+
});
|
|
186039
|
+
var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
|
|
185988
186040
|
|
|
185989
186041
|
// src/core/resources/function/api.ts
|
|
185990
186042
|
function toDeployPayloadItem(fn) {
|
|
@@ -186015,6 +186067,55 @@ async function deployFunctions(functions) {
|
|
|
186015
186067
|
}
|
|
186016
186068
|
return result.data;
|
|
186017
186069
|
}
|
|
186070
|
+
function buildLogsQueryString(filters) {
|
|
186071
|
+
const params = new URLSearchParams;
|
|
186072
|
+
if (filters.since) {
|
|
186073
|
+
params.set("since", filters.since);
|
|
186074
|
+
}
|
|
186075
|
+
if (filters.until) {
|
|
186076
|
+
params.set("until", filters.until);
|
|
186077
|
+
}
|
|
186078
|
+
if (filters.level) {
|
|
186079
|
+
params.set("level", filters.level);
|
|
186080
|
+
}
|
|
186081
|
+
if (filters.limit !== undefined) {
|
|
186082
|
+
params.set("limit", String(filters.limit));
|
|
186083
|
+
}
|
|
186084
|
+
if (filters.order) {
|
|
186085
|
+
params.set("order", filters.order);
|
|
186086
|
+
}
|
|
186087
|
+
const queryString = params.toString();
|
|
186088
|
+
return queryString ? `?${queryString}` : "";
|
|
186089
|
+
}
|
|
186090
|
+
async function fetchFunctionLogs(functionName, filters = {}) {
|
|
186091
|
+
const appClient = getAppClient();
|
|
186092
|
+
const queryString = buildLogsQueryString(filters);
|
|
186093
|
+
let response;
|
|
186094
|
+
try {
|
|
186095
|
+
response = await appClient.get(`functions-mgmt/${functionName}/logs${queryString}`);
|
|
186096
|
+
} catch (error48) {
|
|
186097
|
+
if (error48 instanceof HTTPError) {
|
|
186098
|
+
if (error48.response.status === 404) {
|
|
186099
|
+
throw new FunctionNotFoundError(functionName, error48);
|
|
186100
|
+
}
|
|
186101
|
+
try {
|
|
186102
|
+
const body = await error48.response.clone().json();
|
|
186103
|
+
if (body.error_type === "KeyError") {
|
|
186104
|
+
throw new FunctionNotFoundError(functionName, error48);
|
|
186105
|
+
}
|
|
186106
|
+
} catch (parseError) {
|
|
186107
|
+
if (parseError instanceof ApiError)
|
|
186108
|
+
throw parseError;
|
|
186109
|
+
}
|
|
186110
|
+
}
|
|
186111
|
+
throw await ApiError.fromHttpError(error48, `fetching function logs: '${functionName}'`);
|
|
186112
|
+
}
|
|
186113
|
+
const result = FunctionLogsResponseSchema.safeParse(await response.json());
|
|
186114
|
+
if (!result.success) {
|
|
186115
|
+
throw new SchemaValidationError("Invalid function logs response from server", result.error);
|
|
186116
|
+
}
|
|
186117
|
+
return result.data;
|
|
186118
|
+
}
|
|
186018
186119
|
// src/core/resources/function/config.ts
|
|
186019
186120
|
import { dirname as dirname4, join as join5 } from "node:path";
|
|
186020
186121
|
async function readFunctionConfig(configPath) {
|
|
@@ -187064,7 +187165,9 @@ var theme = {
|
|
|
187064
187165
|
styles: {
|
|
187065
187166
|
header: source_default.dim,
|
|
187066
187167
|
bold: source_default.bold,
|
|
187067
|
-
dim: source_default.dim
|
|
187168
|
+
dim: source_default.dim,
|
|
187169
|
+
error: source_default.red,
|
|
187170
|
+
warn: source_default.yellow
|
|
187068
187171
|
},
|
|
187069
187172
|
format: {
|
|
187070
187173
|
errorContext(ctx) {
|
|
@@ -193846,7 +193949,7 @@ var {
|
|
|
193846
193949
|
// package.json
|
|
193847
193950
|
var package_default = {
|
|
193848
193951
|
name: "base44",
|
|
193849
|
-
version: "0.0.
|
|
193952
|
+
version: "0.0.33",
|
|
193850
193953
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
193851
193954
|
type: "module",
|
|
193852
193955
|
bin: {
|
|
@@ -193887,6 +193990,7 @@ var package_default = {
|
|
|
193887
193990
|
"@types/bun": "^1.2.15",
|
|
193888
193991
|
"@types/common-tags": "^1.8.4",
|
|
193889
193992
|
"@types/cors": "^2.8.19",
|
|
193993
|
+
"@types/deno": "^2.5.0",
|
|
193890
193994
|
"@types/ejs": "^3.1.5",
|
|
193891
193995
|
"@types/express": "^5.0.6",
|
|
193892
193996
|
"@types/json-schema": "^7.0.15",
|
|
@@ -193973,7 +194077,6 @@ async function printUpgradeNotificationIfAvailable() {
|
|
|
193973
194077
|
|
|
193974
194078
|
// src/cli/utils/runCommand.ts
|
|
193975
194079
|
async function runCommand(commandFn, options, context) {
|
|
193976
|
-
console.log();
|
|
193977
194080
|
if (options?.fullBanner) {
|
|
193978
194081
|
await printBanner(context.isNonInteractive);
|
|
193979
194082
|
We("");
|
|
@@ -193999,8 +194102,11 @@ async function runCommand(commandFn, options, context) {
|
|
|
193999
194102
|
const appConfig = await initAppConfig();
|
|
194000
194103
|
context.errorReporter.setContext({ appId: appConfig.id });
|
|
194001
194104
|
}
|
|
194002
|
-
const
|
|
194003
|
-
Le(outroMessage || "");
|
|
194105
|
+
const result = await commandFn();
|
|
194106
|
+
Le(result.outroMessage || "");
|
|
194107
|
+
if (result.stdout) {
|
|
194108
|
+
process.stdout.write(result.stdout);
|
|
194109
|
+
}
|
|
194004
194110
|
} catch (error48) {
|
|
194005
194111
|
const errorMessage = error48 instanceof Error ? error48.message : String(error48);
|
|
194006
194112
|
R2.error(errorMessage);
|
|
@@ -195027,6 +195133,147 @@ function getFunctionsDeployCommand(context) {
|
|
|
195027
195133
|
}));
|
|
195028
195134
|
}
|
|
195029
195135
|
|
|
195136
|
+
// src/cli/commands/logs/index.ts
|
|
195137
|
+
var VALID_LEVELS = ["log", "info", "warn", "error", "debug"];
|
|
195138
|
+
function parseFunctionFilters(options) {
|
|
195139
|
+
const filters = {};
|
|
195140
|
+
if (options.since) {
|
|
195141
|
+
filters.since = options.since;
|
|
195142
|
+
}
|
|
195143
|
+
if (options.until) {
|
|
195144
|
+
filters.until = options.until;
|
|
195145
|
+
}
|
|
195146
|
+
if (options.level) {
|
|
195147
|
+
filters.level = options.level;
|
|
195148
|
+
}
|
|
195149
|
+
if (options.limit) {
|
|
195150
|
+
filters.limit = Number.parseInt(options.limit, 10);
|
|
195151
|
+
}
|
|
195152
|
+
if (options.order) {
|
|
195153
|
+
filters.order = options.order.toLowerCase();
|
|
195154
|
+
}
|
|
195155
|
+
return filters;
|
|
195156
|
+
}
|
|
195157
|
+
function parseFunctionNames(option) {
|
|
195158
|
+
if (!option)
|
|
195159
|
+
return [];
|
|
195160
|
+
return option.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
195161
|
+
}
|
|
195162
|
+
function normalizeDatetime(value) {
|
|
195163
|
+
if (/Z$|[+-]\d{2}:\d{2}$/.test(value))
|
|
195164
|
+
return value;
|
|
195165
|
+
return `${value}Z`;
|
|
195166
|
+
}
|
|
195167
|
+
function validateOptions2(options) {
|
|
195168
|
+
if (options.level && !VALID_LEVELS.includes(options.level)) {
|
|
195169
|
+
throw new InvalidInputError(`Invalid level: "${options.level}". Must be one of: ${VALID_LEVELS.join(", ")}.`);
|
|
195170
|
+
}
|
|
195171
|
+
if (options.limit) {
|
|
195172
|
+
const limit = Number.parseInt(options.limit, 10);
|
|
195173
|
+
if (Number.isNaN(limit) || limit < 1 || limit > 1000) {
|
|
195174
|
+
throw new InvalidInputError(`Invalid limit: "${options.limit}". Must be a number between 1 and 1000.`);
|
|
195175
|
+
}
|
|
195176
|
+
}
|
|
195177
|
+
if (options.order) {
|
|
195178
|
+
const order = options.order.toUpperCase();
|
|
195179
|
+
if (order !== "ASC" && order !== "DESC") {
|
|
195180
|
+
throw new InvalidInputError(`Invalid order: "${options.order}". Must be "ASC" or "DESC".`);
|
|
195181
|
+
}
|
|
195182
|
+
}
|
|
195183
|
+
}
|
|
195184
|
+
function formatEntry(entry) {
|
|
195185
|
+
const time3 = entry.time.substring(0, 19).replace("T", " ");
|
|
195186
|
+
const level = entry.level.toUpperCase().padEnd(5);
|
|
195187
|
+
const message = entry.message.trim();
|
|
195188
|
+
return `${time3} ${level} ${message}
|
|
195189
|
+
`;
|
|
195190
|
+
}
|
|
195191
|
+
function formatLogs(entries) {
|
|
195192
|
+
if (entries.length === 0) {
|
|
195193
|
+
return `No logs found matching the filters.
|
|
195194
|
+
`;
|
|
195195
|
+
}
|
|
195196
|
+
let output = `Showing ${entries.length} function log entries
|
|
195197
|
+
|
|
195198
|
+
`;
|
|
195199
|
+
for (const entry of entries) {
|
|
195200
|
+
output += formatEntry(entry);
|
|
195201
|
+
}
|
|
195202
|
+
return output;
|
|
195203
|
+
}
|
|
195204
|
+
function normalizeLogEntry(entry, functionName) {
|
|
195205
|
+
return {
|
|
195206
|
+
time: entry.time,
|
|
195207
|
+
level: entry.level,
|
|
195208
|
+
message: `[${functionName}] ${entry.message}`,
|
|
195209
|
+
source: functionName
|
|
195210
|
+
};
|
|
195211
|
+
}
|
|
195212
|
+
async function fetchLogsForFunctions(functionNames, options, availableFunctionNames) {
|
|
195213
|
+
const filters = parseFunctionFilters(options);
|
|
195214
|
+
const allEntries = [];
|
|
195215
|
+
for (const functionName of functionNames) {
|
|
195216
|
+
let logs;
|
|
195217
|
+
try {
|
|
195218
|
+
logs = await fetchFunctionLogs(functionName, filters);
|
|
195219
|
+
} catch (error48) {
|
|
195220
|
+
if (error48 instanceof FunctionNotFoundError && availableFunctionNames.length > 0) {
|
|
195221
|
+
const available = availableFunctionNames.join(", ");
|
|
195222
|
+
throw new InvalidInputError(`Function "${functionName}" was not found in this app`, {
|
|
195223
|
+
hints: [
|
|
195224
|
+
{
|
|
195225
|
+
message: `Available functions in this project: ${available}`
|
|
195226
|
+
},
|
|
195227
|
+
{
|
|
195228
|
+
message: "Make sure the function has been deployed before fetching logs",
|
|
195229
|
+
command: "base44 functions deploy"
|
|
195230
|
+
}
|
|
195231
|
+
]
|
|
195232
|
+
});
|
|
195233
|
+
}
|
|
195234
|
+
throw error48;
|
|
195235
|
+
}
|
|
195236
|
+
const entries = logs.map((entry) => normalizeLogEntry(entry, functionName));
|
|
195237
|
+
allEntries.push(...entries);
|
|
195238
|
+
}
|
|
195239
|
+
if (functionNames.length > 1) {
|
|
195240
|
+
const order = options.order?.toUpperCase() === "ASC" ? 1 : -1;
|
|
195241
|
+
allEntries.sort((a2, b) => order * a2.time.localeCompare(b.time));
|
|
195242
|
+
}
|
|
195243
|
+
return allEntries;
|
|
195244
|
+
}
|
|
195245
|
+
async function getAllFunctionNames() {
|
|
195246
|
+
const { functions } = await readProjectConfig();
|
|
195247
|
+
return functions.map((fn) => fn.name);
|
|
195248
|
+
}
|
|
195249
|
+
async function logsAction(options) {
|
|
195250
|
+
if (options.since)
|
|
195251
|
+
options.since = normalizeDatetime(options.since);
|
|
195252
|
+
if (options.until)
|
|
195253
|
+
options.until = normalizeDatetime(options.until);
|
|
195254
|
+
validateOptions2(options);
|
|
195255
|
+
const specifiedFunctions = parseFunctionNames(options.function);
|
|
195256
|
+
const allProjectFunctions = await getAllFunctionNames();
|
|
195257
|
+
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
|
|
195258
|
+
if (functionNames.length === 0) {
|
|
195259
|
+
return { stdout: `No functions found in this project.
|
|
195260
|
+
` };
|
|
195261
|
+
}
|
|
195262
|
+
let entries = await fetchLogsForFunctions(functionNames, options, allProjectFunctions);
|
|
195263
|
+
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
195264
|
+
if (limit !== undefined && entries.length > limit) {
|
|
195265
|
+
entries = entries.slice(0, limit);
|
|
195266
|
+
}
|
|
195267
|
+
const stdout = options.json ? `${JSON.stringify(entries, null, 2)}
|
|
195268
|
+
` : formatLogs(entries);
|
|
195269
|
+
return { stdout };
|
|
195270
|
+
}
|
|
195271
|
+
function getLogsCommand(context) {
|
|
195272
|
+
return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)").option("--until <datetime>", "Show logs until this time (ISO format)").option("--level <level>", "Filter by log level: log, info, warn, error, debug").option("-n, --limit <n>", "Results per page (1-1000, default: 50)").option("--order <order>", "Sort order: ASC|DESC (default: DESC)").option("--json", "Output raw JSON").action(async (options) => {
|
|
195273
|
+
await runCommand(() => logsAction(options), { requireAuth: true }, context);
|
|
195274
|
+
});
|
|
195275
|
+
}
|
|
195276
|
+
|
|
195030
195277
|
// src/cli/commands/project/create.ts
|
|
195031
195278
|
import { basename as basename3, join as join11, resolve as resolve2 } from "node:path";
|
|
195032
195279
|
var import_lodash = __toESM(require_lodash(), 1);
|
|
@@ -195610,9 +195857,12 @@ function getTypesCommand(context) {
|
|
|
195610
195857
|
return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand(context));
|
|
195611
195858
|
}
|
|
195612
195859
|
|
|
195860
|
+
// src/cli/commands/dev.ts
|
|
195861
|
+
import { dirname as dirname12, join as join16 } from "node:path";
|
|
195862
|
+
|
|
195613
195863
|
// src/cli/dev/dev-server/main.ts
|
|
195614
195864
|
var import_cors = __toESM(require_lib4(), 1);
|
|
195615
|
-
var
|
|
195865
|
+
var import_express2 = __toESM(require_express(), 1);
|
|
195616
195866
|
|
|
195617
195867
|
// node_modules/get-port/index.js
|
|
195618
195868
|
import net from "node:net";
|
|
@@ -195729,13 +195979,232 @@ async function getPorts(options8) {
|
|
|
195729
195979
|
}
|
|
195730
195980
|
|
|
195731
195981
|
// src/cli/dev/dev-server/main.ts
|
|
195982
|
+
var import_http_proxy_middleware2 = __toESM(require_dist2(), 1);
|
|
195983
|
+
|
|
195984
|
+
// src/cli/dev/createDevLogger.ts
|
|
195985
|
+
var colorByType = {
|
|
195986
|
+
error: theme.styles.error,
|
|
195987
|
+
warn: theme.styles.warn,
|
|
195988
|
+
log: (text) => text
|
|
195989
|
+
};
|
|
195990
|
+
function createDevLogger() {
|
|
195991
|
+
const print = (type, msg) => {
|
|
195992
|
+
const colorize = colorByType[type];
|
|
195993
|
+
console[type](colorize(msg));
|
|
195994
|
+
};
|
|
195995
|
+
return {
|
|
195996
|
+
log: (msg) => print("log", msg),
|
|
195997
|
+
error: (msg, err) => {
|
|
195998
|
+
print("error", msg);
|
|
195999
|
+
if (err) {
|
|
196000
|
+
print("error", String(err));
|
|
196001
|
+
}
|
|
196002
|
+
},
|
|
196003
|
+
warn: (msg) => print("warn", msg)
|
|
196004
|
+
};
|
|
196005
|
+
}
|
|
196006
|
+
|
|
196007
|
+
// src/cli/dev/dev-server/function-manager.ts
|
|
196008
|
+
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
196009
|
+
import { dirname as dirname11, join as join15 } from "node:path";
|
|
196010
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
196011
|
+
var __dirname5 = dirname11(fileURLToPath7(import.meta.url));
|
|
196012
|
+
var WRAPPER_PATH = join15(__dirname5, "../deno-runtime/main.js");
|
|
196013
|
+
var READY_TIMEOUT = 30000;
|
|
196014
|
+
|
|
196015
|
+
class FunctionManager {
|
|
196016
|
+
functions;
|
|
196017
|
+
running = new Map;
|
|
196018
|
+
starting = new Map;
|
|
196019
|
+
logger;
|
|
196020
|
+
constructor(functions, logger) {
|
|
196021
|
+
this.functions = new Map(functions.map((f7) => [f7.name, f7]));
|
|
196022
|
+
this.logger = logger;
|
|
196023
|
+
if (functions.length > 0) {
|
|
196024
|
+
this.verifyDenoIsInstalled();
|
|
196025
|
+
}
|
|
196026
|
+
}
|
|
196027
|
+
verifyDenoIsInstalled() {
|
|
196028
|
+
const result = spawnSync2("deno", ["--version"]);
|
|
196029
|
+
if (result.error) {
|
|
196030
|
+
throw new DependencyNotFoundError("Deno is required to run functions", {
|
|
196031
|
+
hints: [{ message: "Install Deno from https://deno.com/download" }]
|
|
196032
|
+
});
|
|
196033
|
+
}
|
|
196034
|
+
}
|
|
196035
|
+
getFunctionNames() {
|
|
196036
|
+
return Array.from(this.functions.keys());
|
|
196037
|
+
}
|
|
196038
|
+
async ensureRunning(name2) {
|
|
196039
|
+
const backendFunction = this.functions.get(name2);
|
|
196040
|
+
if (!backendFunction) {
|
|
196041
|
+
throw new InvalidInputError(`Function "${name2}" not found`, {
|
|
196042
|
+
hints: [{ message: "Check available functions in your project" }]
|
|
196043
|
+
});
|
|
196044
|
+
}
|
|
196045
|
+
const existing = this.running.get(name2);
|
|
196046
|
+
if (existing?.ready) {
|
|
196047
|
+
return existing.port;
|
|
196048
|
+
}
|
|
196049
|
+
const pending = this.starting.get(name2);
|
|
196050
|
+
if (pending) {
|
|
196051
|
+
return pending;
|
|
196052
|
+
}
|
|
196053
|
+
const promise2 = this.startFunction(name2, backendFunction);
|
|
196054
|
+
this.starting.set(name2, promise2);
|
|
196055
|
+
try {
|
|
196056
|
+
return await promise2;
|
|
196057
|
+
} finally {
|
|
196058
|
+
this.starting.delete(name2);
|
|
196059
|
+
}
|
|
196060
|
+
}
|
|
196061
|
+
async startFunction(name2, backendFunction) {
|
|
196062
|
+
const port = await this.allocatePort();
|
|
196063
|
+
const process21 = this.spawnFunction(backendFunction, port);
|
|
196064
|
+
const runningFunc = {
|
|
196065
|
+
process: process21,
|
|
196066
|
+
port,
|
|
196067
|
+
ready: false
|
|
196068
|
+
};
|
|
196069
|
+
this.running.set(name2, runningFunc);
|
|
196070
|
+
this.setupProcessHandlers(name2, process21);
|
|
196071
|
+
return this.waitForReady(name2, runningFunc);
|
|
196072
|
+
}
|
|
196073
|
+
stopAll() {
|
|
196074
|
+
for (const [name2, { process: process21 }] of this.running) {
|
|
196075
|
+
this.logger.log(`[dev-server] Stopping function: ${name2}`);
|
|
196076
|
+
process21.kill();
|
|
196077
|
+
}
|
|
196078
|
+
this.running.clear();
|
|
196079
|
+
this.starting.clear();
|
|
196080
|
+
}
|
|
196081
|
+
async allocatePort() {
|
|
196082
|
+
const usedPorts = Array.from(this.running.values()).map((r5) => r5.port);
|
|
196083
|
+
return getPorts({ exclude: usedPorts });
|
|
196084
|
+
}
|
|
196085
|
+
spawnFunction(func, port) {
|
|
196086
|
+
this.logger.log(`[dev-server] Spawning function "${func.name}" on port ${port}`);
|
|
196087
|
+
const process21 = spawn2("deno", ["run", "--allow-all", WRAPPER_PATH], {
|
|
196088
|
+
env: {
|
|
196089
|
+
...globalThis.process.env,
|
|
196090
|
+
FUNCTION_PATH: func.entryPath,
|
|
196091
|
+
FUNCTION_PORT: String(port),
|
|
196092
|
+
FUNCTION_NAME: func.name
|
|
196093
|
+
},
|
|
196094
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
196095
|
+
});
|
|
196096
|
+
return process21;
|
|
196097
|
+
}
|
|
196098
|
+
setupProcessHandlers(name2, process21) {
|
|
196099
|
+
process21.stdout?.on("data", (data) => {
|
|
196100
|
+
const lines = data.toString().trim().split(`
|
|
196101
|
+
`);
|
|
196102
|
+
for (const line3 of lines) {
|
|
196103
|
+
this.logger.log(line3);
|
|
196104
|
+
}
|
|
196105
|
+
});
|
|
196106
|
+
process21.stderr?.on("data", (data) => {
|
|
196107
|
+
const lines = data.toString().trim().split(`
|
|
196108
|
+
`);
|
|
196109
|
+
for (const line3 of lines) {
|
|
196110
|
+
this.logger.error(line3);
|
|
196111
|
+
}
|
|
196112
|
+
});
|
|
196113
|
+
process21.on("exit", (code2) => {
|
|
196114
|
+
this.logger.log(`[dev-server] Function "${name2}" exited with code ${code2}`);
|
|
196115
|
+
this.running.delete(name2);
|
|
196116
|
+
});
|
|
196117
|
+
process21.on("error", (error48) => {
|
|
196118
|
+
this.logger.error(`[dev-server] Function "${name2}" error:`, error48);
|
|
196119
|
+
this.running.delete(name2);
|
|
196120
|
+
});
|
|
196121
|
+
}
|
|
196122
|
+
waitForReady(name2, runningFunc) {
|
|
196123
|
+
return new Promise((resolve5, reject) => {
|
|
196124
|
+
runningFunc.process.on("exit", (code2) => {
|
|
196125
|
+
if (!runningFunc.ready) {
|
|
196126
|
+
clearTimeout(timeout3);
|
|
196127
|
+
reject(new InternalError(`Function "${name2}" exited with code ${code2}`, {
|
|
196128
|
+
hints: [{ message: "Check the function code for errors" }]
|
|
196129
|
+
}));
|
|
196130
|
+
}
|
|
196131
|
+
});
|
|
196132
|
+
const timeout3 = setTimeout(() => {
|
|
196133
|
+
runningFunc.process.kill();
|
|
196134
|
+
reject(new InternalError(`Function "${name2}" failed to start within ${READY_TIMEOUT / 1000}s timeout`, {
|
|
196135
|
+
hints: [
|
|
196136
|
+
{ message: "Check the function code for startup errors" }
|
|
196137
|
+
]
|
|
196138
|
+
}));
|
|
196139
|
+
}, READY_TIMEOUT);
|
|
196140
|
+
const onData = (data) => {
|
|
196141
|
+
const output = data.toString();
|
|
196142
|
+
if (output.includes("Listening on")) {
|
|
196143
|
+
runningFunc.ready = true;
|
|
196144
|
+
clearTimeout(timeout3);
|
|
196145
|
+
runningFunc.process.stdout?.off("data", onData);
|
|
196146
|
+
resolve5(runningFunc.port);
|
|
196147
|
+
}
|
|
196148
|
+
};
|
|
196149
|
+
runningFunc.process.stdout?.on("data", onData);
|
|
196150
|
+
});
|
|
196151
|
+
}
|
|
196152
|
+
}
|
|
196153
|
+
|
|
196154
|
+
// src/cli/dev/dev-server/routes/functions.ts
|
|
196155
|
+
var import_express = __toESM(require_express(), 1);
|
|
195732
196156
|
var import_http_proxy_middleware = __toESM(require_dist2(), 1);
|
|
196157
|
+
import { ServerResponse } from "node:http";
|
|
196158
|
+
function createFunctionRouter(manager, logger) {
|
|
196159
|
+
const router = import_express.Router({ mergeParams: true });
|
|
196160
|
+
const portsByRequest = new WeakMap;
|
|
196161
|
+
const proxy = import_http_proxy_middleware.createProxyMiddleware({
|
|
196162
|
+
router: (req) => `http://localhost:${portsByRequest.get(req)}`,
|
|
196163
|
+
changeOrigin: true,
|
|
196164
|
+
on: {
|
|
196165
|
+
proxyReq: (proxyReq, req) => {
|
|
196166
|
+
const xAppId = req.headers["x-app-id"];
|
|
196167
|
+
if (xAppId) {
|
|
196168
|
+
proxyReq.setHeader("Base44-App-Id", xAppId);
|
|
196169
|
+
}
|
|
196170
|
+
proxyReq.setHeader("Base44-Api-Url", `${req.protocol}://${req.headers.host}`);
|
|
196171
|
+
},
|
|
196172
|
+
error: (err, _req, res) => {
|
|
196173
|
+
logger.error("Function proxy error:", err);
|
|
196174
|
+
if (res instanceof ServerResponse && !res.headersSent) {
|
|
196175
|
+
res.writeHead(502, { "Content-Type": "application/json" });
|
|
196176
|
+
res.end(JSON.stringify({
|
|
196177
|
+
error: "Failed to proxy request to function",
|
|
196178
|
+
details: err.message
|
|
196179
|
+
}));
|
|
196180
|
+
}
|
|
196181
|
+
}
|
|
196182
|
+
}
|
|
196183
|
+
});
|
|
196184
|
+
router.all("/:functionName", async (req, res, next) => {
|
|
196185
|
+
const { functionName } = req.params;
|
|
196186
|
+
try {
|
|
196187
|
+
const port = await manager.ensureRunning(functionName);
|
|
196188
|
+
portsByRequest.set(req, port);
|
|
196189
|
+
next();
|
|
196190
|
+
} catch (error48) {
|
|
196191
|
+
logger.error("Function error:", error48);
|
|
196192
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
196193
|
+
res.status(500).json({ error: message });
|
|
196194
|
+
}
|
|
196195
|
+
}, proxy);
|
|
196196
|
+
return router;
|
|
196197
|
+
}
|
|
196198
|
+
|
|
196199
|
+
// src/cli/dev/dev-server/main.ts
|
|
195733
196200
|
var DEFAULT_PORT = 4400;
|
|
195734
196201
|
var BASE44_APP_URL = "https://base44.app";
|
|
195735
|
-
async function createDevServer(options8
|
|
195736
|
-
const
|
|
195737
|
-
const
|
|
195738
|
-
const
|
|
196202
|
+
async function createDevServer(options8) {
|
|
196203
|
+
const { port: userPort } = options8;
|
|
196204
|
+
const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
|
|
196205
|
+
const { functions } = await options8.loadResources();
|
|
196206
|
+
const app = import_express2.default();
|
|
196207
|
+
const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
|
|
195739
196208
|
target: BASE44_APP_URL,
|
|
195740
196209
|
changeOrigin: true
|
|
195741
196210
|
});
|
|
@@ -195751,6 +196220,13 @@ async function createDevServer(options8 = {}) {
|
|
|
195751
196220
|
}
|
|
195752
196221
|
next();
|
|
195753
196222
|
});
|
|
196223
|
+
const devLogger = createDevLogger();
|
|
196224
|
+
const functionManager = new FunctionManager(functions, devLogger);
|
|
196225
|
+
if (functionManager.getFunctionNames().length > 0) {
|
|
196226
|
+
R2.info(`Loaded functions: ${functionManager.getFunctionNames().join(", ")}`);
|
|
196227
|
+
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
196228
|
+
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
196229
|
+
}
|
|
195754
196230
|
app.use((req, res, next) => {
|
|
195755
196231
|
return remoteProxy(req, res, next);
|
|
195756
196232
|
});
|
|
@@ -195763,6 +196239,12 @@ async function createDevServer(options8 = {}) {
|
|
|
195763
196239
|
reject(err);
|
|
195764
196240
|
}
|
|
195765
196241
|
} else {
|
|
196242
|
+
const shutdown = () => {
|
|
196243
|
+
functionManager.stopAll();
|
|
196244
|
+
server.close();
|
|
196245
|
+
};
|
|
196246
|
+
process.on("SIGINT", shutdown);
|
|
196247
|
+
process.on("SIGTERM", shutdown);
|
|
195766
196248
|
resolve5({
|
|
195767
196249
|
port,
|
|
195768
196250
|
server
|
|
@@ -195775,7 +196257,15 @@ async function createDevServer(options8 = {}) {
|
|
|
195775
196257
|
// src/cli/commands/dev.ts
|
|
195776
196258
|
async function devAction(options8) {
|
|
195777
196259
|
const port = options8.port ? Number(options8.port) : undefined;
|
|
195778
|
-
const { port: resolvedPort } = await createDevServer({
|
|
196260
|
+
const { port: resolvedPort } = await createDevServer({
|
|
196261
|
+
port,
|
|
196262
|
+
loadResources: async () => {
|
|
196263
|
+
const { project: project2 } = await readProjectConfig();
|
|
196264
|
+
const configDir = dirname12(project2.configPath);
|
|
196265
|
+
const functions = await functionResource.readAll(join16(configDir, project2.functionsDir));
|
|
196266
|
+
return { functions };
|
|
196267
|
+
}
|
|
196268
|
+
});
|
|
195779
196269
|
return {
|
|
195780
196270
|
outroMessage: `Dev server is available at ${theme.colors.links(`http://localhost:${resolvedPort}`)}`
|
|
195781
196271
|
};
|
|
@@ -195899,6 +196389,7 @@ function createProgram(context) {
|
|
|
195899
196389
|
program2.addCommand(getSiteCommand(context));
|
|
195900
196390
|
program2.addCommand(getTypesCommand(context));
|
|
195901
196391
|
program2.addCommand(getDevCommand(context), { hidden: true });
|
|
196392
|
+
program2.addCommand(getLogsCommand(context));
|
|
195902
196393
|
return program2;
|
|
195903
196394
|
}
|
|
195904
196395
|
|
|
@@ -195937,7 +196428,7 @@ function nanoid3(size = 21) {
|
|
|
195937
196428
|
}
|
|
195938
196429
|
|
|
195939
196430
|
// node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
195940
|
-
import { dirname as
|
|
196431
|
+
import { dirname as dirname13, posix, sep } from "path";
|
|
195941
196432
|
function createModulerModifier() {
|
|
195942
196433
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
195943
196434
|
return async (frames) => {
|
|
@@ -195946,7 +196437,7 @@ function createModulerModifier() {
|
|
|
195946
196437
|
return frames;
|
|
195947
196438
|
};
|
|
195948
196439
|
}
|
|
195949
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
196440
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname13(process.argv[1]) : process.cwd(), isWindows4 = sep === "\\") {
|
|
195950
196441
|
const normalizedBase = isWindows4 ? normalizeWindowsPath2(basePath) : basePath;
|
|
195951
196442
|
return (filename) => {
|
|
195952
196443
|
if (!filename)
|
|
@@ -200163,4 +200654,4 @@ export {
|
|
|
200163
200654
|
CLIExitError
|
|
200164
200655
|
};
|
|
200165
200656
|
|
|
200166
|
-
//# debugId=
|
|
200657
|
+
//# debugId=00151F47FED4FE2F64756E2164756E21
|