@base44-preview/cli 0.0.41-pr.394.651c0cf → 0.0.41-pr.394.67fd14d

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
@@ -238421,6 +238421,8 @@ var package_default = {
238421
238421
  start: "./bin/run.js",
238422
238422
  clean: "rm -rf dist && mkdir -p dist",
238423
238423
  test: "vitest run",
238424
+ "test:npm": "CLI_TEST_RUNNER=npm vitest run",
238425
+ "test:binary": "CLI_TEST_RUNNER=binary vitest run",
238424
238426
  "test:watch": "vitest",
238425
238427
  lint: "cd ../.. && bun run lint",
238426
238428
  "lint:fix": "cd ../.. && bun run lint:fix",
@@ -247899,7 +247901,16 @@ async function getAllFunctionNames() {
247899
247901
  const { functions } = await readProjectConfig();
247900
247902
  return functions.map((fn) => fn.name);
247901
247903
  }
247904
+ function validateLimit(limit) {
247905
+ if (limit === undefined)
247906
+ return;
247907
+ const n2 = Number.parseInt(limit, 10);
247908
+ if (Number.isNaN(n2) || n2 < 1 || n2 > 1000) {
247909
+ throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
247910
+ }
247911
+ }
247902
247912
  async function logsAction(options) {
247913
+ validateLimit(options.limit);
247903
247914
  const specifiedFunctions = parseFunctionNames(options.function);
247904
247915
  const allProjectFunctions = await getAllFunctionNames();
247905
247916
  const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
@@ -247916,13 +247927,7 @@ async function logsAction(options) {
247916
247927
  return { outroMessage: "Fetched logs", stdout: logsOutput };
247917
247928
  }
247918
247929
  function getLogsCommand(context) {
247919
- return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)", normalizeDatetime).option("--until <datetime>", "Show logs until this time (ISO format)", normalizeDatetime).addOption(new Option("--level <level>", "Filter by log level").choices([...LogLevelSchema.options]).hideHelp()).option("-n, --limit <n>", "Results per page (1-1000, default: 50)", (v) => {
247920
- const n2 = Number.parseInt(v, 10);
247921
- if (Number.isNaN(n2) || n2 < 1 || n2 > 1000) {
247922
- throw new InvalidArgumentError(`Invalid limit: "${v}". Must be a number between 1 and 1000.`);
247923
- }
247924
- return v;
247925
- }).addOption(new Option("--order <order>", "Sort order").choices(["asc", "desc"])).action(async (options) => {
247930
+ return new Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all project functions").option("--since <datetime>", "Show logs from this time (ISO format)", normalizeDatetime).option("--until <datetime>", "Show logs until this time (ISO format)", normalizeDatetime).addOption(new Option("--level <level>", "Filter by log level").choices([...LogLevelSchema.options]).hideHelp()).option("-n, --limit <n>", "Results per page (1-1000, default: 50)").addOption(new Option("--order <order>", "Sort order").choices(["asc", "desc"])).action(async (options) => {
247926
247931
  await runCommand(() => logsAction(options), { requireAuth: true }, context);
247927
247932
  });
247928
247933
  }
@@ -247988,19 +247993,18 @@ function parseEntries(entries) {
247988
247993
  }
247989
247994
  return secrets;
247990
247995
  }
247991
- function validateInput(command) {
247992
- const entries = command.args;
247993
- const { envFile } = command.opts();
247996
+ function validateInput(entries, options) {
247994
247997
  const hasEntries = entries.length > 0;
247995
- const hasEnvFile = Boolean(envFile);
247998
+ const hasEnvFile = Boolean(options.envFile);
247996
247999
  if (!hasEntries && !hasEnvFile) {
247997
- command.error("Provide KEY=VALUE pairs or use --env-file. Example: base44 secrets set KEY1=VALUE1 KEY2=VALUE2");
248000
+ throw new InvalidInputError("Provide KEY=VALUE pairs or use --env-file. Example: base44 secrets set KEY1=VALUE1 KEY2=VALUE2");
247998
248001
  }
247999
248002
  if (hasEntries && hasEnvFile) {
248000
- command.error("Provide KEY=VALUE pairs or --env-file, but not both.");
248003
+ throw new InvalidInputError("Provide KEY=VALUE pairs or --env-file, but not both.");
248001
248004
  }
248002
248005
  }
248003
248006
  async function setSecretsAction(entries, options) {
248007
+ validateInput(entries, options);
248004
248008
  let secrets;
248005
248009
  if (options.envFile) {
248006
248010
  secrets = await parseEnvFile(resolve3(options.envFile));
@@ -248023,7 +248027,7 @@ async function setSecretsAction(entries, options) {
248023
248027
  };
248024
248028
  }
248025
248029
  function getSecretsSetCommand(context) {
248026
- return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. KEY1=VALUE1 KEY2=VALUE2)").option("--env-file <path>", "Path to .env file").hook("preAction", validateInput).action(async (entries, options) => {
248030
+ return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. KEY1=VALUE1 KEY2=VALUE2)").option("--env-file <path>", "Path to .env file").action(async (entries, options) => {
248027
248031
  await runCommand(() => setSecretsAction(entries, options), { requireAuth: true }, context);
248028
248032
  });
248029
248033
  }
@@ -248884,13 +248888,19 @@ function createEntityRoutes(db2, logger, remoteProxy, broadcast) {
248884
248888
  // src/cli/dev/dev-server/routes/integrations.ts
248885
248889
  var import_express3 = __toESM(require_express(), 1);
248886
248890
  var import_multer = __toESM(require_multer(), 1);
248887
- import { randomUUID as randomUUID4 } from "node:crypto";
248891
+ import { createHash, randomUUID as randomUUID4 } from "node:crypto";
248888
248892
  import fs28 from "node:fs";
248889
248893
  import path18 from "node:path";
248894
+ function createFileToken(fileUri) {
248895
+ return createHash("sha256").update(fileUri).digest("hex");
248896
+ }
248890
248897
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
248891
248898
  const router = import_express3.Router({ mergeParams: true });
248892
248899
  const parseBody = import_express3.json();
248900
+ const privateFilesDir = path18.join(mediaFilesDir, "private");
248893
248901
  fs28.mkdirSync(mediaFilesDir, { recursive: true });
248902
+ fs28.mkdirSync(privateFilesDir, { recursive: true });
248903
+ const MAX_FILE_SIZE = 50 * 1024 * 1024;
248894
248904
  const storage = import_multer.default.diskStorage({
248895
248905
  destination: mediaFilesDir,
248896
248906
  filename: (_req, file2, cb2) => {
@@ -248898,8 +248908,18 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
248898
248908
  cb2(null, `${randomUUID4()}${ext}`);
248899
248909
  }
248900
248910
  });
248901
- const MAX_FILE_SIZE = 50 * 1024 * 1024;
248911
+ const privateStorage = import_multer.default.diskStorage({
248912
+ destination: privateFilesDir,
248913
+ filename: (_req, file2, cb2) => {
248914
+ const ext = path18.extname(file2.originalname);
248915
+ cb2(null, `${randomUUID4()}${ext}`);
248916
+ }
248917
+ });
248902
248918
  const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
248919
+ const privateUpload = import_multer.default({
248920
+ storage: privateStorage,
248921
+ limits: { fileSize: MAX_FILE_SIZE }
248922
+ });
248903
248923
  router.post("/Core/UploadFile", upload.single("file"), (req, res) => {
248904
248924
  if (!req.file) {
248905
248925
  res.status(400).json({ error: "No file uploaded" });
@@ -248908,7 +248928,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
248908
248928
  const file_url = `${baseUrl}/media/${req.file.filename}`;
248909
248929
  res.json({ file_url });
248910
248930
  });
248911
- router.post("/Core/UploadPrivateFile", upload.single("file"), (req, res) => {
248931
+ router.post("/Core/UploadPrivateFile", privateUpload.single("file"), (req, res) => {
248912
248932
  if (!req.file) {
248913
248933
  res.status(400).json({ error: "No file uploaded" });
248914
248934
  return;
@@ -248922,8 +248942,8 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
248922
248942
  res.status(400).json({ error: "file_uri is required" });
248923
248943
  return;
248924
248944
  }
248925
- const signature = randomUUID4();
248926
- const signed_url = `${baseUrl}/media/${file_uri}?signature=${signature}`;
248945
+ const token2 = createFileToken(file_uri);
248946
+ const signed_url = `${baseUrl}/media/private/${file_uri}?token=${token2}`;
248927
248947
  res.json({ signed_url });
248928
248948
  });
248929
248949
  router.post("/Core/:endpointName", (req, res, next) => {
@@ -250692,6 +250712,24 @@ async function createDevServer(options8) {
250692
250712
  const entityRoutes = createEntityRoutes(db2, devLogger, remoteProxy, (...args) => emitEntityEvent(...args));
250693
250713
  app.use("/api/apps/:appId/entities", entityRoutes);
250694
250714
  const { path: mediaFilesDir } = await $dir();
250715
+ app.use("/media/private/:fileUri", (req, res, next) => {
250716
+ const { fileUri } = req.params;
250717
+ const token2 = req.query.token;
250718
+ if (!token2) {
250719
+ res.status(401).json({ error: "Missing token" });
250720
+ return;
250721
+ }
250722
+ const expectedToken = createFileToken(fileUri);
250723
+ if (token2 !== expectedToken) {
250724
+ res.status(400).json({
250725
+ error: "InvalidJWT",
250726
+ message: "signature verification failed",
250727
+ statusCode: "400"
250728
+ });
250729
+ return;
250730
+ }
250731
+ next();
250732
+ });
250695
250733
  app.use("/media", import_express4.default.static(mediaFilesDir));
250696
250734
  const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
250697
250735
  app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
@@ -255142,4 +255180,4 @@ export {
255142
255180
  CLIExitError
255143
255181
  };
255144
255182
 
255145
- //# debugId=46E1FE346B46A74664756E2164756E21
255183
+ //# debugId=8877E4FCD306ECFF64756E2164756E21