base44 0.0.33 → 0.0.35
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 +8 -7
- package/dist/cli/index.js +249 -44
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,21 +44,22 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
|
|
|
44
44
|
| Command | Description |
|
|
45
45
|
| ------- | ----------- |
|
|
46
46
|
| [`create`](https://docs.base44.com/developers/references/cli/commands/create) | Create a new Base44 project from a template |
|
|
47
|
-
| [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy resources and site to Base44 |
|
|
48
|
-
| [`
|
|
47
|
+
| [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy all project resources and site to Base44 |
|
|
48
|
+
| [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Download the code for an existing Base44 project |
|
|
49
|
+
| [`link`](https://docs.base44.com/developers/references/cli/commands/link) | Link a local project to a 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
52
|
| [`logout`](https://docs.base44.com/developers/references/cli/commands/logout) | Sign out and clear stored credentials |
|
|
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 |
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<!--| [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Create a Base44 backend project from an existing Base44 app | -->
|
|
62
|
+
| [`types generate`](https://docs.base44.com/developers/references/cli/commands/types-generate) | Generate TypeScript types from project resources |
|
|
62
63
|
|
|
63
64
|
## AI agent skills
|
|
64
65
|
|
|
@@ -91,4 +92,4 @@ Found a bug? [Open an issue](https://github.com/base44/cli/issues).
|
|
|
91
92
|
|
|
92
93
|
## License
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
MIT
|
package/dist/cli/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="
|
|
1
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="019c8b01-a41e-78d0-855b-1f264ec2d7de")}catch(e){}}();import { createRequire } from "node:module";
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __getProtoOf = Object.getPrototypeOf;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -178557,9 +178557,10 @@ class ApiError extends SystemError {
|
|
|
178557
178557
|
} catch {
|
|
178558
178558
|
message = error48.message;
|
|
178559
178559
|
}
|
|
178560
|
+
const statusCode = ApiError.normalizeStatusCode(error48.response.status, responseBody);
|
|
178560
178561
|
const requestBody = error48.options.context?.__requestBody;
|
|
178561
178562
|
return new ApiError(`Error ${context}: ${message}`, {
|
|
178562
|
-
statusCode
|
|
178563
|
+
statusCode,
|
|
178563
178564
|
requestUrl: error48.request.url,
|
|
178564
178565
|
requestMethod: error48.request.method,
|
|
178565
178566
|
requestBody,
|
|
@@ -178616,6 +178617,12 @@ class ApiError extends SystemError {
|
|
|
178616
178617
|
return;
|
|
178617
178618
|
return REASON_HINTS[reason];
|
|
178618
178619
|
}
|
|
178620
|
+
static normalizeStatusCode(statusCode, responseBody) {
|
|
178621
|
+
if (responseBody?.error_type === "KeyError") {
|
|
178622
|
+
return 404;
|
|
178623
|
+
}
|
|
178624
|
+
return statusCode;
|
|
178625
|
+
}
|
|
178619
178626
|
}
|
|
178620
178627
|
|
|
178621
178628
|
class FileNotFoundError extends SystemError {
|
|
@@ -185382,18 +185389,16 @@ async function fetchAgents() {
|
|
|
185382
185389
|
}
|
|
185383
185390
|
// src/core/resources/agent/config.ts
|
|
185384
185391
|
import { join as join3 } from "node:path";
|
|
185385
|
-
|
|
185386
|
-
return name2.toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
185387
|
-
}
|
|
185392
|
+
import { isDeepStrictEqual } from "node:util";
|
|
185388
185393
|
async function readAgentFile(agentPath) {
|
|
185389
|
-
const
|
|
185390
|
-
const result = AgentConfigSchema.safeParse(
|
|
185394
|
+
const raw2 = await readJsonFile(agentPath);
|
|
185395
|
+
const result = AgentConfigSchema.safeParse(raw2);
|
|
185391
185396
|
if (!result.success) {
|
|
185392
185397
|
throw new SchemaValidationError("Invalid agent file", result.error, agentPath);
|
|
185393
185398
|
}
|
|
185394
|
-
return result.data;
|
|
185399
|
+
return { data: result.data, raw: raw2 };
|
|
185395
185400
|
}
|
|
185396
|
-
async function
|
|
185401
|
+
async function readAgentFiles(agentsDir) {
|
|
185397
185402
|
if (!await pathExists(agentsDir)) {
|
|
185398
185403
|
return [];
|
|
185399
185404
|
}
|
|
@@ -185401,37 +185406,72 @@ async function readAllAgents(agentsDir) {
|
|
|
185401
185406
|
cwd: agentsDir,
|
|
185402
185407
|
absolute: true
|
|
185403
185408
|
});
|
|
185404
|
-
|
|
185405
|
-
|
|
185406
|
-
|
|
185407
|
-
|
|
185408
|
-
|
|
185409
|
+
return await Promise.all(files.map(async (filePath) => {
|
|
185410
|
+
const { data, raw: raw2 } = await readAgentFile(filePath);
|
|
185411
|
+
return { data, raw: raw2, filePath };
|
|
185412
|
+
}));
|
|
185413
|
+
}
|
|
185414
|
+
function buildNameToEntryMap(entries) {
|
|
185415
|
+
const nameToEntry = new Map;
|
|
185416
|
+
for (const entry of entries) {
|
|
185417
|
+
if (nameToEntry.has(entry.data.name)) {
|
|
185418
|
+
throw new InvalidInputError(`Duplicate agent name "${entry.data.name}"`, {
|
|
185419
|
+
hints: [
|
|
185420
|
+
{
|
|
185421
|
+
message: `Remove duplicate agents with name "${entry.data.name}" - only one agent per name is allowed`
|
|
185422
|
+
}
|
|
185423
|
+
]
|
|
185424
|
+
});
|
|
185425
|
+
}
|
|
185426
|
+
nameToEntry.set(entry.data.name, entry);
|
|
185427
|
+
}
|
|
185428
|
+
return nameToEntry;
|
|
185429
|
+
}
|
|
185430
|
+
async function readAllAgents(agentsDir) {
|
|
185431
|
+
const entries = await readAgentFiles(agentsDir);
|
|
185432
|
+
const nameToEntry = buildNameToEntryMap(entries);
|
|
185433
|
+
return [...nameToEntry.values()].map((e2) => e2.data);
|
|
185434
|
+
}
|
|
185435
|
+
function findAvailablePath(agentsDir, name2, claimedPaths) {
|
|
185436
|
+
const base = join3(agentsDir, `${name2}.${CONFIG_FILE_EXTENSION}`);
|
|
185437
|
+
if (!claimedPaths.has(base)) {
|
|
185438
|
+
return base;
|
|
185439
|
+
}
|
|
185440
|
+
for (let i = 1;; i++) {
|
|
185441
|
+
const candidate = join3(agentsDir, `${name2}_${i}.${CONFIG_FILE_EXTENSION}`);
|
|
185442
|
+
if (!claimedPaths.has(candidate)) {
|
|
185443
|
+
return candidate;
|
|
185409
185444
|
}
|
|
185410
|
-
names.add(agent.name);
|
|
185411
185445
|
}
|
|
185412
|
-
return agents;
|
|
185413
185446
|
}
|
|
185414
185447
|
async function writeAgents(agentsDir, remoteAgents) {
|
|
185415
|
-
const
|
|
185448
|
+
const entries = await readAgentFiles(agentsDir);
|
|
185449
|
+
const nameToEntry = buildNameToEntryMap(entries);
|
|
185416
185450
|
const newNames = new Set(remoteAgents.map((a) => a.name));
|
|
185417
|
-
const
|
|
185418
|
-
for (const
|
|
185419
|
-
|
|
185420
|
-
|
|
185421
|
-
|
|
185422
|
-
absolute: true
|
|
185423
|
-
});
|
|
185424
|
-
for (const filePath of files) {
|
|
185425
|
-
await deleteFile(filePath);
|
|
185451
|
+
const deleted = [];
|
|
185452
|
+
for (const [name2, entry] of nameToEntry) {
|
|
185453
|
+
if (!newNames.has(name2)) {
|
|
185454
|
+
await deleteFile(entry.filePath);
|
|
185455
|
+
deleted.push(name2);
|
|
185426
185456
|
}
|
|
185427
185457
|
}
|
|
185458
|
+
const claimedPaths = new Set;
|
|
185459
|
+
for (const [name2, entry] of nameToEntry) {
|
|
185460
|
+
if (newNames.has(name2)) {
|
|
185461
|
+
claimedPaths.add(entry.filePath);
|
|
185462
|
+
}
|
|
185463
|
+
}
|
|
185464
|
+
const written = [];
|
|
185428
185465
|
for (const agent of remoteAgents) {
|
|
185429
|
-
const
|
|
185430
|
-
|
|
185466
|
+
const existing = nameToEntry.get(agent.name);
|
|
185467
|
+
if (existing && isDeepStrictEqual(existing.raw, agent)) {
|
|
185468
|
+
continue;
|
|
185469
|
+
}
|
|
185470
|
+
const filePath = existing?.filePath ?? findAvailablePath(agentsDir, agent.name, claimedPaths);
|
|
185471
|
+
claimedPaths.add(filePath);
|
|
185431
185472
|
await writeJsonFile(filePath, agent);
|
|
185473
|
+
written.push(agent.name);
|
|
185432
185474
|
}
|
|
185433
|
-
const written = remoteAgents.map((a) => a.name);
|
|
185434
|
-
const deleted = toDelete.map((a) => a.name);
|
|
185435
185475
|
return { written, deleted };
|
|
185436
185476
|
}
|
|
185437
185477
|
// src/core/resources/agent/resource.ts
|
|
@@ -185648,7 +185688,7 @@ async function removeConnector(integrationType) {
|
|
|
185648
185688
|
}
|
|
185649
185689
|
// src/core/resources/connector/config.ts
|
|
185650
185690
|
import { join as join4 } from "node:path";
|
|
185651
|
-
import { isDeepStrictEqual } from "node:util";
|
|
185691
|
+
import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
185652
185692
|
async function readConnectorFile(connectorPath) {
|
|
185653
185693
|
const parsed = await readJsonFile(connectorPath);
|
|
185654
185694
|
const result = ConnectorResourceSchema.safeParse(parsed);
|
|
@@ -185709,7 +185749,7 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
|
|
|
185709
185749
|
type: connector.integrationType,
|
|
185710
185750
|
scopes: connector.scopes
|
|
185711
185751
|
};
|
|
185712
|
-
if (existing &&
|
|
185752
|
+
if (existing && isDeepStrictEqual2(existing.data, localConnector)) {
|
|
185713
185753
|
continue;
|
|
185714
185754
|
}
|
|
185715
185755
|
const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.integrationType}.${CONFIG_FILE_EXTENSION}`);
|
|
@@ -186012,6 +186052,13 @@ var DeployFunctionsResponseSchema = exports_external.object({
|
|
|
186012
186052
|
skipped: exports_external.array(exports_external.string()).optional().nullable(),
|
|
186013
186053
|
errors: exports_external.array(exports_external.object({ name: exports_external.string(), message: exports_external.string() })).nullable()
|
|
186014
186054
|
});
|
|
186055
|
+
var LogLevelSchema = exports_external.enum(["info", "warning", "error", "debug"]);
|
|
186056
|
+
var FunctionLogEntrySchema = exports_external.object({
|
|
186057
|
+
time: exports_external.string(),
|
|
186058
|
+
level: LogLevelSchema,
|
|
186059
|
+
message: exports_external.string()
|
|
186060
|
+
});
|
|
186061
|
+
var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
|
|
186015
186062
|
|
|
186016
186063
|
// src/core/resources/function/api.ts
|
|
186017
186064
|
function toDeployPayloadItem(fn) {
|
|
@@ -186042,6 +186089,42 @@ async function deployFunctions(functions) {
|
|
|
186042
186089
|
}
|
|
186043
186090
|
return result.data;
|
|
186044
186091
|
}
|
|
186092
|
+
function buildLogsQueryString(filters) {
|
|
186093
|
+
const params = new URLSearchParams;
|
|
186094
|
+
if (filters.since) {
|
|
186095
|
+
params.set("since", filters.since);
|
|
186096
|
+
}
|
|
186097
|
+
if (filters.until) {
|
|
186098
|
+
params.set("until", filters.until);
|
|
186099
|
+
}
|
|
186100
|
+
if (filters.level) {
|
|
186101
|
+
params.set("level", filters.level);
|
|
186102
|
+
}
|
|
186103
|
+
if (filters.limit !== undefined) {
|
|
186104
|
+
params.set("limit", String(filters.limit));
|
|
186105
|
+
}
|
|
186106
|
+
if (filters.order) {
|
|
186107
|
+
params.set("order", filters.order);
|
|
186108
|
+
}
|
|
186109
|
+
return params;
|
|
186110
|
+
}
|
|
186111
|
+
async function fetchFunctionLogs(functionName, filters = {}) {
|
|
186112
|
+
const appClient = getAppClient();
|
|
186113
|
+
const searchParams = buildLogsQueryString(filters);
|
|
186114
|
+
let response;
|
|
186115
|
+
try {
|
|
186116
|
+
response = await appClient.get(`functions-mgmt/${functionName}/logs`, {
|
|
186117
|
+
searchParams
|
|
186118
|
+
});
|
|
186119
|
+
} catch (error48) {
|
|
186120
|
+
throw await ApiError.fromHttpError(error48, `fetching function logs: '${functionName}'`);
|
|
186121
|
+
}
|
|
186122
|
+
const result = FunctionLogsResponseSchema.safeParse(await response.json());
|
|
186123
|
+
if (!result.success) {
|
|
186124
|
+
throw new SchemaValidationError("Invalid function logs response from server", result.error);
|
|
186125
|
+
}
|
|
186126
|
+
return result.data;
|
|
186127
|
+
}
|
|
186045
186128
|
// src/core/resources/function/config.ts
|
|
186046
186129
|
import { dirname as dirname4, join as join5 } from "node:path";
|
|
186047
186130
|
async function readFunctionConfig(configPath) {
|
|
@@ -193875,7 +193958,7 @@ var {
|
|
|
193875
193958
|
// package.json
|
|
193876
193959
|
var package_default = {
|
|
193877
193960
|
name: "base44",
|
|
193878
|
-
version: "0.0.
|
|
193961
|
+
version: "0.0.35",
|
|
193879
193962
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
193880
193963
|
type: "module",
|
|
193881
193964
|
bin: {
|
|
@@ -194003,7 +194086,6 @@ async function printUpgradeNotificationIfAvailable() {
|
|
|
194003
194086
|
|
|
194004
194087
|
// src/cli/utils/runCommand.ts
|
|
194005
194088
|
async function runCommand(commandFn, options, context) {
|
|
194006
|
-
console.log();
|
|
194007
194089
|
if (options?.fullBanner) {
|
|
194008
194090
|
await printBanner(context.isNonInteractive);
|
|
194009
194091
|
We("");
|
|
@@ -194029,8 +194111,11 @@ async function runCommand(commandFn, options, context) {
|
|
|
194029
194111
|
const appConfig = await initAppConfig();
|
|
194030
194112
|
context.errorReporter.setContext({ appId: appConfig.id });
|
|
194031
194113
|
}
|
|
194032
|
-
const
|
|
194033
|
-
Le(outroMessage || "");
|
|
194114
|
+
const result = await commandFn();
|
|
194115
|
+
Le(result.outroMessage || "");
|
|
194116
|
+
if (result.stdout) {
|
|
194117
|
+
process.stdout.write(result.stdout);
|
|
194118
|
+
}
|
|
194034
194119
|
} catch (error48) {
|
|
194035
194120
|
const errorMessage = error48 instanceof Error ? error48.message : String(error48);
|
|
194036
194121
|
R2.error(errorMessage);
|
|
@@ -194078,14 +194163,11 @@ async function pullAgentsAction() {
|
|
|
194078
194163
|
successMessage: "Agents fetched successfully",
|
|
194079
194164
|
errorMessage: "Failed to fetch agents"
|
|
194080
194165
|
});
|
|
194081
|
-
|
|
194082
|
-
return { outroMessage: "No agents found on Base44" };
|
|
194083
|
-
}
|
|
194084
|
-
const { written, deleted } = await runTask("Writing agent files", async () => {
|
|
194166
|
+
const { written, deleted } = await runTask("Syncing agent files", async () => {
|
|
194085
194167
|
return await writeAgents(agentsDir, remoteAgents.items);
|
|
194086
194168
|
}, {
|
|
194087
|
-
successMessage: "Agent files
|
|
194088
|
-
errorMessage: "Failed to
|
|
194169
|
+
successMessage: "Agent files synced successfully",
|
|
194170
|
+
errorMessage: "Failed to sync agent files"
|
|
194089
194171
|
});
|
|
194090
194172
|
if (written.length > 0) {
|
|
194091
194173
|
R2.success(`Written: ${written.join(", ")}`);
|
|
@@ -194093,6 +194175,9 @@ async function pullAgentsAction() {
|
|
|
194093
194175
|
if (deleted.length > 0) {
|
|
194094
194176
|
R2.warn(`Deleted: ${deleted.join(", ")}`);
|
|
194095
194177
|
}
|
|
194178
|
+
if (written.length === 0 && deleted.length === 0) {
|
|
194179
|
+
R2.info("All agents are already up to date");
|
|
194180
|
+
}
|
|
194096
194181
|
return {
|
|
194097
194182
|
outroMessage: `Pulled ${remoteAgents.total} agents to ${agentsDir}`
|
|
194098
194183
|
};
|
|
@@ -195451,6 +195536,125 @@ function getLinkCommand(context) {
|
|
|
195451
195536
|
});
|
|
195452
195537
|
}
|
|
195453
195538
|
|
|
195539
|
+
// src/cli/commands/project/logs.ts
|
|
195540
|
+
function parseFunctionFilters(options) {
|
|
195541
|
+
const filters = {};
|
|
195542
|
+
if (options.since) {
|
|
195543
|
+
filters.since = options.since;
|
|
195544
|
+
}
|
|
195545
|
+
if (options.until) {
|
|
195546
|
+
filters.until = options.until;
|
|
195547
|
+
}
|
|
195548
|
+
if (options.level) {
|
|
195549
|
+
filters.level = options.level;
|
|
195550
|
+
}
|
|
195551
|
+
if (options.limit) {
|
|
195552
|
+
filters.limit = Number.parseInt(options.limit, 10);
|
|
195553
|
+
}
|
|
195554
|
+
if (options.order) {
|
|
195555
|
+
filters.order = options.order.toLowerCase();
|
|
195556
|
+
}
|
|
195557
|
+
return filters;
|
|
195558
|
+
}
|
|
195559
|
+
function parseFunctionNames(option) {
|
|
195560
|
+
if (!option)
|
|
195561
|
+
return [];
|
|
195562
|
+
return option.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
195563
|
+
}
|
|
195564
|
+
function normalizeDatetime(value) {
|
|
195565
|
+
if (/Z$|[+-]\d{2}:\d{2}$/.test(value))
|
|
195566
|
+
return value;
|
|
195567
|
+
return `${value}Z`;
|
|
195568
|
+
}
|
|
195569
|
+
function formatEntry(entry) {
|
|
195570
|
+
const time3 = entry.time.substring(0, 19).replace("T", " ");
|
|
195571
|
+
const level = entry.level.toUpperCase().padEnd(5);
|
|
195572
|
+
const message = entry.message.trim();
|
|
195573
|
+
return `${time3} ${level} ${message}`;
|
|
195574
|
+
}
|
|
195575
|
+
function formatLogs(entries) {
|
|
195576
|
+
if (entries.length === 0) {
|
|
195577
|
+
return `No logs found matching the filters.
|
|
195578
|
+
`;
|
|
195579
|
+
}
|
|
195580
|
+
const header2 = `Showing ${entries.length} function log entries
|
|
195581
|
+
`;
|
|
195582
|
+
return [header2, ...entries.map(formatEntry)].join(`
|
|
195583
|
+
`);
|
|
195584
|
+
}
|
|
195585
|
+
function normalizeLogEntry(entry, functionName) {
|
|
195586
|
+
return {
|
|
195587
|
+
time: entry.time,
|
|
195588
|
+
level: entry.level,
|
|
195589
|
+
message: `[${functionName}] ${entry.message}`,
|
|
195590
|
+
source: functionName
|
|
195591
|
+
};
|
|
195592
|
+
}
|
|
195593
|
+
async function fetchLogsForFunctions(functionNames, options, availableFunctionNames) {
|
|
195594
|
+
const filters = parseFunctionFilters(options);
|
|
195595
|
+
const allEntries = [];
|
|
195596
|
+
for (const functionName of functionNames) {
|
|
195597
|
+
let logs;
|
|
195598
|
+
try {
|
|
195599
|
+
logs = await fetchFunctionLogs(functionName, filters);
|
|
195600
|
+
} catch (error48) {
|
|
195601
|
+
if (error48 instanceof ApiError && error48.statusCode === 404 && availableFunctionNames.length > 0) {
|
|
195602
|
+
const available = availableFunctionNames.join(", ");
|
|
195603
|
+
throw new InvalidInputError(`Function "${functionName}" was not found in this app`, {
|
|
195604
|
+
hints: [
|
|
195605
|
+
{
|
|
195606
|
+
message: `Available functions in this project: ${available}`
|
|
195607
|
+
},
|
|
195608
|
+
{
|
|
195609
|
+
message: "Make sure the function has been deployed before fetching logs",
|
|
195610
|
+
command: "base44 functions deploy"
|
|
195611
|
+
}
|
|
195612
|
+
]
|
|
195613
|
+
});
|
|
195614
|
+
}
|
|
195615
|
+
throw error48;
|
|
195616
|
+
}
|
|
195617
|
+
const entries = logs.map((entry) => normalizeLogEntry(entry, functionName));
|
|
195618
|
+
allEntries.push(...entries);
|
|
195619
|
+
}
|
|
195620
|
+
if (functionNames.length > 1) {
|
|
195621
|
+
const order = options.order?.toUpperCase() === "ASC" ? 1 : -1;
|
|
195622
|
+
allEntries.sort((a2, b) => order * a2.time.localeCompare(b.time));
|
|
195623
|
+
}
|
|
195624
|
+
return allEntries;
|
|
195625
|
+
}
|
|
195626
|
+
async function getAllFunctionNames() {
|
|
195627
|
+
const { functions } = await readProjectConfig();
|
|
195628
|
+
return functions.map((fn) => fn.name);
|
|
195629
|
+
}
|
|
195630
|
+
async function logsAction(options) {
|
|
195631
|
+
const specifiedFunctions = parseFunctionNames(options.function);
|
|
195632
|
+
const allProjectFunctions = await getAllFunctionNames();
|
|
195633
|
+
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
|
|
195634
|
+
if (functionNames.length === 0) {
|
|
195635
|
+
return { outroMessage: "No functions found in this project." };
|
|
195636
|
+
}
|
|
195637
|
+
let entries = await fetchLogsForFunctions(functionNames, options, allProjectFunctions);
|
|
195638
|
+
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
195639
|
+
if (limit !== undefined && entries.length > limit) {
|
|
195640
|
+
entries = entries.slice(0, limit);
|
|
195641
|
+
}
|
|
195642
|
+
const logsOutput = options.json ? `${JSON.stringify(entries, null, 2)}
|
|
195643
|
+
` : formatLogs(entries);
|
|
195644
|
+
return { outroMessage: "Fetched logs", stdout: logsOutput };
|
|
195645
|
+
}
|
|
195646
|
+
function getLogsCommand(context) {
|
|
195647
|
+
return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)", normalizeDatetime).option("--until <datetime>", "Show logs until this time (ISO format)", normalizeDatetime).addOption(new Option("--level <level>", "Filter by log level").choices([...LogLevelSchema.options]).hideHelp()).option("-n, --limit <n>", "Results per page (1-1000, default: 50)", (v) => {
|
|
195648
|
+
const n2 = Number.parseInt(v, 10);
|
|
195649
|
+
if (Number.isNaN(n2) || n2 < 1 || n2 > 1000) {
|
|
195650
|
+
throw new InvalidInputError(`Invalid limit: "${v}". Must be a number between 1 and 1000.`);
|
|
195651
|
+
}
|
|
195652
|
+
return v;
|
|
195653
|
+
}).addOption(new Option("--order <order>", "Sort order").choices(["asc", "desc"])).action(async (options) => {
|
|
195654
|
+
await runCommand(() => logsAction(options), { requireAuth: true }, context);
|
|
195655
|
+
});
|
|
195656
|
+
}
|
|
195657
|
+
|
|
195454
195658
|
// src/cli/commands/site/deploy.ts
|
|
195455
195659
|
import { resolve as resolve3 } from "node:path";
|
|
195456
195660
|
async function deployAction2(options) {
|
|
@@ -196172,6 +196376,7 @@ function createProgram(context) {
|
|
|
196172
196376
|
program2.addCommand(getSiteCommand(context));
|
|
196173
196377
|
program2.addCommand(getTypesCommand(context));
|
|
196174
196378
|
program2.addCommand(getDevCommand(context), { hidden: true });
|
|
196379
|
+
program2.addCommand(getLogsCommand(context), { hidden: true });
|
|
196175
196380
|
return program2;
|
|
196176
196381
|
}
|
|
196177
196382
|
|
|
@@ -200436,6 +200641,6 @@ export {
|
|
|
200436
200641
|
CLIExitError
|
|
200437
200642
|
};
|
|
200438
200643
|
|
|
200439
|
-
//# debugId=
|
|
200644
|
+
//# debugId=97F60A57F6E2DA7C64756E2164756E21
|
|
200440
200645
|
|
|
200441
|
-
//# chunkId=
|
|
200646
|
+
//# chunkId=019c8b01-a41e-78d0-855b-1f264ec2d7de
|