@base44-preview/cli 0.0.44-pr.419.4194a5c → 0.0.45-pr.406.ed52e60

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/README.md CHANGED
@@ -53,14 +53,10 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
53
53
  | [`whoami`](https://docs.base44.com/developers/references/cli/commands/whoami) | Display the current authenticated user |
54
54
  | [`agents pull`](https://docs.base44.com/developers/references/cli/commands/agents-pull) | Pull agents from Base44 to local files |
55
55
  | [`agents push`](https://docs.base44.com/developers/references/cli/commands/agents-push) | Push local agents to Base44 |
56
- | [`connectors list-available`](https://docs.base44.com/developers/references/cli/commands/connectors-list-available) | List all available integration types |
57
56
  | [`connectors pull`](https://docs.base44.com/developers/references/cli/commands/connectors-pull) | Pull connectors from Base44 to local files |
58
57
  | [`connectors push`](https://docs.base44.com/developers/references/cli/commands/connectors-push) | Push local connectors to Base44 |
59
58
  | [`entities push`](https://docs.base44.com/developers/references/cli/commands/entities-push) | Push local entities to Base44 |
60
- | `functions delete` | Delete deployed functions |
61
- | [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy functions to Base44 |
62
- | `functions list` | List all deployed functions |
63
- | `functions pull` | Pull deployed functions from Base44 |
59
+ | [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy local functions to Base44 |
64
60
  | [`secrets list`](https://docs.base44.com/developers/references/cli/commands/secrets-list) | List project secret names |
65
61
  | [`secrets set`](https://docs.base44.com/developers/references/cli/commands/secrets-set) | Set one or more project secrets |
66
62
  | [`secrets delete`](https://docs.base44.com/developers/references/cli/commands/secrets-delete) | Delete a project secret |
package/dist/cli/index.js CHANGED
@@ -179494,19 +179494,19 @@ var require_base64id = __commonJS((exports, module) => {
179494
179494
  /*!
179495
179495
  * base64id v0.1.0
179496
179496
  */
179497
- var crypto = __require("crypto");
179497
+ var crypto2 = __require("crypto");
179498
179498
  var Base64Id = function() {};
179499
179499
  Base64Id.prototype.getRandomBytes = function(bytes) {
179500
179500
  var BUFFER_SIZE = 4096;
179501
179501
  var self2 = this;
179502
179502
  bytes = bytes || 12;
179503
179503
  if (bytes > BUFFER_SIZE) {
179504
- return crypto.randomBytes(bytes);
179504
+ return crypto2.randomBytes(bytes);
179505
179505
  }
179506
179506
  var bytesInBuffer = parseInt(BUFFER_SIZE / bytes);
179507
179507
  var threshold = parseInt(bytesInBuffer * 0.85);
179508
179508
  if (!threshold) {
179509
- return crypto.randomBytes(bytes);
179509
+ return crypto2.randomBytes(bytes);
179510
179510
  }
179511
179511
  if (this.bytesBufferIndex == null) {
179512
179512
  this.bytesBufferIndex = -1;
@@ -179518,14 +179518,14 @@ var require_base64id = __commonJS((exports, module) => {
179518
179518
  if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) {
179519
179519
  if (!this.isGeneratingBytes) {
179520
179520
  this.isGeneratingBytes = true;
179521
- crypto.randomBytes(BUFFER_SIZE, function(err, bytes2) {
179521
+ crypto2.randomBytes(BUFFER_SIZE, function(err, bytes2) {
179522
179522
  self2.bytesBuffer = bytes2;
179523
179523
  self2.bytesBufferIndex = 0;
179524
179524
  self2.isGeneratingBytes = false;
179525
179525
  });
179526
179526
  }
179527
179527
  if (this.bytesBufferIndex == -1) {
179528
- return crypto.randomBytes(bytes);
179528
+ return crypto2.randomBytes(bytes);
179529
179529
  }
179530
179530
  }
179531
179531
  var result = this.bytesBuffer.slice(bytes * this.bytesBufferIndex, bytes * (this.bytesBufferIndex + 1));
@@ -179539,7 +179539,7 @@ var require_base64id = __commonJS((exports, module) => {
179539
179539
  }
179540
179540
  this.sequenceNumber = this.sequenceNumber + 1 | 0;
179541
179541
  rand.writeInt32BE(this.sequenceNumber, 11);
179542
- if (crypto.randomBytes) {
179542
+ if (crypto2.randomBytes) {
179543
179543
  this.getRandomBytes(12).copy(rand);
179544
179544
  } else {
179545
179545
  [0, 4, 8].forEach(function(i5) {
@@ -238710,7 +238710,7 @@ import { join as join8 } from "node:path";
238710
238710
  // package.json
238711
238711
  var package_default = {
238712
238712
  name: "base44",
238713
- version: "0.0.44",
238713
+ version: "0.0.45",
238714
238714
  description: "Base44 CLI - Unified interface for managing Base44 applications",
238715
238715
  type: "module",
238716
238716
  bin: {
@@ -248819,7 +248819,7 @@ function getTypesCommand(context) {
248819
248819
  // src/cli/dev/dev-server/main.ts
248820
248820
  import { dirname as dirname14, join as join20 } from "node:path";
248821
248821
  var import_cors = __toESM(require_lib4(), 1);
248822
- var import_express4 = __toESM(require_express(), 1);
248822
+ var import_express6 = __toESM(require_express(), 1);
248823
248823
 
248824
248824
  // ../../node_modules/get-port/index.js
248825
248825
  import net from "node:net";
@@ -249177,6 +249177,36 @@ function createFunctionRouter(manager, logger) {
249177
249177
  // src/cli/dev/dev-server/db/database.ts
249178
249178
  var import_nedb = __toESM(require_nedb(), 1);
249179
249179
 
249180
+ // ../../node_modules/nanoid/index.js
249181
+ import { webcrypto as crypto } from "node:crypto";
249182
+
249183
+ // ../../node_modules/nanoid/url-alphabet/index.js
249184
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
249185
+
249186
+ // ../../node_modules/nanoid/index.js
249187
+ var POOL_SIZE_MULTIPLIER = 128;
249188
+ var pool;
249189
+ var poolOffset;
249190
+ function fillPool(bytes) {
249191
+ if (!pool || pool.length < bytes) {
249192
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
249193
+ crypto.getRandomValues(pool);
249194
+ poolOffset = 0;
249195
+ } else if (poolOffset + bytes > pool.length) {
249196
+ crypto.getRandomValues(pool);
249197
+ poolOffset = 0;
249198
+ }
249199
+ poolOffset += bytes;
249200
+ }
249201
+ function nanoid3(size = 21) {
249202
+ fillPool(size |= 0);
249203
+ let id2 = "";
249204
+ for (let i5 = poolOffset - size;i5 < poolOffset; i5++) {
249205
+ id2 += urlAlphabet[pool[i5] & 63];
249206
+ }
249207
+ return id2;
249208
+ }
249209
+
249180
249210
  // src/cli/dev/dev-server/db/validator.ts
249181
249211
  var fieldTypes = [
249182
249212
  "string",
@@ -249323,18 +249353,63 @@ class Validator {
249323
249353
  }
249324
249354
 
249325
249355
  // src/cli/dev/dev-server/db/database.ts
249356
+ var USER_COLLECTION = "user";
249357
+
249326
249358
  class Database {
249327
249359
  collections = new Map;
249328
249360
  schemas = new Map;
249329
249361
  validator = new Validator;
249330
- load(entities) {
249362
+ async load(entities) {
249363
+ const userDataStore = new import_nedb.default;
249364
+ this.collections.set(USER_COLLECTION, userDataStore);
249365
+ const userInfo = await readAuth();
249366
+ const now = new Date().toISOString().replace("Z", "000");
249367
+ await userDataStore.insertAsync({
249368
+ id: nanoid3(),
249369
+ email: userInfo.email,
249370
+ full_name: userInfo.name,
249371
+ is_service: false,
249372
+ is_verified: true,
249373
+ disabled: null,
249374
+ role: "admin",
249375
+ collaborator_role: "editor",
249376
+ created_date: now,
249377
+ updated_date: now
249378
+ });
249331
249379
  for (const entity2 of entities) {
249332
- this.collections.set(entity2.name, new import_nedb.default);
249333
- this.schemas.set(entity2.name, entity2);
249380
+ const entityName = this.normalizeName(entity2.name);
249381
+ const clonedEntity = structuredClone(entity2);
249382
+ if (entityName === USER_COLLECTION) {
249383
+ ["full_name", "email"].forEach((predefinedField) => {
249384
+ if (predefinedField in clonedEntity.properties) {
249385
+ 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.`);
249386
+ }
249387
+ });
249388
+ clonedEntity.properties.full_name = { type: "string" };
249389
+ clonedEntity.properties.email = { type: "string" };
249390
+ clonedEntity.properties.role = { type: "string" };
249391
+ } else {
249392
+ this.collections.set(entityName, new import_nedb.default);
249393
+ }
249394
+ this.schemas.set(entityName, clonedEntity);
249334
249395
  }
249396
+ if (!this.schemas.has(USER_COLLECTION)) {
249397
+ this.schemas.set(USER_COLLECTION, {
249398
+ name: "User",
249399
+ type: "object",
249400
+ properties: {
249401
+ full_name: { type: "string" },
249402
+ email: { type: "string" },
249403
+ role: { type: "string" }
249404
+ }
249405
+ });
249406
+ }
249407
+ }
249408
+ hasCollection(name2) {
249409
+ return this.collections.has(this.normalizeName(name2));
249335
249410
  }
249336
249411
  getCollection(name2) {
249337
- return this.collections.get(name2);
249412
+ return this.collections.get(this.normalizeName(name2));
249338
249413
  }
249339
249414
  getCollectionNames() {
249340
249415
  return Array.from(this.collections.keys());
@@ -249347,14 +249422,14 @@ class Database {
249347
249422
  this.schemas.clear();
249348
249423
  }
249349
249424
  validate(entityName, record2, partial2 = false) {
249350
- const schema9 = this.schemas.get(entityName);
249425
+ const schema9 = this.schemas.get(this.normalizeName(entityName));
249351
249426
  if (!schema9) {
249352
249427
  throw new Error(`Entity "${entityName}" not found`);
249353
249428
  }
249354
249429
  return this.validator.validate(record2, schema9, partial2);
249355
249430
  }
249356
249431
  prepareRecord(entityName, record2, partial2 = false) {
249357
- const schema9 = this.schemas.get(entityName);
249432
+ const schema9 = this.schemas.get(this.normalizeName(entityName));
249358
249433
  if (!schema9) {
249359
249434
  throw new Error(`Entity "${entityName}" not found`);
249360
249435
  }
@@ -249364,6 +249439,9 @@ class Database {
249364
249439
  }
249365
249440
  return this.validator.applyDefaults(filteredRecord, schema9);
249366
249441
  }
249442
+ normalizeName(entityName) {
249443
+ return entityName.toLowerCase();
249444
+ }
249367
249445
  }
249368
249446
 
249369
249447
  // ../../node_modules/socket.io/wrapper.mjs
@@ -249398,40 +249476,42 @@ function broadcastEntityEvent(io6, appId, entityName, event) {
249398
249476
  });
249399
249477
  }
249400
249478
 
249401
- // src/cli/dev/dev-server/routes/entities.ts
249402
- var import_express2 = __toESM(require_express(), 1);
249403
-
249404
- // ../../node_modules/nanoid/index.js
249405
- import { webcrypto as crypto } from "node:crypto";
249479
+ // src/cli/dev/dev-server/routes/entities/entities-router.ts
249480
+ var import_express3 = __toESM(require_express(), 1);
249406
249481
 
249407
- // ../../node_modules/nanoid/url-alphabet/index.js
249408
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
249482
+ // src/cli/dev/dev-server/routes/entities/entities-user-router.ts
249483
+ var import_express2 = __toESM(require_express(), 1);
249409
249484
 
249410
- // ../../node_modules/nanoid/index.js
249411
- var POOL_SIZE_MULTIPLIER = 128;
249412
- var pool;
249413
- var poolOffset;
249414
- function fillPool(bytes) {
249415
- if (!pool || pool.length < bytes) {
249416
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
249417
- crypto.getRandomValues(pool);
249418
- poolOffset = 0;
249419
- } else if (poolOffset + bytes > pool.length) {
249420
- crypto.getRandomValues(pool);
249421
- poolOffset = 0;
249485
+ // src/cli/dev/dev-server/routes/entities/utils.ts
249486
+ function stripInternalFields(doc2) {
249487
+ if (Array.isArray(doc2)) {
249488
+ return doc2.map((d5) => stripInternalFields(d5));
249422
249489
  }
249423
- poolOffset += bytes;
249490
+ const { _id, ...rest } = doc2;
249491
+ return rest;
249424
249492
  }
249425
- function nanoid3(size = 21) {
249426
- fillPool(size |= 0);
249427
- let id2 = "";
249428
- for (let i5 = poolOffset - size;i5 < poolOffset; i5++) {
249429
- id2 += urlAlphabet[pool[i5] & 63];
249430
- }
249431
- return id2;
249493
+
249494
+ // src/cli/dev/dev-server/routes/entities/entities-user-router.ts
249495
+ async function createUserRouter(db2) {
249496
+ const router = import_express2.Router({ mergeParams: true });
249497
+ router.get("/:id", async (req, res) => {
249498
+ let result;
249499
+ if (req.params.id === "me") {
249500
+ const userInfo = await readAuth();
249501
+ result = await db2.getCollection("User")?.findOneAsync({ email: userInfo.email });
249502
+ } else {
249503
+ result = await db2.getCollection("User")?.findOneAsync({ id: req.params.id });
249504
+ }
249505
+ if (!result) {
249506
+ res.status(404).json({ error: `User with id "${req.params.id}" not found` });
249507
+ return;
249508
+ }
249509
+ res.json(stripInternalFields(result));
249510
+ });
249511
+ return router;
249432
249512
  }
249433
249513
 
249434
- // src/cli/dev/dev-server/routes/entities.ts
249514
+ // src/cli/dev/dev-server/routes/entities/entities-router.ts
249435
249515
  function parseSort(sort) {
249436
249516
  if (!sort) {
249437
249517
  return;
@@ -249454,16 +249534,9 @@ function parseFields(fields) {
249454
249534
  }
249455
249535
  return Object.keys(projection).length > 0 ? projection : undefined;
249456
249536
  }
249457
- function stripInternalFields(doc2) {
249458
- if (Array.isArray(doc2)) {
249459
- return doc2.map((d5) => stripInternalFields(d5));
249460
- }
249461
- const { _id, ...rest } = doc2;
249462
- return rest;
249463
- }
249464
- function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
249465
- const router = import_express2.Router({ mergeParams: true });
249466
- const parseBody = import_express2.json();
249537
+ async function createEntityRoutes(db2, logger, broadcast) {
249538
+ const router = import_express3.Router({ mergeParams: true });
249539
+ const parseBody = import_express3.json();
249467
249540
  function withCollection(handler) {
249468
249541
  return async (req, res) => {
249469
249542
  const collection = db2.getCollection(req.params.entityName);
@@ -249489,11 +249562,8 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
249489
249562
  }
249490
249563
  broadcast(appId, entityName, createData(data));
249491
249564
  }
249492
- router.get("/User/:id", (req, res, next) => {
249493
- logger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
249494
- req.url = req.originalUrl;
249495
- remoteProxy(req, res, next);
249496
- });
249565
+ const userRouter = await createUserRouter(db2);
249566
+ router.use("/User", userRouter);
249497
249567
  router.get("/:entityName/:id", withCollection(async (req, res, collection) => {
249498
249568
  const { entityName, id: id2 } = req.params;
249499
249569
  try {
@@ -249665,7 +249735,7 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
249665
249735
  }
249666
249736
 
249667
249737
  // src/cli/dev/dev-server/routes/integrations.ts
249668
- var import_express3 = __toESM(require_express(), 1);
249738
+ var import_express4 = __toESM(require_express(), 1);
249669
249739
  var import_multer = __toESM(require_multer(), 1);
249670
249740
  import { createHash, randomUUID as randomUUID4 } from "node:crypto";
249671
249741
  import fs28 from "node:fs";
@@ -249674,8 +249744,8 @@ function createFileToken(fileUri) {
249674
249744
  return createHash("sha256").update(fileUri).digest("hex");
249675
249745
  }
249676
249746
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
249677
- const router = import_express3.Router({ mergeParams: true });
249678
- const parseBody = import_express3.json();
249747
+ const router = import_express4.Router({ mergeParams: true });
249748
+ const parseBody = import_express4.json();
249679
249749
  const privateFilesDir = path18.join(mediaFilesDir, "private");
249680
249750
  fs28.mkdirSync(mediaFilesDir, { recursive: true });
249681
249751
  fs28.mkdirSync(privateFilesDir, { recursive: true });
@@ -249745,7 +249815,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
249745
249815
  return router;
249746
249816
  }
249747
249817
  function createCustomIntegrationRoutes(remoteProxy, logger) {
249748
- const router = import_express3.Router({ mergeParams: true });
249818
+ const router = import_express4.Router({ mergeParams: true });
249749
249819
  router.post("/:slug/:operationId", (req, res, next) => {
249750
249820
  logger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
249751
249821
  req.url = req.originalUrl;
@@ -249754,6 +249824,18 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
249754
249824
  return router;
249755
249825
  }
249756
249826
 
249827
+ // src/cli/dev/dev-server/routes/users.ts
249828
+ var import_express5 = __toESM(require_express(), 1);
249829
+ function createUsersRoutes() {
249830
+ const router = import_express5.Router({ mergeParams: true });
249831
+ const parseBody = import_express5.json();
249832
+ router.post("/invite-user", parseBody, (req, _res, next) => {
249833
+ console.log("invite-user", req.body);
249834
+ next();
249835
+ });
249836
+ return router;
249837
+ }
249838
+
249757
249839
  // src/cli/dev/dev-server/watcher.ts
249758
249840
  import { EventEmitter as EventEmitter4 } from "node:events";
249759
249841
  import { relative as relative6 } from "node:path";
@@ -251458,7 +251540,7 @@ async function createDevServer(options8) {
251458
251540
  const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
251459
251541
  const baseUrl = `http://localhost:${port}`;
251460
251542
  const { functions, entities, project: project2 } = await options8.loadResources();
251461
- const app = import_express4.default();
251543
+ const app = import_express6.default();
251462
251544
  const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
251463
251545
  target: BASE44_APP_URL,
251464
251546
  changeOrigin: true
@@ -251475,7 +251557,17 @@ async function createDevServer(options8) {
251475
251557
  }
251476
251558
  next();
251477
251559
  });
251560
+ app.use((req, res, next) => {
251561
+ const auth2 = req.headers.authorization;
251562
+ if (!auth2 || !auth2.startsWith("Bearer ")) {
251563
+ res.status(401).json({ error: "Unauthorized" });
251564
+ return;
251565
+ }
251566
+ next();
251567
+ });
251478
251568
  const devLogger = createDevLogger();
251569
+ const usersRoutes = createUsersRoutes();
251570
+ app.use("/api/apps/:appId/users", usersRoutes);
251479
251571
  const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
251480
251572
  const functionRoutes = createFunctionRouter(functionManager, devLogger);
251481
251573
  app.use("/api/apps/:appId/functions", functionRoutes);
@@ -251483,12 +251575,12 @@ async function createDevServer(options8) {
251483
251575
  R2.info(`Loaded functions: ${functionManager.getFunctionNames().join(", ")}`);
251484
251576
  }
251485
251577
  const db2 = new Database;
251486
- db2.load(entities);
251578
+ await db2.load(entities);
251487
251579
  if (db2.getCollectionNames().length > 0) {
251488
251580
  R2.info(`Loaded entities: ${db2.getCollectionNames().join(", ")}`);
251489
251581
  }
251490
251582
  let emitEntityEvent = () => {};
251491
- const entityRoutes = createEntityRoutes(db2, devLogger, remoteProxy, (...args) => emitEntityEvent(...args));
251583
+ const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
251492
251584
  app.use("/api/apps/:appId/entities", entityRoutes);
251493
251585
  const { path: mediaFilesDir } = await $dir();
251494
251586
  app.use("/media/private/:fileUri", (req, res, next) => {
@@ -251509,7 +251601,7 @@ async function createDevServer(options8) {
251509
251601
  }
251510
251602
  next();
251511
251603
  });
251512
- app.use("/media", import_express4.default.static(mediaFilesDir));
251604
+ app.use("/media", import_express6.default.static(mediaFilesDir));
251513
251605
  const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
251514
251606
  app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
251515
251607
  const customIntegrationRoutes = createCustomIntegrationRoutes(remoteProxy, devLogger);
@@ -251558,7 +251650,7 @@ async function createDevServer(options8) {
251558
251650
  if (previousEntityCount > 0) {
251559
251651
  devLogger.log("Entities directory changed, clearing data...");
251560
251652
  }
251561
- db2.load(entities2);
251653
+ await db2.load(entities2);
251562
251654
  if (db2.getCollectionNames().length > 0) {
251563
251655
  devLogger.log(`Loaded entities: ${db2.getCollectionNames().join(", ")}`);
251564
251656
  }
@@ -255960,4 +256052,4 @@ export {
255960
256052
  CLIExitError
255961
256053
  };
255962
256054
 
255963
- //# debugId=CD060DA1B6F7116364756E2164756E21
256055
+ //# debugId=1D8798AB57E4532E64756E2164756E21