@base44-preview/cli 0.0.45-pr.406.7acd6ec → 0.0.45-pr.419.e270ff0

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,10 +53,14 @@ 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 |
56
57
  | [`connectors pull`](https://docs.base44.com/developers/references/cli/commands/connectors-pull) | Pull connectors from Base44 to local files |
57
58
  | [`connectors push`](https://docs.base44.com/developers/references/cli/commands/connectors-push) | Push local connectors to Base44 |
58
59
  | [`entities push`](https://docs.base44.com/developers/references/cli/commands/entities-push) | Push local entities to Base44 |
59
- | [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy local functions 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 |
60
64
  | [`secrets list`](https://docs.base44.com/developers/references/cli/commands/secrets-list) | List project secret names |
61
65
  | [`secrets set`](https://docs.base44.com/developers/references/cli/commands/secrets-set) | Set one or more project secrets |
62
66
  | [`secrets delete`](https://docs.base44.com/developers/references/cli/commands/secrets-delete) | Delete a project secret |
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Deno Function Wrapper
3
+ *
4
+ * This script is executed by Deno to run user functions.
5
+ * It patches Deno.serve to inject a dynamic port before importing the user's function.
6
+ *
7
+ * Environment variables:
8
+ * - FUNCTION_PATH: Absolute path to the user's function entry file
9
+ * - FUNCTION_PORT: Port number for the function to listen on
10
+ * - FUNCTION_NAME: Name of the function (for logging)
11
+ */
12
+
13
+ // Make this file a module for top-level await support
14
+ export {};
15
+
16
+ const functionPath = Deno.env.get("FUNCTION_PATH");
17
+ const port = parseInt(Deno.env.get("FUNCTION_PORT") || "8000", 10);
18
+ const functionName = Deno.env.get("FUNCTION_NAME") || "unknown";
19
+
20
+ if (!functionPath) {
21
+ console.error("[wrapper] FUNCTION_PATH environment variable is required");
22
+ Deno.exit(1);
23
+ }
24
+
25
+ // Store the original Deno.serve
26
+ const originalServe = Deno.serve.bind(Deno);
27
+
28
+ // Patch Deno.serve to inject our port and add onListen callback
29
+ // @ts-expect-error - We're intentionally overriding Deno.serve
30
+ Deno.serve = (
31
+ optionsOrHandler:
32
+ | Deno.ServeOptions
33
+ | Deno.ServeHandler
34
+ | (Deno.ServeOptions & { handler: Deno.ServeHandler }),
35
+ maybeHandler?: Deno.ServeHandler,
36
+ ): Deno.HttpServer<Deno.NetAddr> => {
37
+ const onListen = () => {
38
+ // This message is used by FunctionManager to detect when the function is ready
39
+ console.log(`[${functionName}] Listening on http://localhost:${port}`);
40
+ };
41
+
42
+ // Handle the different Deno.serve signatures:
43
+ // 1. Deno.serve(handler)
44
+ // 2. Deno.serve(options, handler)
45
+ // 3. Deno.serve({ ...options, handler })
46
+ if (typeof optionsOrHandler === "function") {
47
+ // Signature: Deno.serve(handler)
48
+ return originalServe({ port, onListen }, optionsOrHandler);
49
+ }
50
+
51
+ if (maybeHandler) {
52
+ // Signature: Deno.serve(options, handler)
53
+ return originalServe({ ...optionsOrHandler, port, onListen }, maybeHandler);
54
+ }
55
+
56
+ // Signature: Deno.serve({ ...options, handler })
57
+ const options = optionsOrHandler as Deno.ServeOptions & {
58
+ handler: Deno.ServeHandler;
59
+ };
60
+ return originalServe({ ...options, port, onListen });
61
+ };
62
+
63
+ console.log(`[${functionName}] Starting function from ${functionPath}`);
64
+
65
+ // Dynamically import the user's function
66
+ // The function will call Deno.serve which is now patched to use our port
67
+ try {
68
+ await import(functionPath);
69
+ } catch (error) {
70
+ console.error(`[${functionName}] Failed to load function:`, error);
71
+ Deno.exit(1);
72
+ }
package/dist/cli/index.js CHANGED
@@ -238807,7 +238807,7 @@ function getTemplatesIndexPath() {
238807
238807
  return join8(ASSETS_DIR, "templates", "templates.json");
238808
238808
  }
238809
238809
  function getDenoWrapperPath() {
238810
- return join8(ASSETS_DIR, "deno-runtime", "main.js");
238810
+ return join8(ASSETS_DIR, "deno-runtime", "main.ts");
238811
238811
  }
238812
238812
  function ensureNpmAssets(sourceDir) {
238813
238813
  if (existsSync(ASSETS_DIR))
@@ -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_express6 = __toESM(require_express(), 1);
248822
+ var import_express4 = __toESM(require_express(), 1);
248823
248823
 
248824
248824
  // ../../node_modules/get-port/index.js
248825
248825
  import net from "node:net";
@@ -249323,47 +249323,18 @@ class Validator {
249323
249323
  }
249324
249324
 
249325
249325
  // src/cli/dev/dev-server/db/database.ts
249326
- var USER_COLLECTION = "user";
249327
-
249328
249326
  class Database {
249329
249327
  collections = new Map;
249330
249328
  schemas = new Map;
249331
249329
  validator = new Validator;
249332
249330
  load(entities) {
249333
- this.collections.set(USER_COLLECTION, new import_nedb.default);
249334
249331
  for (const entity2 of entities) {
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
- });
249332
+ this.collections.set(entity2.name, new import_nedb.default);
249333
+ this.schemas.set(entity2.name, entity2);
249360
249334
  }
249361
249335
  }
249362
- hasCollection(name2) {
249363
- return this.collections.has(this.normalizeName(name2));
249364
- }
249365
249336
  getCollection(name2) {
249366
- return this.collections.get(this.normalizeName(name2));
249337
+ return this.collections.get(name2);
249367
249338
  }
249368
249339
  getCollectionNames() {
249369
249340
  return Array.from(this.collections.keys());
@@ -249376,14 +249347,14 @@ class Database {
249376
249347
  this.schemas.clear();
249377
249348
  }
249378
249349
  validate(entityName, record2, partial2 = false) {
249379
- const schema9 = this.schemas.get(this.normalizeName(entityName));
249350
+ const schema9 = this.schemas.get(entityName);
249380
249351
  if (!schema9) {
249381
249352
  throw new Error(`Entity "${entityName}" not found`);
249382
249353
  }
249383
249354
  return this.validator.validate(record2, schema9, partial2);
249384
249355
  }
249385
249356
  prepareRecord(entityName, record2, partial2 = false) {
249386
- const schema9 = this.schemas.get(this.normalizeName(entityName));
249357
+ const schema9 = this.schemas.get(entityName);
249387
249358
  if (!schema9) {
249388
249359
  throw new Error(`Entity "${entityName}" not found`);
249389
249360
  }
@@ -249393,9 +249364,6 @@ class Database {
249393
249364
  }
249394
249365
  return this.validator.applyDefaults(filteredRecord, schema9);
249395
249366
  }
249396
- normalizeName(entityName) {
249397
- return entityName.toLowerCase();
249398
- }
249399
249367
  }
249400
249368
 
249401
249369
  // ../../node_modules/socket.io/wrapper.mjs
@@ -249430,8 +249398,8 @@ function broadcastEntityEvent(io6, appId, entityName, event) {
249430
249398
  });
249431
249399
  }
249432
249400
 
249433
- // src/cli/dev/dev-server/routes/entities/entities-router.ts
249434
- var import_express3 = __toESM(require_express(), 1);
249401
+ // src/cli/dev/dev-server/routes/entities.ts
249402
+ var import_express2 = __toESM(require_express(), 1);
249435
249403
 
249436
249404
  // ../../node_modules/nanoid/index.js
249437
249405
  import { webcrypto as crypto } from "node:crypto";
@@ -249463,53 +249431,7 @@ function nanoid3(size = 21) {
249463
249431
  return id2;
249464
249432
  }
249465
249433
 
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
249434
+ // src/cli/dev/dev-server/routes/entities.ts
249513
249435
  function parseSort(sort) {
249514
249436
  if (!sort) {
249515
249437
  return;
@@ -249532,9 +249454,16 @@ function parseFields(fields) {
249532
249454
  }
249533
249455
  return Object.keys(projection).length > 0 ? projection : undefined;
249534
249456
  }
249535
- async function createEntityRoutes(db2, logger, broadcast) {
249536
- const router = import_express3.Router({ mergeParams: true });
249537
- const parseBody = import_express3.json();
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();
249538
249467
  function withCollection(handler) {
249539
249468
  return async (req, res) => {
249540
249469
  const collection = db2.getCollection(req.params.entityName);
@@ -249560,8 +249489,11 @@ async function createEntityRoutes(db2, logger, broadcast) {
249560
249489
  }
249561
249490
  broadcast(appId, entityName, createData(data));
249562
249491
  }
249563
- const userRouter = await createUserRouter(db2);
249564
- router.use("/User", userRouter);
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
249497
  router.get("/:entityName/:id", withCollection(async (req, res, collection) => {
249566
249498
  const { entityName, id: id2 } = req.params;
249567
249499
  try {
@@ -249733,7 +249665,7 @@ async function createEntityRoutes(db2, logger, broadcast) {
249733
249665
  }
249734
249666
 
249735
249667
  // src/cli/dev/dev-server/routes/integrations.ts
249736
- var import_express4 = __toESM(require_express(), 1);
249668
+ var import_express3 = __toESM(require_express(), 1);
249737
249669
  var import_multer = __toESM(require_multer(), 1);
249738
249670
  import { createHash, randomUUID as randomUUID4 } from "node:crypto";
249739
249671
  import fs28 from "node:fs";
@@ -249742,8 +249674,8 @@ function createFileToken(fileUri) {
249742
249674
  return createHash("sha256").update(fileUri).digest("hex");
249743
249675
  }
249744
249676
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
249745
- const router = import_express4.Router({ mergeParams: true });
249746
- const parseBody = import_express4.json();
249677
+ const router = import_express3.Router({ mergeParams: true });
249678
+ const parseBody = import_express3.json();
249747
249679
  const privateFilesDir = path18.join(mediaFilesDir, "private");
249748
249680
  fs28.mkdirSync(mediaFilesDir, { recursive: true });
249749
249681
  fs28.mkdirSync(privateFilesDir, { recursive: true });
@@ -249813,7 +249745,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
249813
249745
  return router;
249814
249746
  }
249815
249747
  function createCustomIntegrationRoutes(remoteProxy, logger) {
249816
- const router = import_express4.Router({ mergeParams: true });
249748
+ const router = import_express3.Router({ mergeParams: true });
249817
249749
  router.post("/:slug/:operationId", (req, res, next) => {
249818
249750
  logger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
249819
249751
  req.url = req.originalUrl;
@@ -249822,18 +249754,6 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
249822
249754
  return router;
249823
249755
  }
249824
249756
 
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
-
249837
249757
  // src/cli/dev/dev-server/watcher.ts
249838
249758
  import { EventEmitter as EventEmitter4 } from "node:events";
249839
249759
  import { relative as relative6 } from "node:path";
@@ -251538,7 +251458,7 @@ async function createDevServer(options8) {
251538
251458
  const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
251539
251459
  const baseUrl = `http://localhost:${port}`;
251540
251460
  const { functions, entities, project: project2 } = await options8.loadResources();
251541
- const app = import_express6.default();
251461
+ const app = import_express4.default();
251542
251462
  const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
251543
251463
  target: BASE44_APP_URL,
251544
251464
  changeOrigin: true
@@ -251555,17 +251475,7 @@ async function createDevServer(options8) {
251555
251475
  }
251556
251476
  next();
251557
251477
  });
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
- });
251566
251478
  const devLogger = createDevLogger();
251567
- const usersRoutes = createUsersRoutes();
251568
- app.use("/api/apps/:appId/users", usersRoutes);
251569
251479
  const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
251570
251480
  const functionRoutes = createFunctionRouter(functionManager, devLogger);
251571
251481
  app.use("/api/apps/:appId/functions", functionRoutes);
@@ -251578,7 +251488,7 @@ async function createDevServer(options8) {
251578
251488
  R2.info(`Loaded entities: ${db2.getCollectionNames().join(", ")}`);
251579
251489
  }
251580
251490
  let emitEntityEvent = () => {};
251581
- const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
251491
+ const entityRoutes = createEntityRoutes(db2, devLogger, remoteProxy, (...args) => emitEntityEvent(...args));
251582
251492
  app.use("/api/apps/:appId/entities", entityRoutes);
251583
251493
  const { path: mediaFilesDir } = await $dir();
251584
251494
  app.use("/media/private/:fileUri", (req, res, next) => {
@@ -251599,7 +251509,7 @@ async function createDevServer(options8) {
251599
251509
  }
251600
251510
  next();
251601
251511
  });
251602
- app.use("/media", import_express6.default.static(mediaFilesDir));
251512
+ app.use("/media", import_express4.default.static(mediaFilesDir));
251603
251513
  const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
251604
251514
  app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
251605
251515
  const customIntegrationRoutes = createCustomIntegrationRoutes(remoteProxy, devLogger);
@@ -256050,4 +255960,4 @@ export {
256050
255960
  CLIExitError
256051
255961
  };
256052
255962
 
256053
- //# debugId=A178BD03C903D32B64756E2164756E21
255963
+ //# debugId=8DF79D46442B07AB64756E2164756E21