@base44-preview/cli 0.0.44-pr.382.bab01f6 → 0.0.44-pr.383.39531ce
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 +160 -71
- package/dist/cli/index.js.map +10 -8
- 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
238462
|
}
|
|
238463
|
-
|
|
238464
|
-
|
|
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);
|
|
238473
|
+
}
|
|
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) {
|
|
@@ -247759,41 +247788,101 @@ function getDeleteCommand(context) {
|
|
|
247759
247788
|
});
|
|
247760
247789
|
}
|
|
247761
247790
|
|
|
247791
|
+
// src/cli/commands/functions/formatDeployResult.ts
|
|
247792
|
+
function formatDuration(ms) {
|
|
247793
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
247794
|
+
}
|
|
247795
|
+
function formatDeployResult(result) {
|
|
247796
|
+
const label = result.name.padEnd(25);
|
|
247797
|
+
if (result.status === "deployed") {
|
|
247798
|
+
const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
|
|
247799
|
+
R2.success(`${label} deployed${timing}`);
|
|
247800
|
+
} else if (result.status === "unchanged") {
|
|
247801
|
+
R2.success(`${label} unchanged`);
|
|
247802
|
+
} else {
|
|
247803
|
+
R2.error(`${label} error: ${result.error}`);
|
|
247804
|
+
}
|
|
247805
|
+
}
|
|
247806
|
+
|
|
247807
|
+
// src/cli/commands/functions/parseNames.ts
|
|
247808
|
+
function parseNames2(args) {
|
|
247809
|
+
return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
|
|
247810
|
+
}
|
|
247811
|
+
|
|
247762
247812
|
// src/cli/commands/functions/deploy.ts
|
|
247763
|
-
|
|
247813
|
+
function resolveFunctionsToDeploy(names, allFunctions) {
|
|
247814
|
+
if (names.length === 0)
|
|
247815
|
+
return allFunctions;
|
|
247816
|
+
const notFound = names.filter((n2) => !allFunctions.some((f) => f.name === n2));
|
|
247817
|
+
if (notFound.length > 0) {
|
|
247818
|
+
throw new InvalidInputError(`Function${notFound.length > 1 ? "s" : ""} not found in project: ${notFound.join(", ")}`);
|
|
247819
|
+
}
|
|
247820
|
+
return allFunctions.filter((f) => names.includes(f.name));
|
|
247821
|
+
}
|
|
247822
|
+
function formatPruneResults(pruneResults) {
|
|
247823
|
+
for (const pruneResult of pruneResults) {
|
|
247824
|
+
if (pruneResult.deleted) {
|
|
247825
|
+
R2.success(`${pruneResult.name.padEnd(25)} deleted`);
|
|
247826
|
+
} else {
|
|
247827
|
+
R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
|
|
247828
|
+
}
|
|
247829
|
+
}
|
|
247830
|
+
if (pruneResults.length > 0) {
|
|
247831
|
+
const pruned = pruneResults.filter((r) => r.deleted).length;
|
|
247832
|
+
R2.info(`${pruned} function${pruned !== 1 ? "s" : ""} removed`);
|
|
247833
|
+
}
|
|
247834
|
+
}
|
|
247835
|
+
function buildDeploySummary(results) {
|
|
247836
|
+
const deployed = results.filter((r) => r.status === "deployed").length;
|
|
247837
|
+
const unchanged = results.filter((r) => r.status === "unchanged").length;
|
|
247838
|
+
const failed = results.filter((r) => r.status === "error").length;
|
|
247839
|
+
const parts = [];
|
|
247840
|
+
if (deployed > 0)
|
|
247841
|
+
parts.push(`${deployed} deployed`);
|
|
247842
|
+
if (unchanged > 0)
|
|
247843
|
+
parts.push(`${unchanged} unchanged`);
|
|
247844
|
+
if (failed > 0)
|
|
247845
|
+
parts.push(`${failed} error${failed !== 1 ? "s" : ""}`);
|
|
247846
|
+
return parts.join(", ") || "No functions deployed";
|
|
247847
|
+
}
|
|
247848
|
+
async function deployFunctionsAction(names, options) {
|
|
247849
|
+
if (options.force && names.length > 0) {
|
|
247850
|
+
throw new InvalidInputError("--force cannot be used when specifying function names");
|
|
247851
|
+
}
|
|
247764
247852
|
const { functions } = await readProjectConfig();
|
|
247765
|
-
|
|
247853
|
+
const toDeploy = resolveFunctionsToDeploy(names, functions);
|
|
247854
|
+
if (toDeploy.length === 0) {
|
|
247766
247855
|
return {
|
|
247767
247856
|
outroMessage: "No functions found. Create functions in the 'functions' directory."
|
|
247768
247857
|
};
|
|
247769
247858
|
}
|
|
247770
|
-
R2.info(`Found ${
|
|
247771
|
-
|
|
247772
|
-
|
|
247773
|
-
|
|
247774
|
-
|
|
247775
|
-
|
|
247859
|
+
R2.info(`Found ${toDeploy.length} ${toDeploy.length === 1 ? "function" : "functions"} to deploy`);
|
|
247860
|
+
let completed = 0;
|
|
247861
|
+
const total = toDeploy.length;
|
|
247862
|
+
const results = await deployFunctionsSequentially(toDeploy, {
|
|
247863
|
+
onStart: (startNames) => {
|
|
247864
|
+
const label = startNames.length === 1 ? startNames[0] : `${startNames.length} functions`;
|
|
247865
|
+
R2.step(theme.styles.dim(`[${completed + 1}/${total}] Deploying ${label}...`));
|
|
247866
|
+
},
|
|
247867
|
+
onResult: (result) => {
|
|
247868
|
+
completed++;
|
|
247869
|
+
formatDeployResult(result);
|
|
247870
|
+
}
|
|
247776
247871
|
});
|
|
247777
|
-
if (
|
|
247778
|
-
R2.
|
|
247779
|
-
|
|
247780
|
-
|
|
247781
|
-
|
|
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
|
-
});
|
|
247872
|
+
if (options.force) {
|
|
247873
|
+
R2.info("Removing remote functions not found locally...");
|
|
247874
|
+
const allLocalNames = functions.map((f) => f.name);
|
|
247875
|
+
const pruneResults = await pruneRemovedFunctions(allLocalNames);
|
|
247876
|
+
formatPruneResults(pruneResults);
|
|
247791
247877
|
}
|
|
247792
|
-
return { outroMessage:
|
|
247878
|
+
return { outroMessage: buildDeploySummary(results) };
|
|
247793
247879
|
}
|
|
247794
247880
|
function getDeployCommand(context) {
|
|
247795
|
-
return new Command("deploy").description("Deploy
|
|
247796
|
-
await runCommand(
|
|
247881
|
+
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) => {
|
|
247882
|
+
await runCommand(() => {
|
|
247883
|
+
const names = parseNames2(rawNames);
|
|
247884
|
+
return deployFunctionsAction(names, options);
|
|
247885
|
+
}, { requireAuth: true }, context);
|
|
247797
247886
|
});
|
|
247798
247887
|
}
|
|
247799
247888
|
|
|
@@ -255655,4 +255744,4 @@ export {
|
|
|
255655
255744
|
CLIExitError
|
|
255656
255745
|
};
|
|
255657
255746
|
|
|
255658
|
-
//# debugId=
|
|
255747
|
+
//# debugId=E5A92FA7C3FBB16864756E2164756E21
|