@base44-preview/cli 0.0.44-pr.417.2c58950 → 0.0.45-pr.406.7acd6ec
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 +778 -160
- package/dist/cli/index.js.map +26 -15
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16459,7 +16459,7 @@ var require_lodash = __commonJS((exports, module) => {
|
|
|
16459
16459
|
}
|
|
16460
16460
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
16461
16461
|
});
|
|
16462
|
-
function
|
|
16462
|
+
function join11(array2, separator) {
|
|
16463
16463
|
return array2 == null ? "" : nativeJoin.call(array2, separator);
|
|
16464
16464
|
}
|
|
16465
16465
|
function last(array2) {
|
|
@@ -16481,7 +16481,7 @@ var require_lodash = __commonJS((exports, module) => {
|
|
|
16481
16481
|
function nth(array2, n2) {
|
|
16482
16482
|
return array2 && array2.length ? baseNth(array2, toInteger(n2)) : undefined2;
|
|
16483
16483
|
}
|
|
16484
|
-
var
|
|
16484
|
+
var pull3 = baseRest(pullAll);
|
|
16485
16485
|
function pullAll(array2, values2) {
|
|
16486
16486
|
return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2) : array2;
|
|
16487
16487
|
}
|
|
@@ -18246,7 +18246,7 @@ __p += '`;
|
|
|
18246
18246
|
lodash.pickBy = pickBy;
|
|
18247
18247
|
lodash.property = property;
|
|
18248
18248
|
lodash.propertyOf = propertyOf;
|
|
18249
|
-
lodash.pull =
|
|
18249
|
+
lodash.pull = pull3;
|
|
18250
18250
|
lodash.pullAll = pullAll;
|
|
18251
18251
|
lodash.pullAllBy = pullAllBy;
|
|
18252
18252
|
lodash.pullAllWith = pullAllWith;
|
|
@@ -18391,7 +18391,7 @@ __p += '`;
|
|
|
18391
18391
|
lodash.isUndefined = isUndefined;
|
|
18392
18392
|
lodash.isWeakMap = isWeakMap;
|
|
18393
18393
|
lodash.isWeakSet = isWeakSet;
|
|
18394
|
-
lodash.join =
|
|
18394
|
+
lodash.join = join11;
|
|
18395
18395
|
lodash.kebabCase = kebabCase;
|
|
18396
18396
|
lodash.last = last;
|
|
18397
18397
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -27503,7 +27503,7 @@ function cleanDoc(doc2) {
|
|
|
27503
27503
|
return mapDoc(doc2, (currentDoc) => cleanDocFn(currentDoc));
|
|
27504
27504
|
}
|
|
27505
27505
|
function replaceEndOfLine(doc2, replacement = literalline) {
|
|
27506
|
-
return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ?
|
|
27506
|
+
return mapDoc(doc2, (currentDoc) => typeof currentDoc === "string" ? join15(replacement, currentDoc.split(`
|
|
27507
27507
|
`)) : currentDoc);
|
|
27508
27508
|
}
|
|
27509
27509
|
function canBreakFn(doc2) {
|
|
@@ -27583,7 +27583,7 @@ function indentIfBreak(contents, options) {
|
|
|
27583
27583
|
negate: options.negate
|
|
27584
27584
|
};
|
|
27585
27585
|
}
|
|
27586
|
-
function
|
|
27586
|
+
function join15(separator, docs) {
|
|
27587
27587
|
assertDoc(separator);
|
|
27588
27588
|
assertDocArray(docs);
|
|
27589
27589
|
const parts = [];
|
|
@@ -28294,7 +28294,7 @@ var init_doc = __esm(() => {
|
|
|
28294
28294
|
MODE_FLAT = Symbol("MODE_FLAT");
|
|
28295
28295
|
DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
|
|
28296
28296
|
builders = {
|
|
28297
|
-
join:
|
|
28297
|
+
join: join15,
|
|
28298
28298
|
line,
|
|
28299
28299
|
softline,
|
|
28300
28300
|
hardline,
|
|
@@ -133208,7 +133208,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
|
|
|
133208
133208
|
return mapDoc2(doc2, (currentDoc) => cleanDocFn2(currentDoc));
|
|
133209
133209
|
}
|
|
133210
133210
|
function replaceEndOfLine2(doc2, replacement = literalline2) {
|
|
133211
|
-
return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ?
|
|
133211
|
+
return mapDoc2(doc2, (currentDoc) => typeof currentDoc === "string" ? join17(replacement, currentDoc.split(`
|
|
133212
133212
|
`)) : currentDoc);
|
|
133213
133213
|
}
|
|
133214
133214
|
function canBreakFn2(doc2) {
|
|
@@ -133294,7 +133294,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
|
|
|
133294
133294
|
negate: options8.negate
|
|
133295
133295
|
};
|
|
133296
133296
|
}
|
|
133297
|
-
function
|
|
133297
|
+
function join17(separator, docs) {
|
|
133298
133298
|
assertDoc2(separator);
|
|
133299
133299
|
assertDocArray2(docs);
|
|
133300
133300
|
const parts = [];
|
|
@@ -133959,7 +133959,7 @@ Expected it to be ${EXPECTED_TYPE_VALUES}.`;
|
|
|
133959
133959
|
}
|
|
133960
133960
|
}
|
|
133961
133961
|
var builders2 = {
|
|
133962
|
-
join:
|
|
133962
|
+
join: join17,
|
|
133963
133963
|
line: line3,
|
|
133964
133964
|
softline: softline2,
|
|
133965
133965
|
hardline: hardline4,
|
|
@@ -160399,10 +160399,10 @@ var require_view = __commonJS((exports, module) => {
|
|
|
160399
160399
|
var debug = require_src4()("express:view");
|
|
160400
160400
|
var path18 = __require("node:path");
|
|
160401
160401
|
var fs28 = __require("node:fs");
|
|
160402
|
-
var
|
|
160402
|
+
var dirname12 = path18.dirname;
|
|
160403
160403
|
var basename4 = path18.basename;
|
|
160404
160404
|
var extname2 = path18.extname;
|
|
160405
|
-
var
|
|
160405
|
+
var join18 = path18.join;
|
|
160406
160406
|
var resolve6 = path18.resolve;
|
|
160407
160407
|
module.exports = View;
|
|
160408
160408
|
function View(name2, options8) {
|
|
@@ -160438,7 +160438,7 @@ var require_view = __commonJS((exports, module) => {
|
|
|
160438
160438
|
for (var i5 = 0;i5 < roots.length && !path19; i5++) {
|
|
160439
160439
|
var root2 = roots[i5];
|
|
160440
160440
|
var loc = resolve6(root2, name2);
|
|
160441
|
-
var dir =
|
|
160441
|
+
var dir = dirname12(loc);
|
|
160442
160442
|
var file2 = basename4(loc);
|
|
160443
160443
|
path19 = this.resolve(dir, file2);
|
|
160444
160444
|
}
|
|
@@ -160464,12 +160464,12 @@ var require_view = __commonJS((exports, module) => {
|
|
|
160464
160464
|
};
|
|
160465
160465
|
View.prototype.resolve = function resolve7(dir, file2) {
|
|
160466
160466
|
var ext = this.ext;
|
|
160467
|
-
var path19 =
|
|
160467
|
+
var path19 = join18(dir, file2);
|
|
160468
160468
|
var stat2 = tryStat(path19);
|
|
160469
160469
|
if (stat2 && stat2.isFile()) {
|
|
160470
160470
|
return path19;
|
|
160471
160471
|
}
|
|
160472
|
-
path19 =
|
|
160472
|
+
path19 = join18(dir, basename4(file2, ext), "index" + ext);
|
|
160473
160473
|
stat2 = tryStat(path19);
|
|
160474
160474
|
if (stat2 && stat2.isFile()) {
|
|
160475
160475
|
return path19;
|
|
@@ -164164,7 +164164,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
164164
164164
|
var Stream2 = __require("stream");
|
|
164165
164165
|
var util2 = __require("util");
|
|
164166
164166
|
var extname2 = path18.extname;
|
|
164167
|
-
var
|
|
164167
|
+
var join18 = path18.join;
|
|
164168
164168
|
var normalize = path18.normalize;
|
|
164169
164169
|
var resolve6 = path18.resolve;
|
|
164170
164170
|
var sep = path18.sep;
|
|
@@ -164336,7 +164336,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
164336
164336
|
return res;
|
|
164337
164337
|
}
|
|
164338
164338
|
parts = path19.split(sep);
|
|
164339
|
-
path19 = normalize(
|
|
164339
|
+
path19 = normalize(join18(root2, path19));
|
|
164340
164340
|
} else {
|
|
164341
164341
|
if (UP_PATH_REGEXP.test(path19)) {
|
|
164342
164342
|
debug('malicious path "%s"', path19);
|
|
@@ -164476,7 +164476,7 @@ var require_send = __commonJS((exports, module) => {
|
|
|
164476
164476
|
return self2.onStatError(err);
|
|
164477
164477
|
return self2.error(404);
|
|
164478
164478
|
}
|
|
164479
|
-
var p4 =
|
|
164479
|
+
var p4 = join18(path19, self2._index[i5]);
|
|
164480
164480
|
debug('stat "%s"', p4);
|
|
164481
164481
|
fs28.stat(p4, function(err2, stat2) {
|
|
164482
164482
|
if (err2)
|
|
@@ -211071,7 +211071,7 @@ var require_buffer_list = __commonJS((exports, module) => {
|
|
|
211071
211071
|
}
|
|
211072
211072
|
}, {
|
|
211073
211073
|
key: "join",
|
|
211074
|
-
value: function
|
|
211074
|
+
value: function join18(s5) {
|
|
211075
211075
|
if (this.length === 0)
|
|
211076
211076
|
return "";
|
|
211077
211077
|
var p4 = this.head;
|
|
@@ -214782,7 +214782,7 @@ var require_dist5 = __commonJS((exports, module) => {
|
|
|
214782
214782
|
});
|
|
214783
214783
|
|
|
214784
214784
|
// src/cli/index.ts
|
|
214785
|
-
import { dirname as
|
|
214785
|
+
import { dirname as dirname16, join as join21 } from "node:path";
|
|
214786
214786
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
214787
214787
|
|
|
214788
214788
|
// ../../node_modules/commander/esm.mjs
|
|
@@ -214802,7 +214802,7 @@ var {
|
|
|
214802
214802
|
} = import__.default;
|
|
214803
214803
|
|
|
214804
214804
|
// src/cli/commands/agents/pull.ts
|
|
214805
|
-
import { dirname as dirname7, join as
|
|
214805
|
+
import { dirname as dirname7, join as join11 } from "node:path";
|
|
214806
214806
|
|
|
214807
214807
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
214808
214808
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -237317,7 +237317,7 @@ var generateGlobTasks = normalizeArguments(generateTasks);
|
|
|
237317
237317
|
var generateGlobTasksSync = normalizeArgumentsSync(generateTasksSync);
|
|
237318
237318
|
|
|
237319
237319
|
// src/core/project/config.ts
|
|
237320
|
-
import { dirname as dirname5, join as
|
|
237320
|
+
import { dirname as dirname5, join as join7 } from "node:path";
|
|
237321
237321
|
|
|
237322
237322
|
// src/core/resources/agent/schema.ts
|
|
237323
237323
|
var EntityOperationSchema = exports_external.enum(["create", "update", "delete", "read"]);
|
|
@@ -238100,7 +238100,7 @@ var FieldRLSSchema = exports_external.looseObject({
|
|
|
238100
238100
|
delete: RLSRuleSchema.optional()
|
|
238101
238101
|
});
|
|
238102
238102
|
var PropertyDefinitionSchema = exports_external.looseObject({
|
|
238103
|
-
type: exports_external.string()
|
|
238103
|
+
type: exports_external.string(),
|
|
238104
238104
|
title: exports_external.string().optional(),
|
|
238105
238105
|
description: exports_external.string().optional(),
|
|
238106
238106
|
minLength: exports_external.number().int().min(0).optional(),
|
|
@@ -238249,11 +238249,24 @@ 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
|
-
|
|
238255
|
-
|
|
238256
|
-
|
|
238252
|
+
var DeploySingleFunctionResponseSchema = exports_external.object({
|
|
238253
|
+
status: exports_external.enum(["deployed", "unchanged"])
|
|
238254
|
+
});
|
|
238255
|
+
var FunctionInfoSchema = exports_external.object({
|
|
238256
|
+
name: exports_external.string(),
|
|
238257
|
+
deployment_id: exports_external.string(),
|
|
238258
|
+
entry: exports_external.string(),
|
|
238259
|
+
files: exports_external.array(FunctionFileSchema),
|
|
238260
|
+
automations: exports_external.array(AutomationSchema)
|
|
238261
|
+
}).transform((data) => ({
|
|
238262
|
+
name: data.name,
|
|
238263
|
+
deploymentId: data.deployment_id,
|
|
238264
|
+
entry: data.entry,
|
|
238265
|
+
files: data.files,
|
|
238266
|
+
automations: data.automations
|
|
238267
|
+
}));
|
|
238268
|
+
var ListFunctionsResponseSchema = exports_external.object({
|
|
238269
|
+
functions: exports_external.array(FunctionInfoSchema)
|
|
238257
238270
|
});
|
|
238258
238271
|
var LogLevelSchema = exports_external.enum(["info", "warning", "error", "debug"]);
|
|
238259
238272
|
var FunctionLogEntrySchema = exports_external.object({
|
|
@@ -238264,29 +238277,39 @@ var FunctionLogEntrySchema = exports_external.object({
|
|
|
238264
238277
|
var FunctionLogsResponseSchema = exports_external.array(FunctionLogEntrySchema);
|
|
238265
238278
|
|
|
238266
238279
|
// src/core/resources/function/api.ts
|
|
238267
|
-
function
|
|
238268
|
-
return {
|
|
238269
|
-
name: fn.name,
|
|
238270
|
-
entry: fn.entry,
|
|
238271
|
-
files: fn.files,
|
|
238272
|
-
automations: fn.automations
|
|
238273
|
-
};
|
|
238274
|
-
}
|
|
238275
|
-
async function deployFunctions(functions) {
|
|
238280
|
+
async function deploySingleFunction(name2, payload) {
|
|
238276
238281
|
const appClient = getAppClient();
|
|
238277
|
-
const payload = {
|
|
238278
|
-
functions: functions.map(toDeployPayloadItem)
|
|
238279
|
-
};
|
|
238280
238282
|
let response;
|
|
238281
238283
|
try {
|
|
238282
|
-
response = await appClient.put(
|
|
238283
|
-
|
|
238284
|
-
|
|
238284
|
+
response = await appClient.put(`backend-functions/${encodeURIComponent(name2)}`, { json: payload, timeout: false });
|
|
238285
|
+
} catch (error48) {
|
|
238286
|
+
throw await ApiError.fromHttpError(error48, `deploying function "${name2}"`);
|
|
238287
|
+
}
|
|
238288
|
+
const result = DeploySingleFunctionResponseSchema.safeParse(await response.json());
|
|
238289
|
+
if (!result.success) {
|
|
238290
|
+
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
238291
|
+
}
|
|
238292
|
+
return result.data;
|
|
238293
|
+
}
|
|
238294
|
+
async function deleteSingleFunction(name2) {
|
|
238295
|
+
const appClient = getAppClient();
|
|
238296
|
+
try {
|
|
238297
|
+
await appClient.delete(`backend-functions/${encodeURIComponent(name2)}`, {
|
|
238298
|
+
timeout: 60000
|
|
238285
238299
|
});
|
|
238286
238300
|
} catch (error48) {
|
|
238287
|
-
throw await ApiError.fromHttpError(error48,
|
|
238301
|
+
throw await ApiError.fromHttpError(error48, `deleting function "${name2}"`);
|
|
238302
|
+
}
|
|
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");
|
|
238288
238311
|
}
|
|
238289
|
-
const result =
|
|
238312
|
+
const result = ListFunctionsResponseSchema.safeParse(await response.json());
|
|
238290
238313
|
if (!result.success) {
|
|
238291
238314
|
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
238292
238315
|
}
|
|
@@ -238409,24 +238432,135 @@ async function readAllFunctions(functionsDir) {
|
|
|
238409
238432
|
import { dirname as dirname4, relative as relative2 } from "node:path";
|
|
238410
238433
|
async function loadFunctionCode(fn) {
|
|
238411
238434
|
const functionDir = dirname4(fn.entryPath);
|
|
238412
|
-
const
|
|
238435
|
+
const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
|
|
238413
238436
|
const content = await readTextFile(filePath);
|
|
238414
238437
|
const path11 = relative2(functionDir, filePath).split(/[/\\]/).join("/");
|
|
238415
238438
|
return { path: path11, content };
|
|
238416
238439
|
}));
|
|
238417
|
-
return { ...fn, files:
|
|
238440
|
+
return { ...fn, files: resolvedFiles };
|
|
238418
238441
|
}
|
|
238419
|
-
async function
|
|
238420
|
-
|
|
238421
|
-
|
|
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);
|
|
238473
|
+
}
|
|
238474
|
+
return results;
|
|
238475
|
+
}
|
|
238476
|
+
async function pruneRemovedFunctions(localFunctionNames, options) {
|
|
238477
|
+
const remote = await listDeployedFunctions();
|
|
238478
|
+
const localSet = new Set(localFunctionNames);
|
|
238479
|
+
const toDelete = remote.functions.filter((f) => !localSet.has(f.name));
|
|
238480
|
+
options?.onStart?.(toDelete.length);
|
|
238481
|
+
const results = [];
|
|
238482
|
+
for (const fn of toDelete) {
|
|
238483
|
+
options?.onBeforeDelete?.(fn.name);
|
|
238484
|
+
let result;
|
|
238485
|
+
try {
|
|
238486
|
+
await deleteSingleFunction(fn.name);
|
|
238487
|
+
result = { name: fn.name, deleted: true };
|
|
238488
|
+
} catch (error48) {
|
|
238489
|
+
result = {
|
|
238490
|
+
name: fn.name,
|
|
238491
|
+
deleted: false,
|
|
238492
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
238493
|
+
};
|
|
238494
|
+
}
|
|
238495
|
+
results.push(result);
|
|
238496
|
+
options?.onResult?.(result);
|
|
238497
|
+
}
|
|
238498
|
+
return results;
|
|
238499
|
+
}
|
|
238500
|
+
// src/core/resources/function/pull.ts
|
|
238501
|
+
import { join as join6 } from "node:path";
|
|
238502
|
+
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
238503
|
+
async function writeFunctions(functionsDir, functions) {
|
|
238504
|
+
const written = [];
|
|
238505
|
+
const skipped = [];
|
|
238506
|
+
for (const fn of functions) {
|
|
238507
|
+
const functionDir = join6(functionsDir, fn.name);
|
|
238508
|
+
const configPath = join6(functionDir, "function.jsonc");
|
|
238509
|
+
if (await isFunctionUnchanged(functionDir, fn)) {
|
|
238510
|
+
skipped.push(fn.name);
|
|
238511
|
+
continue;
|
|
238512
|
+
}
|
|
238513
|
+
const config5 = {
|
|
238514
|
+
name: fn.name,
|
|
238515
|
+
entry: fn.entry
|
|
238516
|
+
};
|
|
238517
|
+
if (fn.automations.length > 0) {
|
|
238518
|
+
config5.automations = fn.automations;
|
|
238519
|
+
}
|
|
238520
|
+
await writeJsonFile(configPath, config5);
|
|
238521
|
+
for (const file2 of fn.files) {
|
|
238522
|
+
await writeFile(join6(functionDir, file2.path), file2.content);
|
|
238523
|
+
}
|
|
238524
|
+
written.push(fn.name);
|
|
238422
238525
|
}
|
|
238423
|
-
|
|
238424
|
-
|
|
238526
|
+
return { written, skipped };
|
|
238527
|
+
}
|
|
238528
|
+
async function isFunctionUnchanged(functionDir, fn) {
|
|
238529
|
+
if (!await pathExists(functionDir)) {
|
|
238530
|
+
return false;
|
|
238531
|
+
}
|
|
238532
|
+
const configPath = join6(functionDir, "function.jsonc");
|
|
238533
|
+
try {
|
|
238534
|
+
const localConfig = await readJsonFile(configPath);
|
|
238535
|
+
if (localConfig.entry !== fn.entry) {
|
|
238536
|
+
return false;
|
|
238537
|
+
}
|
|
238538
|
+
if (!isDeepStrictEqual3(localConfig.automations ?? [], fn.automations)) {
|
|
238539
|
+
return false;
|
|
238540
|
+
}
|
|
238541
|
+
} catch {
|
|
238542
|
+
return false;
|
|
238543
|
+
}
|
|
238544
|
+
for (const file2 of fn.files) {
|
|
238545
|
+
const filePath = join6(functionDir, file2.path);
|
|
238546
|
+
if (!await pathExists(filePath)) {
|
|
238547
|
+
return false;
|
|
238548
|
+
}
|
|
238549
|
+
try {
|
|
238550
|
+
const localContent = await readTextFile(filePath);
|
|
238551
|
+
if (localContent !== file2.content) {
|
|
238552
|
+
return false;
|
|
238553
|
+
}
|
|
238554
|
+
} catch {
|
|
238555
|
+
return false;
|
|
238556
|
+
}
|
|
238557
|
+
}
|
|
238558
|
+
return true;
|
|
238425
238559
|
}
|
|
238426
238560
|
// src/core/resources/function/resource.ts
|
|
238427
238561
|
var functionResource = {
|
|
238428
238562
|
readAll: readAllFunctions,
|
|
238429
|
-
push:
|
|
238563
|
+
push: (functions) => deployFunctionsSequentially(functions)
|
|
238430
238564
|
};
|
|
238431
238565
|
// src/core/project/config.ts
|
|
238432
238566
|
async function findConfigInDir(dir) {
|
|
@@ -238467,10 +238601,10 @@ async function readProjectConfig(projectRoot) {
|
|
|
238467
238601
|
const project = result.data;
|
|
238468
238602
|
const configDir = dirname5(configPath);
|
|
238469
238603
|
const [entities, functions, agents, connectors] = await Promise.all([
|
|
238470
|
-
entityResource.readAll(
|
|
238471
|
-
functionResource.readAll(
|
|
238472
|
-
agentResource.readAll(
|
|
238473
|
-
connectorResource.readAll(
|
|
238604
|
+
entityResource.readAll(join7(configDir, project.entitiesDir)),
|
|
238605
|
+
functionResource.readAll(join7(configDir, project.functionsDir)),
|
|
238606
|
+
agentResource.readAll(join7(configDir, project.agentsDir)),
|
|
238607
|
+
connectorResource.readAll(join7(configDir, project.connectorsDir))
|
|
238474
238608
|
]);
|
|
238475
238609
|
return {
|
|
238476
238610
|
project: { ...project, root, configPath },
|
|
@@ -238567,16 +238701,16 @@ async function readAppConfig(projectRoot) {
|
|
|
238567
238701
|
// src/core/project/template.ts
|
|
238568
238702
|
var import_ejs = __toESM(require_ejs(), 1);
|
|
238569
238703
|
var import_front_matter = __toESM(require_front_matter(), 1);
|
|
238570
|
-
import { dirname as dirname6, join as
|
|
238704
|
+
import { dirname as dirname6, join as join9 } from "node:path";
|
|
238571
238705
|
|
|
238572
238706
|
// src/core/assets.ts
|
|
238573
238707
|
import { cpSync, existsSync } from "node:fs";
|
|
238574
238708
|
import { homedir as homedir2 } from "node:os";
|
|
238575
|
-
import { join as
|
|
238709
|
+
import { join as join8 } from "node:path";
|
|
238576
238710
|
// package.json
|
|
238577
238711
|
var package_default = {
|
|
238578
238712
|
name: "base44",
|
|
238579
|
-
version: "0.0.
|
|
238713
|
+
version: "0.0.45",
|
|
238580
238714
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
238581
238715
|
type: "module",
|
|
238582
238716
|
bin: {
|
|
@@ -238665,15 +238799,15 @@ var package_default = {
|
|
|
238665
238799
|
};
|
|
238666
238800
|
|
|
238667
238801
|
// src/core/assets.ts
|
|
238668
|
-
var ASSETS_DIR =
|
|
238802
|
+
var ASSETS_DIR = join8(homedir2(), ".base44", "assets", package_default.version);
|
|
238669
238803
|
function getTemplatesDir() {
|
|
238670
|
-
return
|
|
238804
|
+
return join8(ASSETS_DIR, "templates");
|
|
238671
238805
|
}
|
|
238672
238806
|
function getTemplatesIndexPath() {
|
|
238673
|
-
return
|
|
238807
|
+
return join8(ASSETS_DIR, "templates", "templates.json");
|
|
238674
238808
|
}
|
|
238675
238809
|
function getDenoWrapperPath() {
|
|
238676
|
-
return
|
|
238810
|
+
return join8(ASSETS_DIR, "deno-runtime", "main.js");
|
|
238677
238811
|
}
|
|
238678
238812
|
function ensureNpmAssets(sourceDir) {
|
|
238679
238813
|
if (existsSync(ASSETS_DIR))
|
|
@@ -238694,23 +238828,23 @@ async function listTemplates() {
|
|
|
238694
238828
|
return result.data.templates;
|
|
238695
238829
|
}
|
|
238696
238830
|
async function renderTemplate(template, destPath, data) {
|
|
238697
|
-
const templateDir =
|
|
238831
|
+
const templateDir = join9(getTemplatesDir(), template.path);
|
|
238698
238832
|
const files = await globby("**/*", {
|
|
238699
238833
|
cwd: templateDir,
|
|
238700
238834
|
dot: true,
|
|
238701
238835
|
onlyFiles: true
|
|
238702
238836
|
});
|
|
238703
238837
|
for (const file2 of files) {
|
|
238704
|
-
const srcPath =
|
|
238838
|
+
const srcPath = join9(templateDir, file2);
|
|
238705
238839
|
try {
|
|
238706
238840
|
if (file2.endsWith(".ejs")) {
|
|
238707
238841
|
const rendered = await import_ejs.default.renderFile(srcPath, data);
|
|
238708
238842
|
const { attributes, body } = import_front_matter.default(rendered);
|
|
238709
|
-
const destFile = attributes.outputFileName ?
|
|
238710
|
-
const destFilePath =
|
|
238843
|
+
const destFile = attributes.outputFileName ? join9(dirname6(file2), attributes.outputFileName) : file2.replace(/\.ejs$/, "");
|
|
238844
|
+
const destFilePath = join9(destPath, destFile);
|
|
238711
238845
|
await writeFile(destFilePath, body);
|
|
238712
238846
|
} else {
|
|
238713
|
-
const destFilePath =
|
|
238847
|
+
const destFilePath = join9(destPath, file2);
|
|
238714
238848
|
await copyFile(srcPath, destFilePath);
|
|
238715
238849
|
}
|
|
238716
238850
|
} catch (error48) {
|
|
@@ -238809,7 +238943,7 @@ async function getSiteFilePaths(outputDir) {
|
|
|
238809
238943
|
// src/core/site/deploy.ts
|
|
238810
238944
|
import { randomUUID } from "node:crypto";
|
|
238811
238945
|
import { tmpdir } from "node:os";
|
|
238812
|
-
import { join as
|
|
238946
|
+
import { join as join10 } from "node:path";
|
|
238813
238947
|
async function deploySite(siteOutputDir) {
|
|
238814
238948
|
if (!await pathExists(siteOutputDir)) {
|
|
238815
238949
|
throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
|
|
@@ -238826,7 +238960,7 @@ async function deploySite(siteOutputDir) {
|
|
|
238826
238960
|
]
|
|
238827
238961
|
});
|
|
238828
238962
|
}
|
|
238829
|
-
const archivePath =
|
|
238963
|
+
const archivePath = join10(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
|
|
238830
238964
|
try {
|
|
238831
238965
|
await createArchive(siteOutputDir, archivePath);
|
|
238832
238966
|
return await uploadSite(archivePath);
|
|
@@ -238851,10 +238985,13 @@ function hasResourcesToDeploy(projectData) {
|
|
|
238851
238985
|
const hasConnectors = connectors.length > 0;
|
|
238852
238986
|
return hasEntities || hasFunctions || hasAgents || hasConnectors || hasSite;
|
|
238853
238987
|
}
|
|
238854
|
-
async function deployAll(projectData) {
|
|
238988
|
+
async function deployAll(projectData, options) {
|
|
238855
238989
|
const { project, entities, functions, agents, connectors } = projectData;
|
|
238856
238990
|
await entityResource.push(entities);
|
|
238857
|
-
await
|
|
238991
|
+
await deployFunctionsSequentially(functions, {
|
|
238992
|
+
onStart: options?.onFunctionStart,
|
|
238993
|
+
onResult: options?.onFunctionResult
|
|
238994
|
+
});
|
|
238858
238995
|
await agentResource.push(agents);
|
|
238859
238996
|
const { results: connectorResults } = await pushConnectors(connectors);
|
|
238860
238997
|
if (project.site?.outputDirectory) {
|
|
@@ -246611,7 +246748,7 @@ function formatYaml(data, options = {}) {
|
|
|
246611
246748
|
async function pullAgentsAction() {
|
|
246612
246749
|
const { project: project2 } = await readProjectConfig();
|
|
246613
246750
|
const configDir = dirname7(project2.configPath);
|
|
246614
|
-
const agentsDir =
|
|
246751
|
+
const agentsDir = join11(configDir, project2.agentsDir);
|
|
246615
246752
|
const remoteAgents = await runTask("Fetching agents from Base44", async () => {
|
|
246616
246753
|
return await fetchAgents();
|
|
246617
246754
|
}, {
|
|
@@ -246733,11 +246870,11 @@ function getConnectorsListAvailableCommand(context) {
|
|
|
246733
246870
|
}
|
|
246734
246871
|
|
|
246735
246872
|
// src/cli/commands/connectors/pull.ts
|
|
246736
|
-
import { dirname as dirname8, join as
|
|
246873
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
246737
246874
|
async function pullConnectorsAction() {
|
|
246738
246875
|
const { project: project2 } = await readProjectConfig();
|
|
246739
246876
|
const configDir = dirname8(project2.configPath);
|
|
246740
|
-
const connectorsDir =
|
|
246877
|
+
const connectorsDir = join12(configDir, project2.connectorsDir);
|
|
246741
246878
|
const remoteConnectors = await runTask("Fetching connectors from Base44", async () => {
|
|
246742
246879
|
return await pullAllConnectors();
|
|
246743
246880
|
}, {
|
|
@@ -247606,46 +247743,242 @@ function getEntitiesPushCommand(context) {
|
|
|
247606
247743
|
}));
|
|
247607
247744
|
}
|
|
247608
247745
|
|
|
247746
|
+
// src/cli/commands/functions/delete.ts
|
|
247747
|
+
async function deleteFunctionsAction(names) {
|
|
247748
|
+
let deleted = 0;
|
|
247749
|
+
let notFound = 0;
|
|
247750
|
+
let errors5 = 0;
|
|
247751
|
+
for (const name2 of names) {
|
|
247752
|
+
try {
|
|
247753
|
+
await runTask(`Deleting ${name2}...`, () => deleteSingleFunction(name2), {
|
|
247754
|
+
successMessage: `${name2} deleted`,
|
|
247755
|
+
errorMessage: `Failed to delete ${name2}`
|
|
247756
|
+
});
|
|
247757
|
+
deleted++;
|
|
247758
|
+
} catch (error48) {
|
|
247759
|
+
if (error48 instanceof ApiError && error48.statusCode === 404) {
|
|
247760
|
+
notFound++;
|
|
247761
|
+
} else {
|
|
247762
|
+
errors5++;
|
|
247763
|
+
}
|
|
247764
|
+
}
|
|
247765
|
+
}
|
|
247766
|
+
if (names.length === 1) {
|
|
247767
|
+
if (deleted)
|
|
247768
|
+
return { outroMessage: `Function "${names[0]}" deleted` };
|
|
247769
|
+
if (notFound)
|
|
247770
|
+
return { outroMessage: `Function "${names[0]}" not found` };
|
|
247771
|
+
return { outroMessage: `Failed to delete "${names[0]}"` };
|
|
247772
|
+
}
|
|
247773
|
+
const total = names.length;
|
|
247774
|
+
const parts = [];
|
|
247775
|
+
if (deleted > 0)
|
|
247776
|
+
parts.push(`${deleted}/${total} deleted`);
|
|
247777
|
+
if (notFound > 0)
|
|
247778
|
+
parts.push(`${notFound} not found`);
|
|
247779
|
+
if (errors5 > 0)
|
|
247780
|
+
parts.push(`${errors5} error${errors5 !== 1 ? "s" : ""}`);
|
|
247781
|
+
return { outroMessage: parts.join(", ") };
|
|
247782
|
+
}
|
|
247783
|
+
function parseNames(args) {
|
|
247784
|
+
return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
|
|
247785
|
+
}
|
|
247786
|
+
function validateNames(command) {
|
|
247787
|
+
const names = parseNames(command.args);
|
|
247788
|
+
if (names.length === 0) {
|
|
247789
|
+
command.error("At least one function name is required");
|
|
247790
|
+
}
|
|
247791
|
+
}
|
|
247792
|
+
function getDeleteCommand(context) {
|
|
247793
|
+
return new Command("delete").description("Delete deployed functions").argument("<names...>", "Function names to delete").hook("preAction", validateNames).action(async (rawNames) => {
|
|
247794
|
+
const names = parseNames(rawNames);
|
|
247795
|
+
await runCommand(() => deleteFunctionsAction(names), { requireAuth: true }, context);
|
|
247796
|
+
});
|
|
247797
|
+
}
|
|
247798
|
+
|
|
247799
|
+
// src/cli/commands/functions/formatDeployResult.ts
|
|
247800
|
+
function formatDuration(ms) {
|
|
247801
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
247802
|
+
}
|
|
247803
|
+
function formatDeployResult(result) {
|
|
247804
|
+
const label = result.name.padEnd(25);
|
|
247805
|
+
if (result.status === "deployed") {
|
|
247806
|
+
const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
|
|
247807
|
+
R2.success(`${label} deployed${timing}`);
|
|
247808
|
+
} else if (result.status === "unchanged") {
|
|
247809
|
+
R2.success(`${label} unchanged`);
|
|
247810
|
+
} else {
|
|
247811
|
+
R2.error(`${label} error: ${result.error}`);
|
|
247812
|
+
}
|
|
247813
|
+
}
|
|
247814
|
+
|
|
247815
|
+
// src/cli/commands/functions/parseNames.ts
|
|
247816
|
+
function parseNames2(args) {
|
|
247817
|
+
return args.flatMap((arg) => arg.split(",")).map((n2) => n2.trim()).filter(Boolean);
|
|
247818
|
+
}
|
|
247819
|
+
|
|
247609
247820
|
// src/cli/commands/functions/deploy.ts
|
|
247610
|
-
|
|
247821
|
+
function resolveFunctionsToDeploy(names, allFunctions) {
|
|
247822
|
+
if (names.length === 0)
|
|
247823
|
+
return allFunctions;
|
|
247824
|
+
const notFound = names.filter((n2) => !allFunctions.some((f) => f.name === n2));
|
|
247825
|
+
if (notFound.length > 0) {
|
|
247826
|
+
throw new InvalidInputError(`Function${notFound.length > 1 ? "s" : ""} not found in project: ${notFound.join(", ")}`);
|
|
247827
|
+
}
|
|
247828
|
+
return allFunctions.filter((f) => names.includes(f.name));
|
|
247829
|
+
}
|
|
247830
|
+
function formatPruneResult(pruneResult) {
|
|
247831
|
+
if (pruneResult.deleted) {
|
|
247832
|
+
R2.success(`${pruneResult.name.padEnd(25)} deleted`);
|
|
247833
|
+
} else {
|
|
247834
|
+
R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
|
|
247835
|
+
}
|
|
247836
|
+
}
|
|
247837
|
+
function formatPruneSummary(pruneResults) {
|
|
247838
|
+
if (pruneResults.length > 0) {
|
|
247839
|
+
const pruned = pruneResults.filter((r) => r.deleted).length;
|
|
247840
|
+
R2.info(`${pruned} deleted`);
|
|
247841
|
+
}
|
|
247842
|
+
}
|
|
247843
|
+
function buildDeploySummary(results) {
|
|
247844
|
+
const deployed = results.filter((r) => r.status === "deployed").length;
|
|
247845
|
+
const unchanged = results.filter((r) => r.status === "unchanged").length;
|
|
247846
|
+
const failed = results.filter((r) => r.status === "error").length;
|
|
247847
|
+
const parts = [];
|
|
247848
|
+
if (deployed > 0)
|
|
247849
|
+
parts.push(`${deployed} deployed`);
|
|
247850
|
+
if (unchanged > 0)
|
|
247851
|
+
parts.push(`${unchanged} unchanged`);
|
|
247852
|
+
if (failed > 0)
|
|
247853
|
+
parts.push(`${failed} error${failed !== 1 ? "s" : ""}`);
|
|
247854
|
+
return parts.join(", ") || "No functions deployed";
|
|
247855
|
+
}
|
|
247856
|
+
async function deployFunctionsAction(names, options) {
|
|
247857
|
+
if (options.force && names.length > 0) {
|
|
247858
|
+
throw new InvalidInputError("--force cannot be used when specifying function names");
|
|
247859
|
+
}
|
|
247611
247860
|
const { functions } = await readProjectConfig();
|
|
247612
|
-
|
|
247861
|
+
const toDeploy = resolveFunctionsToDeploy(names, functions);
|
|
247862
|
+
if (toDeploy.length === 0) {
|
|
247613
247863
|
return {
|
|
247614
247864
|
outroMessage: "No functions found. Create functions in the 'functions' directory."
|
|
247615
247865
|
};
|
|
247616
247866
|
}
|
|
247617
|
-
R2.info(`Found ${
|
|
247618
|
-
|
|
247619
|
-
|
|
247867
|
+
R2.info(`Found ${toDeploy.length} ${toDeploy.length === 1 ? "function" : "functions"} to deploy`);
|
|
247868
|
+
let completed = 0;
|
|
247869
|
+
const total = toDeploy.length;
|
|
247870
|
+
const results = await deployFunctionsSequentially(toDeploy, {
|
|
247871
|
+
onStart: (startNames) => {
|
|
247872
|
+
const label = startNames.length === 1 ? startNames[0] : `${startNames.length} functions`;
|
|
247873
|
+
R2.step(theme.styles.dim(`[${completed + 1}/${total}] Deploying ${label}...`));
|
|
247874
|
+
},
|
|
247875
|
+
onResult: (result) => {
|
|
247876
|
+
completed++;
|
|
247877
|
+
formatDeployResult(result);
|
|
247878
|
+
}
|
|
247879
|
+
});
|
|
247880
|
+
if (options.force) {
|
|
247881
|
+
const allLocalNames = functions.map((f) => f.name);
|
|
247882
|
+
let pruneCompleted = 0;
|
|
247883
|
+
let pruneTotal = 0;
|
|
247884
|
+
const pruneResults = await pruneRemovedFunctions(allLocalNames, {
|
|
247885
|
+
onStart: (total2) => {
|
|
247886
|
+
pruneTotal = total2;
|
|
247887
|
+
if (total2 > 0) {
|
|
247888
|
+
R2.info(`Found ${total2} remote ${total2 === 1 ? "function" : "functions"} to delete`);
|
|
247889
|
+
}
|
|
247890
|
+
},
|
|
247891
|
+
onBeforeDelete: (name2) => {
|
|
247892
|
+
pruneCompleted++;
|
|
247893
|
+
R2.step(theme.styles.dim(`[${pruneCompleted}/${pruneTotal}] Deleting ${name2}...`));
|
|
247894
|
+
},
|
|
247895
|
+
onResult: formatPruneResult
|
|
247896
|
+
});
|
|
247897
|
+
formatPruneSummary(pruneResults);
|
|
247898
|
+
}
|
|
247899
|
+
return { outroMessage: buildDeploySummary(results) };
|
|
247900
|
+
}
|
|
247901
|
+
function getDeployCommand(context) {
|
|
247902
|
+
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) => {
|
|
247903
|
+
await runCommand(() => {
|
|
247904
|
+
const names = parseNames2(rawNames);
|
|
247905
|
+
return deployFunctionsAction(names, options);
|
|
247906
|
+
}, { requireAuth: true }, context);
|
|
247907
|
+
});
|
|
247908
|
+
}
|
|
247909
|
+
|
|
247910
|
+
// src/cli/commands/functions/list.ts
|
|
247911
|
+
async function listFunctionsAction() {
|
|
247912
|
+
const { functions } = await runTask("Fetching functions...", async () => listDeployedFunctions(), { errorMessage: "Failed to fetch functions" });
|
|
247913
|
+
if (functions.length === 0) {
|
|
247914
|
+
return { outroMessage: "No functions on remote" };
|
|
247915
|
+
}
|
|
247916
|
+
for (const fn of functions) {
|
|
247917
|
+
const automationCount = fn.automations.length;
|
|
247918
|
+
const automationLabel = automationCount > 0 ? theme.styles.dim(` (${automationCount} automation${automationCount > 1 ? "s" : ""})`) : "";
|
|
247919
|
+
R2.message(` ${fn.name}${automationLabel}`);
|
|
247920
|
+
}
|
|
247921
|
+
return {
|
|
247922
|
+
outroMessage: `${functions.length} function${functions.length !== 1 ? "s" : ""} on remote`
|
|
247923
|
+
};
|
|
247924
|
+
}
|
|
247925
|
+
function getListCommand(context) {
|
|
247926
|
+
return new Command("list").description("List all deployed functions").action(async () => {
|
|
247927
|
+
await runCommand(listFunctionsAction, { requireAuth: true }, context);
|
|
247928
|
+
});
|
|
247929
|
+
}
|
|
247930
|
+
|
|
247931
|
+
// src/cli/commands/functions/pull.ts
|
|
247932
|
+
import { dirname as dirname9, join as join13 } from "node:path";
|
|
247933
|
+
async function pullFunctionsAction(name2) {
|
|
247934
|
+
const { project: project2 } = await readProjectConfig();
|
|
247935
|
+
const configDir = dirname9(project2.configPath);
|
|
247936
|
+
const functionsDir = join13(configDir, project2.functionsDir);
|
|
247937
|
+
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
247938
|
+
const { functions } = await listDeployedFunctions();
|
|
247939
|
+
return functions;
|
|
247620
247940
|
}, {
|
|
247621
|
-
successMessage: "Functions
|
|
247622
|
-
errorMessage: "Failed to
|
|
247941
|
+
successMessage: "Functions fetched successfully",
|
|
247942
|
+
errorMessage: "Failed to fetch functions"
|
|
247623
247943
|
});
|
|
247624
|
-
|
|
247625
|
-
|
|
247944
|
+
const toPull = name2 ? remoteFunctions.filter((f) => f.name === name2) : remoteFunctions;
|
|
247945
|
+
if (name2 && toPull.length === 0) {
|
|
247946
|
+
return {
|
|
247947
|
+
outroMessage: `Function "${name2}" not found on remote`
|
|
247948
|
+
};
|
|
247626
247949
|
}
|
|
247627
|
-
if (
|
|
247628
|
-
|
|
247950
|
+
if (toPull.length === 0) {
|
|
247951
|
+
return { outroMessage: "No functions found on remote" };
|
|
247629
247952
|
}
|
|
247630
|
-
|
|
247631
|
-
|
|
247632
|
-
|
|
247633
|
-
|
|
247634
|
-
|
|
247635
|
-
|
|
247636
|
-
|
|
247637
|
-
});
|
|
247953
|
+
const { written, skipped } = await runTask("Writing function files", async () => {
|
|
247954
|
+
return await writeFunctions(functionsDir, toPull);
|
|
247955
|
+
}, {
|
|
247956
|
+
successMessage: "Function files written successfully",
|
|
247957
|
+
errorMessage: "Failed to write function files"
|
|
247958
|
+
});
|
|
247959
|
+
for (const name3 of written) {
|
|
247960
|
+
R2.success(`${name3.padEnd(25)} written`);
|
|
247638
247961
|
}
|
|
247639
|
-
|
|
247962
|
+
for (const name3 of skipped) {
|
|
247963
|
+
R2.info(`${name3.padEnd(25)} unchanged`);
|
|
247964
|
+
}
|
|
247965
|
+
return {
|
|
247966
|
+
outroMessage: `Pulled ${toPull.length} function${toPull.length !== 1 ? "s" : ""} to ${functionsDir}`
|
|
247967
|
+
};
|
|
247640
247968
|
}
|
|
247641
|
-
function
|
|
247642
|
-
return new Command("
|
|
247643
|
-
await runCommand(
|
|
247644
|
-
})
|
|
247969
|
+
function getPullCommand(context) {
|
|
247970
|
+
return new Command("pull").description("Pull deployed functions from Base44").argument("[name]", "Function name to pull (pulls all if omitted)").action(async (name2) => {
|
|
247971
|
+
await runCommand(() => pullFunctionsAction(name2), { requireAuth: true }, context);
|
|
247972
|
+
});
|
|
247973
|
+
}
|
|
247974
|
+
|
|
247975
|
+
// src/cli/commands/functions/index.ts
|
|
247976
|
+
function getFunctionsCommand(context) {
|
|
247977
|
+
return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand(context)).addCommand(getDeleteCommand(context)).addCommand(getListCommand(context)).addCommand(getPullCommand(context));
|
|
247645
247978
|
}
|
|
247646
247979
|
|
|
247647
247980
|
// src/cli/commands/project/create.ts
|
|
247648
|
-
import { basename as basename3, join as
|
|
247981
|
+
import { basename as basename3, join as join14, resolve as resolve2 } from "node:path";
|
|
247649
247982
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
247650
247983
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
247651
247984
|
async function getTemplateById(templateId) {
|
|
@@ -247782,7 +248115,7 @@ async function executeCreate({
|
|
|
247782
248115
|
updateMessage("Building project...");
|
|
247783
248116
|
await execa({ cwd: resolvedPath, shell: true })`${buildCommand}`;
|
|
247784
248117
|
updateMessage("Deploying site...");
|
|
247785
|
-
return await deploySite(
|
|
248118
|
+
return await deploySite(join14(resolvedPath, outputDirectory));
|
|
247786
248119
|
}, {
|
|
247787
248120
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
247788
248121
|
errorMessage: "Failed to deploy site"
|
|
@@ -247869,11 +248202,17 @@ ${summaryLines.join(`
|
|
|
247869
248202
|
${summaryLines.join(`
|
|
247870
248203
|
`)}`);
|
|
247871
248204
|
}
|
|
247872
|
-
|
|
247873
|
-
|
|
247874
|
-
|
|
247875
|
-
|
|
247876
|
-
|
|
248205
|
+
let functionCompleted = 0;
|
|
248206
|
+
const functionTotal = functions.length;
|
|
248207
|
+
const result = await deployAll(projectData, {
|
|
248208
|
+
onFunctionStart: (names) => {
|
|
248209
|
+
const label = names.length === 1 ? names[0] : `${names.length} functions`;
|
|
248210
|
+
R2.step(theme.styles.dim(`[${functionCompleted + 1}/${functionTotal}] Deploying ${label}...`));
|
|
248211
|
+
},
|
|
248212
|
+
onFunctionResult: (r) => {
|
|
248213
|
+
functionCompleted++;
|
|
248214
|
+
formatDeployResult(r);
|
|
248215
|
+
}
|
|
247877
248216
|
});
|
|
247878
248217
|
const connectorResults = result.connectorResults ?? [];
|
|
247879
248218
|
await handleOAuthConnectors(connectorResults, options);
|
|
@@ -247887,7 +248226,7 @@ ${summaryLines.join(`
|
|
|
247887
248226
|
}
|
|
247888
248227
|
return { outroMessage: "App deployed successfully" };
|
|
247889
248228
|
}
|
|
247890
|
-
function
|
|
248229
|
+
function getDeployCommand2(context) {
|
|
247891
248230
|
return new Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
247892
248231
|
await runCommand(() => deployAction({
|
|
247893
248232
|
...options,
|
|
@@ -248432,10 +248771,10 @@ function toPascalCase(name2) {
|
|
|
248432
248771
|
return name2.split(/[-_\s]+/).map((w8) => w8.charAt(0).toUpperCase() + w8.slice(1)).join("");
|
|
248433
248772
|
}
|
|
248434
248773
|
// src/core/types/update-project.ts
|
|
248435
|
-
import { join as
|
|
248774
|
+
import { join as join17 } from "node:path";
|
|
248436
248775
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
248437
248776
|
async function updateProjectConfig(projectRoot) {
|
|
248438
|
-
const tsconfigPath =
|
|
248777
|
+
const tsconfigPath = join17(projectRoot, "tsconfig.json");
|
|
248439
248778
|
if (!await pathExists(tsconfigPath)) {
|
|
248440
248779
|
return false;
|
|
248441
248780
|
}
|
|
@@ -248478,9 +248817,9 @@ function getTypesCommand(context) {
|
|
|
248478
248817
|
}
|
|
248479
248818
|
|
|
248480
248819
|
// src/cli/dev/dev-server/main.ts
|
|
248481
|
-
import { dirname as
|
|
248820
|
+
import { dirname as dirname14, join as join20 } from "node:path";
|
|
248482
248821
|
var import_cors = __toESM(require_lib4(), 1);
|
|
248483
|
-
var
|
|
248822
|
+
var import_express6 = __toESM(require_express(), 1);
|
|
248484
248823
|
|
|
248485
248824
|
// ../../node_modules/get-port/index.js
|
|
248486
248825
|
import net from "node:net";
|
|
@@ -248835,18 +249174,196 @@ function createFunctionRouter(manager, logger) {
|
|
|
248835
249174
|
return router;
|
|
248836
249175
|
}
|
|
248837
249176
|
|
|
248838
|
-
// src/cli/dev/dev-server/database.ts
|
|
249177
|
+
// src/cli/dev/dev-server/db/database.ts
|
|
248839
249178
|
var import_nedb = __toESM(require_nedb(), 1);
|
|
248840
249179
|
|
|
249180
|
+
// src/cli/dev/dev-server/db/validator.ts
|
|
249181
|
+
var fieldTypes = [
|
|
249182
|
+
"string",
|
|
249183
|
+
"integer",
|
|
249184
|
+
"number",
|
|
249185
|
+
"boolean",
|
|
249186
|
+
"array",
|
|
249187
|
+
"object"
|
|
249188
|
+
];
|
|
249189
|
+
|
|
249190
|
+
class Validator {
|
|
249191
|
+
filterFields(record2, entitySchema) {
|
|
249192
|
+
const filteredRecord = {};
|
|
249193
|
+
for (const [key2, value] of Object.entries(record2)) {
|
|
249194
|
+
if (entitySchema.properties[key2]) {
|
|
249195
|
+
filteredRecord[key2] = value;
|
|
249196
|
+
}
|
|
249197
|
+
}
|
|
249198
|
+
return filteredRecord;
|
|
249199
|
+
}
|
|
249200
|
+
applyDefaults(record2, entitySchema) {
|
|
249201
|
+
const result = {};
|
|
249202
|
+
for (const [key2, property] of Object.entries(entitySchema.properties)) {
|
|
249203
|
+
if (property.default !== undefined) {
|
|
249204
|
+
result[key2] = property.default;
|
|
249205
|
+
}
|
|
249206
|
+
}
|
|
249207
|
+
return {
|
|
249208
|
+
...result,
|
|
249209
|
+
...record2
|
|
249210
|
+
};
|
|
249211
|
+
}
|
|
249212
|
+
validate(record2, entitySchema, partial2 = false) {
|
|
249213
|
+
if (!partial2) {
|
|
249214
|
+
const requiredFieldsResponse = this.validateRequiredFields(record2, entitySchema);
|
|
249215
|
+
if (requiredFieldsResponse.hasError) {
|
|
249216
|
+
return requiredFieldsResponse;
|
|
249217
|
+
}
|
|
249218
|
+
}
|
|
249219
|
+
const fieldTypesResponse = this.validateFieldTypes(record2, entitySchema);
|
|
249220
|
+
if (fieldTypesResponse.hasError) {
|
|
249221
|
+
return fieldTypesResponse;
|
|
249222
|
+
}
|
|
249223
|
+
return {
|
|
249224
|
+
hasError: false
|
|
249225
|
+
};
|
|
249226
|
+
}
|
|
249227
|
+
createValidationError(message) {
|
|
249228
|
+
return {
|
|
249229
|
+
error_type: "ValidationError",
|
|
249230
|
+
message,
|
|
249231
|
+
request_id: null,
|
|
249232
|
+
traceback: ""
|
|
249233
|
+
};
|
|
249234
|
+
}
|
|
249235
|
+
validateFieldTypes(record2, entitySchema) {
|
|
249236
|
+
for (const [key2, value] of Object.entries(record2)) {
|
|
249237
|
+
const property = entitySchema.properties[key2];
|
|
249238
|
+
const result = this.validateValue(value, property, key2);
|
|
249239
|
+
if (result.hasError)
|
|
249240
|
+
return result;
|
|
249241
|
+
}
|
|
249242
|
+
return {
|
|
249243
|
+
hasError: false
|
|
249244
|
+
};
|
|
249245
|
+
}
|
|
249246
|
+
validateValue(value, property, fieldPath) {
|
|
249247
|
+
if (!property) {
|
|
249248
|
+
return { hasError: false };
|
|
249249
|
+
}
|
|
249250
|
+
const propertyType = property.type;
|
|
249251
|
+
if (!fieldTypes.includes(propertyType)) {
|
|
249252
|
+
return {
|
|
249253
|
+
hasError: true,
|
|
249254
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Unsupported field type ${propertyType}`)
|
|
249255
|
+
};
|
|
249256
|
+
}
|
|
249257
|
+
switch (propertyType) {
|
|
249258
|
+
case "array":
|
|
249259
|
+
if (!Array.isArray(value)) {
|
|
249260
|
+
return {
|
|
249261
|
+
hasError: true,
|
|
249262
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be a valid array`)
|
|
249263
|
+
};
|
|
249264
|
+
}
|
|
249265
|
+
if (property.items) {
|
|
249266
|
+
for (let i5 = 0;i5 < value.length; i5++) {
|
|
249267
|
+
const itemResult = this.validateValue(value[i5], property.items, `${fieldPath}[${i5}]`);
|
|
249268
|
+
if (itemResult.hasError)
|
|
249269
|
+
return itemResult;
|
|
249270
|
+
}
|
|
249271
|
+
}
|
|
249272
|
+
break;
|
|
249273
|
+
case "object":
|
|
249274
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
249275
|
+
return {
|
|
249276
|
+
hasError: true,
|
|
249277
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be a valid object`)
|
|
249278
|
+
};
|
|
249279
|
+
}
|
|
249280
|
+
if (property.properties) {
|
|
249281
|
+
for (const [subKey, subValue] of Object.entries(value)) {
|
|
249282
|
+
if (property.properties[subKey]) {
|
|
249283
|
+
const subResult = this.validateValue(subValue, property.properties[subKey], `${fieldPath}.${subKey}`);
|
|
249284
|
+
if (subResult.hasError)
|
|
249285
|
+
return subResult;
|
|
249286
|
+
}
|
|
249287
|
+
}
|
|
249288
|
+
}
|
|
249289
|
+
break;
|
|
249290
|
+
case "integer":
|
|
249291
|
+
if (!Number.isInteger(value)) {
|
|
249292
|
+
return {
|
|
249293
|
+
hasError: true,
|
|
249294
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be a valid integer`)
|
|
249295
|
+
};
|
|
249296
|
+
}
|
|
249297
|
+
break;
|
|
249298
|
+
default:
|
|
249299
|
+
if (typeof value !== propertyType) {
|
|
249300
|
+
return {
|
|
249301
|
+
hasError: true,
|
|
249302
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be a valid ${propertyType}`)
|
|
249303
|
+
};
|
|
249304
|
+
}
|
|
249305
|
+
}
|
|
249306
|
+
return { hasError: false };
|
|
249307
|
+
}
|
|
249308
|
+
validateRequiredFields(record2, entitySchema) {
|
|
249309
|
+
if (entitySchema.required && entitySchema.required.length > 0) {
|
|
249310
|
+
for (const required2 of entitySchema.required) {
|
|
249311
|
+
if (record2[required2] == null) {
|
|
249312
|
+
return {
|
|
249313
|
+
hasError: true,
|
|
249314
|
+
error: this.createValidationError(`Error in field ${required2}: Field required`)
|
|
249315
|
+
};
|
|
249316
|
+
}
|
|
249317
|
+
}
|
|
249318
|
+
}
|
|
249319
|
+
return {
|
|
249320
|
+
hasError: false
|
|
249321
|
+
};
|
|
249322
|
+
}
|
|
249323
|
+
}
|
|
249324
|
+
|
|
249325
|
+
// src/cli/dev/dev-server/db/database.ts
|
|
249326
|
+
var USER_COLLECTION = "user";
|
|
249327
|
+
|
|
248841
249328
|
class Database {
|
|
248842
249329
|
collections = new Map;
|
|
249330
|
+
schemas = new Map;
|
|
249331
|
+
validator = new Validator;
|
|
248843
249332
|
load(entities) {
|
|
249333
|
+
this.collections.set(USER_COLLECTION, new import_nedb.default);
|
|
248844
249334
|
for (const entity2 of entities) {
|
|
248845
|
-
this.
|
|
249335
|
+
const entityName = this.normalizeName(entity2.name);
|
|
249336
|
+
this.collections.set(entityName, new import_nedb.default);
|
|
249337
|
+
const clonedEntity = structuredClone(entity2);
|
|
249338
|
+
if (entityName === USER_COLLECTION) {
|
|
249339
|
+
["full_name", "email"].forEach((predefinedField) => {
|
|
249340
|
+
if (predefinedField in clonedEntity.properties) {
|
|
249341
|
+
throw new Error(`Error syncing entities: Invalid User schema: User schema cannot contain base fields: ${predefinedField}. These fields are built-in and managed by the system.`);
|
|
249342
|
+
}
|
|
249343
|
+
});
|
|
249344
|
+
clonedEntity.properties.full_name = { type: "string" };
|
|
249345
|
+
clonedEntity.properties.email = { type: "string" };
|
|
249346
|
+
clonedEntity.properties.role = { type: "string" };
|
|
249347
|
+
}
|
|
249348
|
+
this.schemas.set(entityName, clonedEntity);
|
|
249349
|
+
}
|
|
249350
|
+
if (!this.schemas.has(USER_COLLECTION)) {
|
|
249351
|
+
this.schemas.set(USER_COLLECTION, {
|
|
249352
|
+
name: "User",
|
|
249353
|
+
type: "object",
|
|
249354
|
+
properties: {
|
|
249355
|
+
full_name: { type: "string" },
|
|
249356
|
+
email: { type: "string" },
|
|
249357
|
+
role: { type: "string" }
|
|
249358
|
+
}
|
|
249359
|
+
});
|
|
248846
249360
|
}
|
|
248847
249361
|
}
|
|
249362
|
+
hasCollection(name2) {
|
|
249363
|
+
return this.collections.has(this.normalizeName(name2));
|
|
249364
|
+
}
|
|
248848
249365
|
getCollection(name2) {
|
|
248849
|
-
return this.collections.get(name2);
|
|
249366
|
+
return this.collections.get(this.normalizeName(name2));
|
|
248850
249367
|
}
|
|
248851
249368
|
getCollectionNames() {
|
|
248852
249369
|
return Array.from(this.collections.keys());
|
|
@@ -248856,6 +249373,28 @@ class Database {
|
|
|
248856
249373
|
collection.remove({}, { multi: true });
|
|
248857
249374
|
}
|
|
248858
249375
|
this.collections.clear();
|
|
249376
|
+
this.schemas.clear();
|
|
249377
|
+
}
|
|
249378
|
+
validate(entityName, record2, partial2 = false) {
|
|
249379
|
+
const schema9 = this.schemas.get(this.normalizeName(entityName));
|
|
249380
|
+
if (!schema9) {
|
|
249381
|
+
throw new Error(`Entity "${entityName}" not found`);
|
|
249382
|
+
}
|
|
249383
|
+
return this.validator.validate(record2, schema9, partial2);
|
|
249384
|
+
}
|
|
249385
|
+
prepareRecord(entityName, record2, partial2 = false) {
|
|
249386
|
+
const schema9 = this.schemas.get(this.normalizeName(entityName));
|
|
249387
|
+
if (!schema9) {
|
|
249388
|
+
throw new Error(`Entity "${entityName}" not found`);
|
|
249389
|
+
}
|
|
249390
|
+
const filteredRecord = this.validator.filterFields(record2, schema9);
|
|
249391
|
+
if (partial2) {
|
|
249392
|
+
return filteredRecord;
|
|
249393
|
+
}
|
|
249394
|
+
return this.validator.applyDefaults(filteredRecord, schema9);
|
|
249395
|
+
}
|
|
249396
|
+
normalizeName(entityName) {
|
|
249397
|
+
return entityName.toLowerCase();
|
|
248859
249398
|
}
|
|
248860
249399
|
}
|
|
248861
249400
|
|
|
@@ -248891,8 +249430,8 @@ function broadcastEntityEvent(io6, appId, entityName, event) {
|
|
|
248891
249430
|
});
|
|
248892
249431
|
}
|
|
248893
249432
|
|
|
248894
|
-
// src/cli/dev/dev-server/routes/entities.ts
|
|
248895
|
-
var
|
|
249433
|
+
// src/cli/dev/dev-server/routes/entities/entities-router.ts
|
|
249434
|
+
var import_express3 = __toESM(require_express(), 1);
|
|
248896
249435
|
|
|
248897
249436
|
// ../../node_modules/nanoid/index.js
|
|
248898
249437
|
import { webcrypto as crypto } from "node:crypto";
|
|
@@ -248924,7 +249463,53 @@ function nanoid3(size = 21) {
|
|
|
248924
249463
|
return id2;
|
|
248925
249464
|
}
|
|
248926
249465
|
|
|
248927
|
-
// src/cli/dev/dev-server/routes/entities.ts
|
|
249466
|
+
// src/cli/dev/dev-server/routes/entities/entities-user-router.ts
|
|
249467
|
+
var import_express2 = __toESM(require_express(), 1);
|
|
249468
|
+
|
|
249469
|
+
// src/cli/dev/dev-server/routes/entities/utils.ts
|
|
249470
|
+
function stripInternalFields(doc2) {
|
|
249471
|
+
if (Array.isArray(doc2)) {
|
|
249472
|
+
return doc2.map((d5) => stripInternalFields(d5));
|
|
249473
|
+
}
|
|
249474
|
+
const { _id, ...rest } = doc2;
|
|
249475
|
+
return rest;
|
|
249476
|
+
}
|
|
249477
|
+
|
|
249478
|
+
// src/cli/dev/dev-server/routes/entities/entities-user-router.ts
|
|
249479
|
+
async function createUserRouter(db2) {
|
|
249480
|
+
const userInfo = await readAuth();
|
|
249481
|
+
const meEntity = await db2.getCollection("User")?.findOneAsync({ email: userInfo.email });
|
|
249482
|
+
let idMe = meEntity?.id;
|
|
249483
|
+
if (!idMe) {
|
|
249484
|
+
const now = new Date().toISOString().replace("Z", "000");
|
|
249485
|
+
idMe = nanoid3();
|
|
249486
|
+
await db2.getCollection("User")?.insertAsync({
|
|
249487
|
+
id: idMe,
|
|
249488
|
+
email: userInfo.email,
|
|
249489
|
+
full_name: userInfo.name,
|
|
249490
|
+
is_service: false,
|
|
249491
|
+
is_verified: true,
|
|
249492
|
+
disabled: null,
|
|
249493
|
+
role: "admin",
|
|
249494
|
+
collaborator_role: "editor",
|
|
249495
|
+
created_date: now,
|
|
249496
|
+
updated_date: now
|
|
249497
|
+
});
|
|
249498
|
+
}
|
|
249499
|
+
const router = import_express2.Router({ mergeParams: true });
|
|
249500
|
+
router.get("/:id", async (req, res) => {
|
|
249501
|
+
const id2 = req.params.id === "me" ? idMe : req.params.id;
|
|
249502
|
+
const result = await db2.getCollection("User")?.findOneAsync({ id: id2 });
|
|
249503
|
+
if (!result) {
|
|
249504
|
+
res.status(404).json({ error: `User with id "${req.params.id}" not found` });
|
|
249505
|
+
return;
|
|
249506
|
+
}
|
|
249507
|
+
res.json(stripInternalFields(result));
|
|
249508
|
+
});
|
|
249509
|
+
return router;
|
|
249510
|
+
}
|
|
249511
|
+
|
|
249512
|
+
// src/cli/dev/dev-server/routes/entities/entities-router.ts
|
|
248928
249513
|
function parseSort(sort) {
|
|
248929
249514
|
if (!sort) {
|
|
248930
249515
|
return;
|
|
@@ -248947,16 +249532,9 @@ function parseFields(fields) {
|
|
|
248947
249532
|
}
|
|
248948
249533
|
return Object.keys(projection).length > 0 ? projection : undefined;
|
|
248949
249534
|
}
|
|
248950
|
-
function
|
|
248951
|
-
|
|
248952
|
-
|
|
248953
|
-
}
|
|
248954
|
-
const { _id, ...rest } = doc2;
|
|
248955
|
-
return rest;
|
|
248956
|
-
}
|
|
248957
|
-
function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
248958
|
-
const router = import_express2.Router({ mergeParams: true });
|
|
248959
|
-
const parseBody = import_express2.json();
|
|
249535
|
+
async function createEntityRoutes(db2, logger, broadcast) {
|
|
249536
|
+
const router = import_express3.Router({ mergeParams: true });
|
|
249537
|
+
const parseBody = import_express3.json();
|
|
248960
249538
|
function withCollection(handler) {
|
|
248961
249539
|
return async (req, res) => {
|
|
248962
249540
|
const collection = db2.getCollection(req.params.entityName);
|
|
@@ -248982,11 +249560,8 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
248982
249560
|
}
|
|
248983
249561
|
broadcast(appId, entityName, createData(data));
|
|
248984
249562
|
}
|
|
248985
|
-
|
|
248986
|
-
|
|
248987
|
-
req.url = req.originalUrl;
|
|
248988
|
-
remoteProxy(req, res, next);
|
|
248989
|
-
});
|
|
249563
|
+
const userRouter = await createUserRouter(db2);
|
|
249564
|
+
router.use("/User", userRouter);
|
|
248990
249565
|
router.get("/:entityName/:id", withCollection(async (req, res, collection) => {
|
|
248991
249566
|
const { entityName, id: id2 } = req.params;
|
|
248992
249567
|
try {
|
|
@@ -249047,8 +249622,14 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249047
249622
|
try {
|
|
249048
249623
|
const now = new Date().toISOString();
|
|
249049
249624
|
const { _id, ...body } = req.body;
|
|
249625
|
+
const filteredBody = db2.prepareRecord(entityName, body);
|
|
249626
|
+
const validation = db2.validate(entityName, filteredBody);
|
|
249627
|
+
if (validation.hasError) {
|
|
249628
|
+
res.status(422).json(validation.error);
|
|
249629
|
+
return;
|
|
249630
|
+
}
|
|
249050
249631
|
const record2 = {
|
|
249051
|
-
...
|
|
249632
|
+
...filteredBody,
|
|
249052
249633
|
id: nanoid3(),
|
|
249053
249634
|
created_date: now,
|
|
249054
249635
|
updated_date: now
|
|
@@ -249069,12 +249650,21 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249069
249650
|
}
|
|
249070
249651
|
try {
|
|
249071
249652
|
const now = new Date().toISOString();
|
|
249072
|
-
const records =
|
|
249073
|
-
|
|
249074
|
-
|
|
249075
|
-
|
|
249076
|
-
|
|
249077
|
-
|
|
249653
|
+
const records = [];
|
|
249654
|
+
for (const record2 of req.body) {
|
|
249655
|
+
const filteredRecord = db2.prepareRecord(entityName, record2);
|
|
249656
|
+
const validation = db2.validate(entityName, filteredRecord);
|
|
249657
|
+
if (validation.hasError) {
|
|
249658
|
+
res.status(422).json(validation.error);
|
|
249659
|
+
return;
|
|
249660
|
+
}
|
|
249661
|
+
records.push({
|
|
249662
|
+
...filteredRecord,
|
|
249663
|
+
id: nanoid3(),
|
|
249664
|
+
created_date: now,
|
|
249665
|
+
updated_date: now
|
|
249666
|
+
});
|
|
249667
|
+
}
|
|
249078
249668
|
const inserted = stripInternalFields(await collection.insertAsync(records));
|
|
249079
249669
|
emit(appId, entityName, "create", inserted);
|
|
249080
249670
|
res.status(201).json(inserted);
|
|
@@ -249087,8 +249677,14 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249087
249677
|
const { appId, entityName, id: id2 } = req.params;
|
|
249088
249678
|
const { id: _id, created_date: _created_date, ...body } = req.body;
|
|
249089
249679
|
try {
|
|
249680
|
+
const filteredBody = db2.prepareRecord(entityName, body, true);
|
|
249681
|
+
const validation = db2.validate(entityName, filteredBody, true);
|
|
249682
|
+
if (validation.hasError) {
|
|
249683
|
+
res.status(422).json(validation.error);
|
|
249684
|
+
return;
|
|
249685
|
+
}
|
|
249090
249686
|
const updateData = {
|
|
249091
|
-
...
|
|
249687
|
+
...filteredBody,
|
|
249092
249688
|
updated_date: new Date().toISOString()
|
|
249093
249689
|
};
|
|
249094
249690
|
const result = await collection.updateAsync({ id: id2 }, { $set: updateData }, { returnUpdatedDocs: true });
|
|
@@ -249137,7 +249733,7 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249137
249733
|
}
|
|
249138
249734
|
|
|
249139
249735
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
249140
|
-
var
|
|
249736
|
+
var import_express4 = __toESM(require_express(), 1);
|
|
249141
249737
|
var import_multer = __toESM(require_multer(), 1);
|
|
249142
249738
|
import { createHash, randomUUID as randomUUID4 } from "node:crypto";
|
|
249143
249739
|
import fs28 from "node:fs";
|
|
@@ -249146,8 +249742,8 @@ function createFileToken(fileUri) {
|
|
|
249146
249742
|
return createHash("sha256").update(fileUri).digest("hex");
|
|
249147
249743
|
}
|
|
249148
249744
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
249149
|
-
const router =
|
|
249150
|
-
const parseBody =
|
|
249745
|
+
const router = import_express4.Router({ mergeParams: true });
|
|
249746
|
+
const parseBody = import_express4.json();
|
|
249151
249747
|
const privateFilesDir = path18.join(mediaFilesDir, "private");
|
|
249152
249748
|
fs28.mkdirSync(mediaFilesDir, { recursive: true });
|
|
249153
249749
|
fs28.mkdirSync(privateFilesDir, { recursive: true });
|
|
@@ -249217,7 +249813,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
249217
249813
|
return router;
|
|
249218
249814
|
}
|
|
249219
249815
|
function createCustomIntegrationRoutes(remoteProxy, logger) {
|
|
249220
|
-
const router =
|
|
249816
|
+
const router = import_express4.Router({ mergeParams: true });
|
|
249221
249817
|
router.post("/:slug/:operationId", (req, res, next) => {
|
|
249222
249818
|
logger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
|
|
249223
249819
|
req.url = req.originalUrl;
|
|
@@ -249226,6 +249822,18 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
|
|
|
249226
249822
|
return router;
|
|
249227
249823
|
}
|
|
249228
249824
|
|
|
249825
|
+
// src/cli/dev/dev-server/routes/users.ts
|
|
249826
|
+
var import_express5 = __toESM(require_express(), 1);
|
|
249827
|
+
function createUsersRoutes() {
|
|
249828
|
+
const router = import_express5.Router({ mergeParams: true });
|
|
249829
|
+
const parseBody = import_express5.json();
|
|
249830
|
+
router.post("/invite-user", parseBody, (req, _res, next) => {
|
|
249831
|
+
console.log("invite-user", req.body);
|
|
249832
|
+
next();
|
|
249833
|
+
});
|
|
249834
|
+
return router;
|
|
249835
|
+
}
|
|
249836
|
+
|
|
249229
249837
|
// src/cli/dev/dev-server/watcher.ts
|
|
249230
249838
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
249231
249839
|
import { relative as relative6 } from "node:path";
|
|
@@ -249958,9 +250566,9 @@ class NodeFsHandler {
|
|
|
249958
250566
|
if (this.fsw.closed) {
|
|
249959
250567
|
return;
|
|
249960
250568
|
}
|
|
249961
|
-
const
|
|
250569
|
+
const dirname13 = sp2.dirname(file2);
|
|
249962
250570
|
const basename5 = sp2.basename(file2);
|
|
249963
|
-
const parent = this.fsw._getWatchedDir(
|
|
250571
|
+
const parent = this.fsw._getWatchedDir(dirname13);
|
|
249964
250572
|
let prevStats = stats;
|
|
249965
250573
|
if (parent.has(basename5))
|
|
249966
250574
|
return;
|
|
@@ -249987,7 +250595,7 @@ class NodeFsHandler {
|
|
|
249987
250595
|
prevStats = newStats2;
|
|
249988
250596
|
}
|
|
249989
250597
|
} catch (error48) {
|
|
249990
|
-
this.fsw._remove(
|
|
250598
|
+
this.fsw._remove(dirname13, basename5);
|
|
249991
250599
|
}
|
|
249992
250600
|
} else if (parent.has(basename5)) {
|
|
249993
250601
|
const at13 = newStats.atimeMs;
|
|
@@ -250930,7 +251538,7 @@ async function createDevServer(options8) {
|
|
|
250930
251538
|
const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
|
|
250931
251539
|
const baseUrl = `http://localhost:${port}`;
|
|
250932
251540
|
const { functions, entities, project: project2 } = await options8.loadResources();
|
|
250933
|
-
const app =
|
|
251541
|
+
const app = import_express6.default();
|
|
250934
251542
|
const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
|
|
250935
251543
|
target: BASE44_APP_URL,
|
|
250936
251544
|
changeOrigin: true
|
|
@@ -250947,7 +251555,17 @@ async function createDevServer(options8) {
|
|
|
250947
251555
|
}
|
|
250948
251556
|
next();
|
|
250949
251557
|
});
|
|
251558
|
+
app.use((req, res, next) => {
|
|
251559
|
+
const auth2 = req.headers.authorization;
|
|
251560
|
+
if (!auth2 || !auth2.startsWith("Bearer ")) {
|
|
251561
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
251562
|
+
return;
|
|
251563
|
+
}
|
|
251564
|
+
next();
|
|
251565
|
+
});
|
|
250950
251566
|
const devLogger = createDevLogger();
|
|
251567
|
+
const usersRoutes = createUsersRoutes();
|
|
251568
|
+
app.use("/api/apps/:appId/users", usersRoutes);
|
|
250951
251569
|
const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
|
|
250952
251570
|
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
250953
251571
|
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
@@ -250960,7 +251578,7 @@ async function createDevServer(options8) {
|
|
|
250960
251578
|
R2.info(`Loaded entities: ${db2.getCollectionNames().join(", ")}`);
|
|
250961
251579
|
}
|
|
250962
251580
|
let emitEntityEvent = () => {};
|
|
250963
|
-
const entityRoutes = createEntityRoutes(db2, devLogger,
|
|
251581
|
+
const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
|
|
250964
251582
|
app.use("/api/apps/:appId/entities", entityRoutes);
|
|
250965
251583
|
const { path: mediaFilesDir } = await $dir();
|
|
250966
251584
|
app.use("/media/private/:fileUri", (req, res, next) => {
|
|
@@ -250981,7 +251599,7 @@ async function createDevServer(options8) {
|
|
|
250981
251599
|
}
|
|
250982
251600
|
next();
|
|
250983
251601
|
});
|
|
250984
|
-
app.use("/media",
|
|
251602
|
+
app.use("/media", import_express6.default.static(mediaFilesDir));
|
|
250985
251603
|
const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
|
|
250986
251604
|
app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
|
|
250987
251605
|
const customIntegrationRoutes = createCustomIntegrationRoutes(remoteProxy, devLogger);
|
|
@@ -251008,8 +251626,8 @@ async function createDevServer(options8) {
|
|
|
251008
251626
|
broadcastEntityEvent(io6, appId, entityName, event);
|
|
251009
251627
|
};
|
|
251010
251628
|
const base44ConfigWatcher = new WatchBase44({
|
|
251011
|
-
functions:
|
|
251012
|
-
entities:
|
|
251629
|
+
functions: join20(dirname14(project2.configPath), project2.functionsDir),
|
|
251630
|
+
entities: join20(dirname14(project2.configPath), project2.entitiesDir)
|
|
251013
251631
|
}, devLogger);
|
|
251014
251632
|
base44ConfigWatcher.on("change", async (name2) => {
|
|
251015
251633
|
try {
|
|
@@ -251179,13 +251797,13 @@ function createProgram(context) {
|
|
|
251179
251797
|
program2.addCommand(getLogoutCommand(context));
|
|
251180
251798
|
program2.addCommand(getCreateCommand(context));
|
|
251181
251799
|
program2.addCommand(getDashboardCommand(context));
|
|
251182
|
-
program2.addCommand(
|
|
251800
|
+
program2.addCommand(getDeployCommand2(context));
|
|
251183
251801
|
program2.addCommand(getLinkCommand(context));
|
|
251184
251802
|
program2.addCommand(getEjectCommand(context));
|
|
251185
251803
|
program2.addCommand(getEntitiesPushCommand(context));
|
|
251186
251804
|
program2.addCommand(getAgentsCommand(context));
|
|
251187
251805
|
program2.addCommand(getConnectorsCommand(context));
|
|
251188
|
-
program2.addCommand(
|
|
251806
|
+
program2.addCommand(getFunctionsCommand(context));
|
|
251189
251807
|
program2.addCommand(getSecretsCommand(context));
|
|
251190
251808
|
program2.addCommand(getSiteCommand(context));
|
|
251191
251809
|
program2.addCommand(getTypesCommand(context));
|
|
@@ -251199,7 +251817,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
251199
251817
|
import { release, type } from "node:os";
|
|
251200
251818
|
|
|
251201
251819
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
251202
|
-
import { dirname as
|
|
251820
|
+
import { dirname as dirname15, posix, sep } from "path";
|
|
251203
251821
|
function createModulerModifier() {
|
|
251204
251822
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
251205
251823
|
return async (frames) => {
|
|
@@ -251208,7 +251826,7 @@ function createModulerModifier() {
|
|
|
251208
251826
|
return frames;
|
|
251209
251827
|
};
|
|
251210
251828
|
}
|
|
251211
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
251829
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname15(process.argv[1]) : process.cwd(), isWindows5 = sep === "\\") {
|
|
251212
251830
|
const normalizedBase = isWindows5 ? normalizeWindowsPath2(basePath) : basePath;
|
|
251213
251831
|
return (filename) => {
|
|
251214
251832
|
if (!filename)
|
|
@@ -255397,9 +256015,9 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
|
|
|
255397
256015
|
});
|
|
255398
256016
|
}
|
|
255399
256017
|
// src/cli/index.ts
|
|
255400
|
-
var __dirname4 =
|
|
256018
|
+
var __dirname4 = dirname16(fileURLToPath6(import.meta.url));
|
|
255401
256019
|
async function runCLI(options8) {
|
|
255402
|
-
ensureNpmAssets(
|
|
256020
|
+
ensureNpmAssets(join21(__dirname4, "../assets"));
|
|
255403
256021
|
const errorReporter = new ErrorReporter;
|
|
255404
256022
|
errorReporter.registerProcessErrorHandlers();
|
|
255405
256023
|
const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
@@ -255432,4 +256050,4 @@ export {
|
|
|
255432
256050
|
CLIExitError
|
|
255433
256051
|
};
|
|
255434
256052
|
|
|
255435
|
-
//# debugId=
|
|
256053
|
+
//# debugId=A178BD03C903D32B64756E2164756E21
|