@base44-preview/cli 0.0.44-pr.412.0c3809e → 0.0.44-pr.412.e4034f6
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 +234 -27
- package/dist/cli/index.js.map +11 -10
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -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(),
|
|
@@ -238473,22 +238473,27 @@ async function deployFunctionsSequentially(functions, options) {
|
|
|
238473
238473
|
}
|
|
238474
238474
|
return results;
|
|
238475
238475
|
}
|
|
238476
|
-
async function pruneRemovedFunctions(localFunctionNames) {
|
|
238476
|
+
async function pruneRemovedFunctions(localFunctionNames, options) {
|
|
238477
238477
|
const remote = await listDeployedFunctions();
|
|
238478
238478
|
const localSet = new Set(localFunctionNames);
|
|
238479
238479
|
const toDelete = remote.functions.filter((f) => !localSet.has(f.name));
|
|
238480
|
+
options?.onStart?.(toDelete.length);
|
|
238480
238481
|
const results = [];
|
|
238481
238482
|
for (const fn of toDelete) {
|
|
238483
|
+
options?.onBeforeDelete?.(fn.name);
|
|
238484
|
+
let result;
|
|
238482
238485
|
try {
|
|
238483
238486
|
await deleteSingleFunction(fn.name);
|
|
238484
|
-
|
|
238487
|
+
result = { name: fn.name, deleted: true };
|
|
238485
238488
|
} catch (error48) {
|
|
238486
|
-
|
|
238489
|
+
result = {
|
|
238487
238490
|
name: fn.name,
|
|
238488
238491
|
deleted: false,
|
|
238489
238492
|
error: error48 instanceof Error ? error48.message : String(error48)
|
|
238490
|
-
}
|
|
238493
|
+
};
|
|
238491
238494
|
}
|
|
238495
|
+
results.push(result);
|
|
238496
|
+
options?.onResult?.(result);
|
|
238492
238497
|
}
|
|
238493
238498
|
return results;
|
|
238494
238499
|
}
|
|
@@ -247822,17 +247827,17 @@ function resolveFunctionsToDeploy(names, allFunctions) {
|
|
|
247822
247827
|
}
|
|
247823
247828
|
return allFunctions.filter((f) => names.includes(f.name));
|
|
247824
247829
|
}
|
|
247825
|
-
function
|
|
247826
|
-
|
|
247827
|
-
|
|
247828
|
-
|
|
247829
|
-
}
|
|
247830
|
-
R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
|
|
247831
|
-
}
|
|
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}`);
|
|
247832
247835
|
}
|
|
247836
|
+
}
|
|
247837
|
+
function formatPruneSummary(pruneResults) {
|
|
247833
247838
|
if (pruneResults.length > 0) {
|
|
247834
247839
|
const pruned = pruneResults.filter((r) => r.deleted).length;
|
|
247835
|
-
R2.info(`${pruned}
|
|
247840
|
+
R2.info(`${pruned} deleted`);
|
|
247836
247841
|
}
|
|
247837
247842
|
}
|
|
247838
247843
|
function buildDeploySummary(results) {
|
|
@@ -247873,10 +247878,23 @@ async function deployFunctionsAction(names, options) {
|
|
|
247873
247878
|
}
|
|
247874
247879
|
});
|
|
247875
247880
|
if (options.force) {
|
|
247876
|
-
R2.info("Removing remote functions not found locally...");
|
|
247877
247881
|
const allLocalNames = functions.map((f) => f.name);
|
|
247878
|
-
|
|
247879
|
-
|
|
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);
|
|
247880
247898
|
}
|
|
247881
247899
|
return { outroMessage: buildDeploySummary(results) };
|
|
247882
247900
|
}
|
|
@@ -247949,7 +247967,7 @@ async function pullFunctionsAction(name2) {
|
|
|
247949
247967
|
};
|
|
247950
247968
|
}
|
|
247951
247969
|
function getPullCommand(context) {
|
|
247952
|
-
return new Command("pull").description("Pull deployed functions from Base44").argument("[name]", "
|
|
247970
|
+
return new Command("pull").description("Pull deployed functions from Base44").argument("[name]", "Function name to pull (pulls all if omitted)").action(async (name2) => {
|
|
247953
247971
|
await runCommand(() => pullFunctionsAction(name2), { requireAuth: true }, context);
|
|
247954
247972
|
});
|
|
247955
247973
|
}
|
|
@@ -249156,14 +249174,163 @@ function createFunctionRouter(manager, logger) {
|
|
|
249156
249174
|
return router;
|
|
249157
249175
|
}
|
|
249158
249176
|
|
|
249159
|
-
// src/cli/dev/dev-server/database.ts
|
|
249177
|
+
// src/cli/dev/dev-server/db/database.ts
|
|
249160
249178
|
var import_nedb = __toESM(require_nedb(), 1);
|
|
249161
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
|
|
249162
249326
|
class Database {
|
|
249163
249327
|
collections = new Map;
|
|
249328
|
+
schemas = new Map;
|
|
249329
|
+
validator = new Validator;
|
|
249164
249330
|
load(entities) {
|
|
249165
249331
|
for (const entity2 of entities) {
|
|
249166
249332
|
this.collections.set(entity2.name, new import_nedb.default);
|
|
249333
|
+
this.schemas.set(entity2.name, entity2);
|
|
249167
249334
|
}
|
|
249168
249335
|
}
|
|
249169
249336
|
getCollection(name2) {
|
|
@@ -249177,6 +249344,25 @@ class Database {
|
|
|
249177
249344
|
collection.remove({}, { multi: true });
|
|
249178
249345
|
}
|
|
249179
249346
|
this.collections.clear();
|
|
249347
|
+
this.schemas.clear();
|
|
249348
|
+
}
|
|
249349
|
+
validate(entityName, record2, partial2 = false) {
|
|
249350
|
+
const schema9 = this.schemas.get(entityName);
|
|
249351
|
+
if (!schema9) {
|
|
249352
|
+
throw new Error(`Entity "${entityName}" not found`);
|
|
249353
|
+
}
|
|
249354
|
+
return this.validator.validate(record2, schema9, partial2);
|
|
249355
|
+
}
|
|
249356
|
+
prepareRecord(entityName, record2, partial2 = false) {
|
|
249357
|
+
const schema9 = this.schemas.get(entityName);
|
|
249358
|
+
if (!schema9) {
|
|
249359
|
+
throw new Error(`Entity "${entityName}" not found`);
|
|
249360
|
+
}
|
|
249361
|
+
const filteredRecord = this.validator.filterFields(record2, schema9);
|
|
249362
|
+
if (partial2) {
|
|
249363
|
+
return filteredRecord;
|
|
249364
|
+
}
|
|
249365
|
+
return this.validator.applyDefaults(filteredRecord, schema9);
|
|
249180
249366
|
}
|
|
249181
249367
|
}
|
|
249182
249368
|
|
|
@@ -249368,8 +249554,14 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249368
249554
|
try {
|
|
249369
249555
|
const now = new Date().toISOString();
|
|
249370
249556
|
const { _id, ...body } = req.body;
|
|
249557
|
+
const filteredBody = db2.prepareRecord(entityName, body);
|
|
249558
|
+
const validation = db2.validate(entityName, filteredBody);
|
|
249559
|
+
if (validation.hasError) {
|
|
249560
|
+
res.status(422).json(validation.error);
|
|
249561
|
+
return;
|
|
249562
|
+
}
|
|
249371
249563
|
const record2 = {
|
|
249372
|
-
...
|
|
249564
|
+
...filteredBody,
|
|
249373
249565
|
id: nanoid3(),
|
|
249374
249566
|
created_date: now,
|
|
249375
249567
|
updated_date: now
|
|
@@ -249390,12 +249582,21 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249390
249582
|
}
|
|
249391
249583
|
try {
|
|
249392
249584
|
const now = new Date().toISOString();
|
|
249393
|
-
const records =
|
|
249394
|
-
|
|
249395
|
-
|
|
249396
|
-
|
|
249397
|
-
|
|
249398
|
-
|
|
249585
|
+
const records = [];
|
|
249586
|
+
for (const record2 of req.body) {
|
|
249587
|
+
const filteredRecord = db2.prepareRecord(entityName, record2);
|
|
249588
|
+
const validation = db2.validate(entityName, filteredRecord);
|
|
249589
|
+
if (validation.hasError) {
|
|
249590
|
+
res.status(422).json(validation.error);
|
|
249591
|
+
return;
|
|
249592
|
+
}
|
|
249593
|
+
records.push({
|
|
249594
|
+
...filteredRecord,
|
|
249595
|
+
id: nanoid3(),
|
|
249596
|
+
created_date: now,
|
|
249597
|
+
updated_date: now
|
|
249598
|
+
});
|
|
249599
|
+
}
|
|
249399
249600
|
const inserted = stripInternalFields(await collection.insertAsync(records));
|
|
249400
249601
|
emit(appId, entityName, "create", inserted);
|
|
249401
249602
|
res.status(201).json(inserted);
|
|
@@ -249408,8 +249609,14 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
|
|
|
249408
249609
|
const { appId, entityName, id: id2 } = req.params;
|
|
249409
249610
|
const { id: _id, created_date: _created_date, ...body } = req.body;
|
|
249410
249611
|
try {
|
|
249612
|
+
const filteredBody = db2.prepareRecord(entityName, body, true);
|
|
249613
|
+
const validation = db2.validate(entityName, filteredBody, true);
|
|
249614
|
+
if (validation.hasError) {
|
|
249615
|
+
res.status(422).json(validation.error);
|
|
249616
|
+
return;
|
|
249617
|
+
}
|
|
249411
249618
|
const updateData = {
|
|
249412
|
-
...
|
|
249619
|
+
...filteredBody,
|
|
249413
249620
|
updated_date: new Date().toISOString()
|
|
249414
249621
|
};
|
|
249415
249622
|
const result = await collection.updateAsync({ id: id2 }, { $set: updateData }, { returnUpdatedDocs: true });
|
|
@@ -255753,4 +255960,4 @@ export {
|
|
|
255753
255960
|
CLIExitError
|
|
255754
255961
|
};
|
|
255755
255962
|
|
|
255756
|
-
//# debugId=
|
|
255963
|
+
//# debugId=CD060DA1B6F7116364756E2164756E21
|