@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 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().optional(),
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
- results.push({ name: fn.name, deleted: true });
238487
+ result = { name: fn.name, deleted: true };
238485
238488
  } catch (error48) {
238486
- results.push({
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 formatPruneResults(pruneResults) {
247826
- for (const pruneResult of pruneResults) {
247827
- if (pruneResult.deleted) {
247828
- R2.success(`${pruneResult.name.padEnd(25)} deleted`);
247829
- } else {
247830
- R2.error(`${pruneResult.name.padEnd(25)} error: ${pruneResult.error}`);
247831
- }
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} function${pruned !== 1 ? "s" : ""} removed`);
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
- const pruneResults = await pruneRemovedFunctions(allLocalNames);
247879
- formatPruneResults(pruneResults);
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]", "Pull a single function by name").action(async (name2) => {
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
- ...body,
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 = req.body.map((item) => ({
249394
- ...item,
249395
- id: nanoid3(),
249396
- created_date: now,
249397
- updated_date: now
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
- ...body,
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=8533D2C01A675ED464756E2164756E21
255963
+ //# debugId=CD060DA1B6F7116364756E2164756E21