@base44-preview/cli 0.0.44-pr.382.bab01f6 → 0.0.44-pr.384.4b98c80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +176 -78
- package/dist/cli/index.js.map +12 -10
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -238249,11 +238249,8 @@ var BackendFunctionSchema = FunctionConfigSchema.extend({
|
|
|
238249
238249
|
entryPath: exports_external.string().min(1, "Entry path cannot be empty"),
|
|
238250
238250
|
filePaths: exports_external.array(exports_external.string()).min(1, "Function must have at least one file")
|
|
238251
238251
|
});
|
|
238252
|
-
var
|
|
238253
|
-
|
|
238254
|
-
deleted: exports_external.array(exports_external.string()),
|
|
238255
|
-
skipped: exports_external.array(exports_external.string()).optional().nullable(),
|
|
238256
|
-
errors: exports_external.array(exports_external.object({ name: exports_external.string(), message: exports_external.string() })).nullable()
|
|
238252
|
+
var DeploySingleFunctionResponseSchema = exports_external.object({
|
|
238253
|
+
status: exports_external.enum(["deployed", "unchanged"])
|
|
238257
238254
|
});
|
|
238258
238255
|
var FunctionInfoSchema = exports_external.object({
|
|
238259
238256
|
name: exports_external.string(),
|
|
@@ -238280,29 +238277,15 @@ var FunctionLogEntrySchema = exports_external.object({
|
|
|
238280
238277
|
var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
|
|
238281
238278
|
|
|
238282
238279
|
// src/core/resources/function/api.ts
|
|
238283
|
-
function
|
|
238284
|
-
return {
|
|
238285
|
-
name: fn.name,
|
|
238286
|
-
entry: fn.entry,
|
|
238287
|
-
files: fn.files,
|
|
238288
|
-
automations: fn.automations
|
|
238289
|
-
};
|
|
238290
|
-
}
|
|
238291
|
-
async function deployFunctions(functions) {
|
|
238280
|
+
async function deploySingleFunction(name2, payload) {
|
|
238292
238281
|
const appClient = getAppClient();
|
|
238293
|
-
const payload = {
|
|
238294
|
-
functions: functions.map(toDeployPayloadItem)
|
|
238295
|
-
};
|
|
238296
238282
|
let response;
|
|
238297
238283
|
try {
|
|
238298
|
-
response = await appClient.put(
|
|
238299
|
-
json: payload,
|
|
238300
|
-
timeout: false
|
|
238301
|
-
});
|
|
238284
|
+
response = await appClient.put(`backend-functions/${encodeURIComponent(name2)}`, { json: payload, timeout: false });
|
|
238302
238285
|
} catch (error48) {
|
|
238303
|
-
throw await ApiError.fromHttpError(error48,
|
|
238286
|
+
throw await ApiError.fromHttpError(error48, `deploying function "${name2}"`);
|
|
238304
238287
|
}
|
|
238305
|
-
const result =
|
|
238288
|
+
const result = DeploySingleFunctionResponseSchema.safeParse(await response.json());
|
|
238306
238289
|
if (!result.success) {
|
|
238307
238290
|
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
238308
238291
|
}
|
|
@@ -238318,6 +238301,20 @@ async function deleteSingleFunction(name2) {
|
|
|
238318
238301
|
throw await ApiError.fromHttpError(error48, `deleting function "${name2}"`);
|
|
238319
238302
|
}
|
|
238320
238303
|
}
|
|
238304
|
+
async function listDeployedFunctions() {
|
|
238305
|
+
const appClient = getAppClient();
|
|
238306
|
+
let response;
|
|
238307
|
+
try {
|
|
238308
|
+
response = await appClient.get("backend-functions", { timeout: 30000 });
|
|
238309
|
+
} catch (error48) {
|
|
238310
|
+
throw await ApiError.fromHttpError(error48, "listing deployed functions");
|
|
238311
|
+
}
|
|
238312
|
+
const result = ListFunctionsResponseSchema.safeParse(await response.json());
|
|
238313
|
+
if (!result.success) {
|
|
238314
|
+
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
238315
|
+
}
|
|
238316
|
+
return result.data;
|
|
238317
|
+
}
|
|
238321
238318
|
function buildLogsQueryString(filters) {
|
|
238322
238319
|
const params = new URLSearchParams;
|
|
238323
238320
|
if (filters.since) {
|
|
@@ -238354,20 +238351,6 @@ async function fetchFunctionLogs(functionName, filters = {}) {
|
|
|
238354
238351
|
}
|
|
238355
238352
|
return result.data;
|
|
238356
238353
|
}
|
|
238357
|
-
async function listDeployedFunctions() {
|
|
238358
|
-
const appClient = getAppClient();
|
|
238359
|
-
let response;
|
|
238360
|
-
try {
|
|
238361
|
-
response = await appClient.get("backend-functions", { timeout: 30000 });
|
|
238362
|
-
} catch (error48) {
|
|
238363
|
-
throw await ApiError.fromHttpError(error48, "listing deployed functions");
|
|
238364
|
-
}
|
|
238365
|
-
const result = ListFunctionsResponseSchema.safeParse(await response.json());
|
|
238366
|
-
if (!result.success) {
|
|
238367
|
-
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
238368
|
-
}
|
|
238369
|
-
return result.data;
|
|
238370
|
-
}
|
|
238371
238354
|
// src/core/resources/function/config.ts
|
|
238372
238355
|
import { basename as basename2, dirname as dirname3, join as join5, relative } from "node:path";
|
|
238373
238356
|
async function readFunctionConfig(configPath) {
|
|
@@ -238449,19 +238432,65 @@ async function readAllFunctions(functionsDir) {
|
|
|
238449
238432
|
import { dirname as dirname4, relative as relative2 } from "node:path";
|
|
238450
238433
|
async function loadFunctionCode(fn) {
|
|
238451
238434
|
const functionDir = dirname4(fn.entryPath);
|
|
238452
|
-
const
|
|
238435
|
+
const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
|
|
238453
238436
|
const content = await readTextFile(filePath);
|
|
238454
238437
|
const path11 = relative2(functionDir, filePath).split(/[/\\]/).join("/");
|
|
238455
238438
|
return { path: path11, content };
|
|
238456
238439
|
}));
|
|
238457
|
-
return { ...fn, files:
|
|
238440
|
+
return { ...fn, files: resolvedFiles };
|
|
238458
238441
|
}
|
|
238459
|
-
async function
|
|
238460
|
-
|
|
238461
|
-
|
|
238442
|
+
async function deployOne(fn) {
|
|
238443
|
+
const start = Date.now();
|
|
238444
|
+
try {
|
|
238445
|
+
const functionWithCode = await loadFunctionCode(fn);
|
|
238446
|
+
const response = await deploySingleFunction(functionWithCode.name, {
|
|
238447
|
+
entry: functionWithCode.entry,
|
|
238448
|
+
files: functionWithCode.files,
|
|
238449
|
+
automations: functionWithCode.automations
|
|
238450
|
+
});
|
|
238451
|
+
return {
|
|
238452
|
+
name: functionWithCode.name,
|
|
238453
|
+
status: response.status,
|
|
238454
|
+
durationMs: Date.now() - start
|
|
238455
|
+
};
|
|
238456
|
+
} catch (error48) {
|
|
238457
|
+
return {
|
|
238458
|
+
name: fn.name,
|
|
238459
|
+
status: "error",
|
|
238460
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
238461
|
+
};
|
|
238462
|
+
}
|
|
238463
|
+
}
|
|
238464
|
+
async function deployFunctionsSequentially(functions, options) {
|
|
238465
|
+
if (functions.length === 0)
|
|
238466
|
+
return [];
|
|
238467
|
+
const results = [];
|
|
238468
|
+
for (const fn of functions) {
|
|
238469
|
+
options?.onStart?.([fn.name]);
|
|
238470
|
+
const result = await deployOne(fn);
|
|
238471
|
+
results.push(result);
|
|
238472
|
+
options?.onResult?.(result);
|
|
238462
238473
|
}
|
|
238463
|
-
|
|
238464
|
-
|
|
238474
|
+
return results;
|
|
238475
|
+
}
|
|
238476
|
+
async function pruneRemovedFunctions(localFunctionNames) {
|
|
238477
|
+
const remote = await listDeployedFunctions();
|
|
238478
|
+
const localSet = new Set(localFunctionNames);
|
|
238479
|
+
const toDelete = remote.functions.filter((f) => !localSet.has(f.name));
|
|
238480
|
+
const results = [];
|
|
238481
|
+
for (const fn of toDelete) {
|
|
238482
|
+
try {
|
|
238483
|
+
await deleteSingleFunction(fn.name);
|
|
238484
|
+
results.push({ name: fn.name, deleted: true });
|
|
238485
|
+
} catch (error48) {
|
|
238486
|
+
results.push({
|
|
238487
|
+
name: fn.name,
|
|
238488
|
+
deleted: false,
|
|
238489
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
238490
|
+
});
|
|
238491
|
+
}
|
|
238492
|
+
}
|
|
238493
|
+
return results;
|
|
238465
238494
|
}
|
|
238466
238495
|
// src/core/resources/function/pull.ts
|
|
238467
238496
|
import { join as join6 } from "node:path";
|
|
@@ -238526,7 +238555,7 @@ async function isFunctionUnchanged(functionDir, fn) {
|
|
|
238526
238555
|
// src/core/resources/function/resource.ts
|
|
238527
238556
|
var functionResource = {
|
|
238528
238557
|
readAll: readAllFunctions,
|
|
238529
|
-
push:
|
|
238558
|
+
push: (functions) => deployFunctionsSequentially(functions)
|
|
238530
238559
|
};
|
|
238531
238560
|
// src/core/project/config.ts
|
|
238532
238561
|
async function findConfigInDir(dir) {
|
|
@@ -238951,10 +238980,13 @@ function hasResourcesToDeploy(projectData) {
|
|
|
238951
238980
|
const hasConnectors = connectors.length > 0;
|
|
238952
238981
|
return hasEntities || hasFunctions || hasAgents || hasConnectors || hasSite;
|
|
238953
238982
|
}
|
|
238954
|
-
async function deployAll(projectData) {
|
|
238983
|
+
async function deployAll(projectData, options) {
|
|
238955
238984
|
const { project, entities, functions, agents, connectors } = projectData;
|
|
238956
238985
|
await entityResource.push(entities);
|
|
238957
|
-
await
|
|
238986
|
+
await deployFunctionsSequentially(functions, {
|
|
238987
|
+
onStart: options?.onFunctionStart,
|
|
238988
|
+
onResult: options?.onFunctionResult
|
|
238989
|
+
});
|
|
238958
238990
|
await agentResource.push(agents);
|
|
238959
238991
|
const { results: connectorResults } = await pushConnectors(connectors);
|
|
238960
238992
|
if (project.site?.outputDirectory) {
|
|
@@ -247759,41 +247791,101 @@ function getDeleteCommand(context) {
|
|
|
247759
247791
|
});
|
|
247760
247792
|
}
|
|
247761
247793
|
|
|
247794
|
+
// src/cli/commands/functions/formatDeployResult.ts
|
|
247795
|
+
function formatDuration(ms) {
|
|
247796
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
247797
|
+
}
|
|
247798
|
+
function formatDeployResult(result) {
|
|
247799
|
+
const label = result.name.padEnd(25);
|
|
247800
|
+
if (result.status === "deployed") {
|
|
247801
|
+
const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
|
|
247802
|
+
R2.success(`${label} deployed${timing}`);
|
|
247803
|
+
} else if (result.status === "unchanged") {
|
|
247804
|
+
R2.success(`${label} unchanged`);
|
|
247805
|
+
} else {
|
|
247806
|
+
R2.error(`${label} error: ${result.error}`);
|
|
247807
|
+
}
|
|
247808
|
+
}
|
|
247809
|
+
|
|
247810
|
+
// src/cli/commands/functions/parseNames.ts
|
|
247811
|
+
function parseNames2(args) {
|
|
247812
|
+
return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
|
|
247813
|
+
}
|
|
247814
|
+
|
|
247762
247815
|
// src/cli/commands/functions/deploy.ts
|
|
247763
|
-
|
|
247816
|
+
function resolveFunctionsToDeploy(names, allFunctions) {
|
|
247817
|
+
if (names.length === 0)
|
|
247818
|
+
return allFunctions;
|
|
247819
|
+
const notFound = names.filter((n2) => !allFunctions.some((f) => f.name === n2));
|
|
247820
|
+
if (notFound.length > 0) {
|
|
247821
|
+
throw new InvalidInputError(`Function${notFound.length > 1 ? "s" : ""} not found in project: ${notFound.join(", ")}`);
|
|
247822
|
+
}
|
|
247823
|
+
return allFunctions.filter((f) => names.includes(f.name));
|
|
247824
|
+
}
|
|
247825
|
+
function formatPruneResults(pruneResults) {
|
|
247826
|
+
for (const pruneResult of pruneResults) {
|
|
247827
|
+
if (pruneResult.deleted) {
|
|
247828
|
+
R2.success(`${pruneResult.name.padEnd(25)} deleted`);
|
|
247829
|
+
} else {
|
|
247830
|
+
R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
|
|
247831
|
+
}
|
|
247832
|
+
}
|
|
247833
|
+
if (pruneResults.length > 0) {
|
|
247834
|
+
const pruned = pruneResults.filter((r) => r.deleted).length;
|
|
247835
|
+
R2.info(`${pruned} function${pruned !== 1 ? "s" : ""} removed`);
|
|
247836
|
+
}
|
|
247837
|
+
}
|
|
247838
|
+
function buildDeploySummary(results) {
|
|
247839
|
+
const deployed = results.filter((r) => r.status === "deployed").length;
|
|
247840
|
+
const unchanged = results.filter((r) => r.status === "unchanged").length;
|
|
247841
|
+
const failed = results.filter((r) => r.status === "error").length;
|
|
247842
|
+
const parts = [];
|
|
247843
|
+
if (deployed > 0)
|
|
247844
|
+
parts.push(`${deployed} deployed`);
|
|
247845
|
+
if (unchanged > 0)
|
|
247846
|
+
parts.push(`${unchanged} unchanged`);
|
|
247847
|
+
if (failed > 0)
|
|
247848
|
+
parts.push(`${failed} error${failed !== 1 ? "s" : ""}`);
|
|
247849
|
+
return parts.join(", ") || "No functions deployed";
|
|
247850
|
+
}
|
|
247851
|
+
async function deployFunctionsAction(names, options) {
|
|
247852
|
+
if (options.force && names.length > 0) {
|
|
247853
|
+
throw new InvalidInputError("--force cannot be used when specifying function names");
|
|
247854
|
+
}
|
|
247764
247855
|
const { functions } = await readProjectConfig();
|
|
247765
|
-
|
|
247856
|
+
const toDeploy = resolveFunctionsToDeploy(names, functions);
|
|
247857
|
+
if (toDeploy.length === 0) {
|
|
247766
247858
|
return {
|
|
247767
247859
|
outroMessage: "No functions found. Create functions in the 'functions' directory."
|
|
247768
247860
|
};
|
|
247769
247861
|
}
|
|
247770
|
-
R2.info(`Found ${
|
|
247771
|
-
|
|
247772
|
-
|
|
247773
|
-
|
|
247774
|
-
|
|
247775
|
-
|
|
247862
|
+
R2.info(`Found ${toDeploy.length} ${toDeploy.length === 1 ? "function" : "functions"} to deploy`);
|
|
247863
|
+
let completed = 0;
|
|
247864
|
+
const total = toDeploy.length;
|
|
247865
|
+
const results = await deployFunctionsSequentially(toDeploy, {
|
|
247866
|
+
onStart: (startNames) => {
|
|
247867
|
+
const label = startNames.length === 1 ? startNames[0] : `${startNames.length} functions`;
|
|
247868
|
+
R2.step(theme.styles.dim(`[${completed + 1}/${total}] Deploying ${label}...`));
|
|
247869
|
+
},
|
|
247870
|
+
onResult: (result) => {
|
|
247871
|
+
completed++;
|
|
247872
|
+
formatDeployResult(result);
|
|
247873
|
+
}
|
|
247776
247874
|
});
|
|
247777
|
-
if (
|
|
247778
|
-
R2.
|
|
247875
|
+
if (options.force) {
|
|
247876
|
+
R2.info("Removing remote functions not found locally...");
|
|
247877
|
+
const allLocalNames = functions.map((f) => f.name);
|
|
247878
|
+
const pruneResults = await pruneRemovedFunctions(allLocalNames);
|
|
247879
|
+
formatPruneResults(pruneResults);
|
|
247779
247880
|
}
|
|
247780
|
-
|
|
247781
|
-
R2.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
247782
|
-
}
|
|
247783
|
-
if (result.errors && result.errors.length > 0) {
|
|
247784
|
-
throw new ApiError("Function deployment errors", {
|
|
247785
|
-
details: result.errors.map((e2) => `'${e2.name}': ${e2.message}`),
|
|
247786
|
-
hints: [
|
|
247787
|
-
{ message: "Check the function code for syntax errors" },
|
|
247788
|
-
{ message: "Ensure all imports are valid" }
|
|
247789
|
-
]
|
|
247790
|
-
});
|
|
247791
|
-
}
|
|
247792
|
-
return { outroMessage: "Functions deployed to Base44" };
|
|
247881
|
+
return { outroMessage: buildDeploySummary(results) };
|
|
247793
247882
|
}
|
|
247794
247883
|
function getDeployCommand(context) {
|
|
247795
|
-
return new Command("deploy").description("Deploy
|
|
247796
|
-
await runCommand(
|
|
247884
|
+
return new Command("deploy").description("Deploy functions to Base44").argument("[names...]", "Function names to deploy (deploys all if omitted)").option("--force", "Delete remote functions not found locally").action(async (rawNames, options) => {
|
|
247885
|
+
await runCommand(() => {
|
|
247886
|
+
const names = parseNames2(rawNames);
|
|
247887
|
+
return deployFunctionsAction(names, options);
|
|
247888
|
+
}, { requireAuth: true }, context);
|
|
247797
247889
|
});
|
|
247798
247890
|
}
|
|
247799
247891
|
|
|
@@ -248092,11 +248184,17 @@ ${summaryLines.join(`
|
|
|
248092
248184
|
${summaryLines.join(`
|
|
248093
248185
|
`)}`);
|
|
248094
248186
|
}
|
|
248095
|
-
|
|
248096
|
-
|
|
248097
|
-
|
|
248098
|
-
|
|
248099
|
-
|
|
248187
|
+
let functionCompleted = 0;
|
|
248188
|
+
const functionTotal = functions.length;
|
|
248189
|
+
const result = await deployAll(projectData, {
|
|
248190
|
+
onFunctionStart: (names) => {
|
|
248191
|
+
const label = names.length === 1 ? names[0] : `${names.length} functions`;
|
|
248192
|
+
R2.step(theme.styles.dim(`[${functionCompleted + 1}/${functionTotal}] Deploying ${label}...`));
|
|
248193
|
+
},
|
|
248194
|
+
onFunctionResult: (r) => {
|
|
248195
|
+
functionCompleted++;
|
|
248196
|
+
formatDeployResult(r);
|
|
248197
|
+
}
|
|
248100
248198
|
});
|
|
248101
248199
|
const connectorResults = result.connectorResults ?? [];
|
|
248102
248200
|
await handleOAuthConnectors(connectorResults, options);
|
|
@@ -255655,4 +255753,4 @@ export {
|
|
|
255655
255753
|
CLIExitError
|
|
255656
255754
|
};
|
|
255657
255755
|
|
|
255658
|
-
//# debugId=
|
|
255756
|
+
//# debugId=8533D2C01A675ED464756E2164756E21
|