@base44-preview/cli 0.0.45-pr.427.2070391 → 0.0.46-pr.428.699825a

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.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Deno Exec Wrapper
3
+ *
4
+ * This script is executed by Deno to run user scripts with the Base44 SDK
5
+ * pre-authenticated and available as a global `base44` variable.
6
+ *
7
+ * Environment variables:
8
+ * - SCRIPT_PATH: Absolute path (or file:// URL) to the user's script
9
+ * - BASE44_APP_ID: App identifier from .app.jsonc
10
+ * - BASE44_ACCESS_TOKEN: User's access token
11
+ * - BASE44_APP_BASE_URL: App's published URL / subdomain (used for function calls)
12
+ */
13
+
14
+ export {};
15
+
16
+ const scriptPath = Deno.env.get("SCRIPT_PATH");
17
+ const appId = Deno.env.get("BASE44_APP_ID");
18
+ const accessToken = Deno.env.get("BASE44_ACCESS_TOKEN");
19
+ const appBaseUrl = Deno.env.get("BASE44_APP_BASE_URL");
20
+
21
+ if (!scriptPath) {
22
+ console.error("SCRIPT_PATH environment variable is required");
23
+ Deno.exit(1);
24
+ }
25
+
26
+ if (!appId || !accessToken) {
27
+ console.error("BASE44_APP_ID and BASE44_ACCESS_TOKEN are required");
28
+ Deno.exit(1);
29
+ }
30
+
31
+ if (!appBaseUrl) {
32
+ console.error("BASE44_APP_BASE_URL environment variable is required");
33
+ Deno.exit(1);
34
+ }
35
+
36
+ import { createClient } from "npm:@base44/sdk";
37
+
38
+ const base44 = createClient({
39
+ appId,
40
+ token: accessToken,
41
+ serverUrl: appBaseUrl,
42
+ });
43
+
44
+ (globalThis as any).base44 = base44;
45
+
46
+ try {
47
+ await import(scriptPath);
48
+ } catch (error) {
49
+ console.error("Failed to execute script:", error);
50
+ Deno.exit(1);
51
+ } finally {
52
+ // Clean up the SDK client (clears analytics heartbeat interval,
53
+ // disconnects socket) so the process can exit naturally.
54
+ base44.cleanup();
55
+ }
package/dist/cli/index.js CHANGED
@@ -214717,7 +214717,7 @@ var require_dist5 = __commonJS((exports, module) => {
214717
214717
  });
214718
214718
  module.exports = __toCommonJS(src_exports);
214719
214719
  var import_promises22 = __require("node:fs/promises");
214720
- var import_node_fs22 = __require("node:fs");
214720
+ var import_node_fs23 = __require("node:fs");
214721
214721
  var DEVIN_LOCAL_PATH = "/opt/.devin";
214722
214722
  var CURSOR2 = "cursor";
214723
214723
  var CURSOR_CLI = "cursor-cli";
@@ -214774,7 +214774,7 @@ var require_dist5 = __commonJS((exports, module) => {
214774
214774
  return { isAgent: true, agent: { name: REPLIT } };
214775
214775
  }
214776
214776
  try {
214777
- await (0, import_promises22.access)(DEVIN_LOCAL_PATH, import_node_fs22.constants.F_OK);
214777
+ await (0, import_promises22.access)(DEVIN_LOCAL_PATH, import_node_fs23.constants.F_OK);
214778
214778
  return { isAgent: true, agent: { name: DEVIN } };
214779
214779
  } catch (error48) {}
214780
214780
  return { isAgent: false, agent: undefined };
@@ -231558,7 +231558,7 @@ async function isLoggedIn() {
231558
231558
  }
231559
231559
 
231560
231560
  // src/core/project/api.ts
231561
- import { Readable } from "node:stream";
231561
+ import { Readable as Readable2 } from "node:stream";
231562
231562
  import { pipeline } from "node:stream/promises";
231563
231563
 
231564
231564
  // ../../node_modules/@isaacs/fs-minipass/dist/esm/index.js
@@ -237065,66 +237065,11 @@ var mtimeFilter = (opt) => {
237065
237065
  }
237066
237066
  opt.filter = filter ? (path8, stat) => filter(path8, stat) && !((opt.mtimeCache?.get(path8) ?? stat.mtime ?? 0) > (stat.mtime ?? 0)) : (path8, stat) => !((opt.mtimeCache?.get(path8) ?? stat.mtime ?? 0) > (stat.mtime ?? 0));
237067
237067
  };
237068
- // src/core/project/api.ts
237069
- async function createProject(projectName, description) {
237070
- let response;
237071
- try {
237072
- response = await base44Client.post("api/apps", {
237073
- json: {
237074
- name: projectName,
237075
- user_description: description ?? `Backend for '${projectName}'`,
237076
- is_managed_source_code: false,
237077
- public_settings: "public_without_login"
237078
- }
237079
- });
237080
- } catch (error48) {
237081
- throw await ApiError.fromHttpError(error48, "creating project");
237082
- }
237083
- const result = CreateProjectResponseSchema.safeParse(await response.json());
237084
- if (!result.success) {
237085
- throw new SchemaValidationError("Invalid response from server", result.error);
237086
- }
237087
- return {
237088
- projectId: result.data.id
237089
- };
237090
- }
237091
- async function listProjects() {
237092
- let response;
237093
- try {
237094
- response = await base44Client.get("api/apps", {
237095
- searchParams: {
237096
- sort: "-updated_date",
237097
- fields: "id,name,user_description,is_managed_source_code",
237098
- limit: 50
237099
- }
237100
- });
237101
- } catch (error48) {
237102
- throw await ApiError.fromHttpError(error48, "listing projects");
237103
- }
237104
- const result = ProjectsResponseSchema.safeParse(await response.json());
237105
- if (!result.success) {
237106
- throw new SchemaValidationError("Invalid response from server", result.error);
237107
- }
237108
- return result.data;
237109
- }
237110
- async function downloadProject(projectId, projectPath) {
237111
- let response;
237112
- try {
237113
- response = await base44Client.get(`api/apps/${projectId}/eject`, {
237114
- timeout: false
237115
- });
237116
- } catch (error48) {
237117
- throw await ApiError.fromHttpError(error48, "downloading project");
237118
- }
237119
- const nodeStream = Readable.fromWeb(response.body);
237120
- await makeDirectory(projectPath);
237121
- await pipeline(nodeStream, extract({ cwd: projectPath }));
237122
- }
237123
237068
  // ../../node_modules/globby/index.js
237124
237069
  import process5 from "node:process";
237125
237070
  import fs13 from "node:fs";
237126
237071
  import nodePath from "node:path";
237127
- import { Readable as Readable2 } from "node:stream";
237072
+ import { Readable } from "node:stream";
237128
237073
 
237129
237074
  // ../../node_modules/@sindresorhus/merge-streams/index.js
237130
237075
  import { on, once } from "node:events";
@@ -238016,7 +237961,7 @@ var globbyStream = normalizeArgumentsSync((patterns, options) => {
238016
237961
  const tasks = generateTasksSync(patterns, modifiedOptions);
238017
237962
  const streams = tasks.map((task) => import_fast_glob2.default.stream(task.patterns, task.options));
238018
237963
  if (streams.length === 0) {
238019
- return Readable2.from([]);
237964
+ return Readable.from([]);
238020
237965
  }
238021
237966
  const stream = mergeStreams(streams).filter((fastGlobResult) => filter(fastGlobResult));
238022
237967
  return stream;
@@ -239407,6 +239352,94 @@ async function readAppConfig(projectRoot) {
239407
239352
  }
239408
239353
  return result.data;
239409
239354
  }
239355
+
239356
+ // src/core/site/schema.ts
239357
+ var DeployResponseSchema = exports_external.object({
239358
+ app_url: exports_external.url()
239359
+ }).transform((data) => ({
239360
+ appUrl: data.app_url
239361
+ }));
239362
+ var PublishedUrlResponseSchema = exports_external.object({
239363
+ url: exports_external.string()
239364
+ });
239365
+
239366
+ // src/core/project/api.ts
239367
+ async function createProject(projectName, description) {
239368
+ let response;
239369
+ try {
239370
+ response = await base44Client.post("api/apps", {
239371
+ json: {
239372
+ name: projectName,
239373
+ user_description: description ?? `Backend for '${projectName}'`,
239374
+ is_managed_source_code: false,
239375
+ public_settings: "public_without_login"
239376
+ }
239377
+ });
239378
+ } catch (error48) {
239379
+ throw await ApiError.fromHttpError(error48, "creating project");
239380
+ }
239381
+ const result = CreateProjectResponseSchema.safeParse(await response.json());
239382
+ if (!result.success) {
239383
+ throw new SchemaValidationError("Invalid response from server", result.error);
239384
+ }
239385
+ return {
239386
+ projectId: result.data.id
239387
+ };
239388
+ }
239389
+ async function listProjects() {
239390
+ let response;
239391
+ try {
239392
+ response = await base44Client.get("api/apps", {
239393
+ searchParams: {
239394
+ sort: "-updated_date",
239395
+ fields: "id,name,user_description,is_managed_source_code",
239396
+ limit: 50
239397
+ }
239398
+ });
239399
+ } catch (error48) {
239400
+ throw await ApiError.fromHttpError(error48, "listing projects");
239401
+ }
239402
+ const result = ProjectsResponseSchema.safeParse(await response.json());
239403
+ if (!result.success) {
239404
+ throw new SchemaValidationError("Invalid response from server", result.error);
239405
+ }
239406
+ return result.data;
239407
+ }
239408
+ async function downloadProject(projectId, projectPath) {
239409
+ let response;
239410
+ try {
239411
+ response = await base44Client.get(`api/apps/${projectId}/eject`, {
239412
+ timeout: false
239413
+ });
239414
+ } catch (error48) {
239415
+ throw await ApiError.fromHttpError(error48, "downloading project");
239416
+ }
239417
+ const nodeStream = Readable2.fromWeb(response.body);
239418
+ await makeDirectory(projectPath);
239419
+ await pipeline(nodeStream, extract({ cwd: projectPath }));
239420
+ }
239421
+ async function getAppUserToken() {
239422
+ try {
239423
+ const response = await getAppClient().get("auth/token").json();
239424
+ return response.token;
239425
+ } catch (error48) {
239426
+ throw await ApiError.fromHttpError(error48, "exchanging platform token for app user token");
239427
+ }
239428
+ }
239429
+ async function getSiteUrl(projectId) {
239430
+ const id = projectId ?? getAppConfig().id;
239431
+ let response;
239432
+ try {
239433
+ response = await base44Client.get(`api/apps/platform/${id}/published-url`);
239434
+ } catch (error48) {
239435
+ throw await ApiError.fromHttpError(error48, "fetching site URL");
239436
+ }
239437
+ const result = PublishedUrlResponseSchema.safeParse(await response.json());
239438
+ if (!result.success) {
239439
+ throw new SchemaValidationError("Invalid response from server", result.error);
239440
+ }
239441
+ return result.data.url;
239442
+ }
239410
239443
  // src/core/project/template.ts
239411
239444
  var import_ejs = __toESM(require_ejs(), 1);
239412
239445
  var import_front_matter = __toESM(require_front_matter(), 1);
@@ -239419,7 +239452,7 @@ import { join as join8 } from "node:path";
239419
239452
  // package.json
239420
239453
  var package_default = {
239421
239454
  name: "base44",
239422
- version: "0.0.45",
239455
+ version: "0.0.46",
239423
239456
  description: "Base44 CLI - Unified interface for managing Base44 applications",
239424
239457
  type: "module",
239425
239458
  bin: {
@@ -239518,6 +239551,9 @@ function getTemplatesIndexPath() {
239518
239551
  function getDenoWrapperPath() {
239519
239552
  return join8(ASSETS_DIR, "deno-runtime", "main.ts");
239520
239553
  }
239554
+ function getExecWrapperPath() {
239555
+ return join8(ASSETS_DIR, "deno-runtime", "exec.ts");
239556
+ }
239521
239557
  function ensureNpmAssets(sourceDir) {
239522
239558
  if (existsSync(ASSETS_DIR))
239523
239559
  return;
@@ -239595,16 +239631,6 @@ async function createProjectFilesForExistingProject(options) {
239595
239631
  // src/core/project/deploy.ts
239596
239632
  import { resolve } from "node:path";
239597
239633
 
239598
- // src/core/site/schema.ts
239599
- var DeployResponseSchema = exports_external.object({
239600
- app_url: exports_external.url()
239601
- }).transform((data) => ({
239602
- appUrl: data.app_url
239603
- }));
239604
- var PublishedUrlResponseSchema = exports_external.object({
239605
- url: exports_external.string()
239606
- });
239607
-
239608
239634
  // src/core/site/api.ts
239609
239635
  async function uploadSite(archivePath) {
239610
239636
  const archiveBuffer = await readFile(archivePath);
@@ -239627,20 +239653,6 @@ async function uploadSite(archivePath) {
239627
239653
  }
239628
239654
  return result.data;
239629
239655
  }
239630
- async function getSiteUrl(projectId) {
239631
- const id = projectId ?? getAppConfig().id;
239632
- let response;
239633
- try {
239634
- response = await base44Client.get(`api/apps/platform/${id}/published-url`);
239635
- } catch (error48) {
239636
- throw await ApiError.fromHttpError(error48, "fetching site URL");
239637
- }
239638
- const result = PublishedUrlResponseSchema.safeParse(await response.json());
239639
- if (!result.success) {
239640
- throw new SchemaValidationError("Invalid response from server", result.error);
239641
- }
239642
- return result.data.url;
239643
- }
239644
239656
  // src/core/site/config.ts
239645
239657
  async function getSiteFilePaths(outputDir) {
239646
239658
  return await globby("**/*", {
@@ -246821,6 +246833,20 @@ async function deleteSecret(name2) {
246821
246833
  }
246822
246834
  return result.data;
246823
246835
  }
246836
+ // src/core/utils/dependencies.ts
246837
+ import { spawnSync as spawnSync2 } from "node:child_process";
246838
+ function verifyDenoInstalled(context) {
246839
+ const result = spawnSync2("deno", ["--version"]);
246840
+ if (result.error) {
246841
+ throw new DependencyNotFoundError(`Deno is required ${context}`, {
246842
+ hints: [
246843
+ {
246844
+ message: "Install Deno: https://docs.deno.com/runtime/getting_started/installation/"
246845
+ }
246846
+ ]
246847
+ });
246848
+ }
246849
+ }
246824
246850
  // src/core/utils/env.ts
246825
246851
  var import_dotenv = __toESM(require_main(), 1);
246826
246852
  async function parseEnvFile(filePath) {
@@ -249024,6 +249050,7 @@ var { promisify: promisify11 } = __require("util");
249024
249050
  var tmp = require_tmp();
249025
249051
  var $fileSync = tmp.fileSync;
249026
249052
  var fileWithOptions = promisify11((options8, cb2) => tmp.file(options8, (err, path18, fd, cleanup) => err ? cb2(err) : cb2(undefined, { path: path18, fd, cleanup: promisify11(cleanup) })));
249053
+ var $file = async (options8) => fileWithOptions(options8);
249027
249054
  var $dirSync = tmp.dirSync;
249028
249055
  var dirWithOptions = promisify11((options8, cb2) => tmp.dir(options8, (err, path18, cleanup) => err ? cb2(err) : cb2(undefined, { path: path18, cleanup: promisify11(cleanup) })));
249029
249056
  var $dir = async (options8) => dirWithOptions(options8);
@@ -249056,7 +249083,7 @@ function createDevLogger() {
249056
249083
  }
249057
249084
 
249058
249085
  // src/cli/dev/dev-server/function-manager.ts
249059
- import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
249086
+ import { spawn as spawn2 } from "node:child_process";
249060
249087
  var READY_TIMEOUT = 30000;
249061
249088
 
249062
249089
  class FunctionManager {
@@ -249070,15 +249097,7 @@ class FunctionManager {
249070
249097
  this.logger = logger;
249071
249098
  this.wrapperPath = wrapperPath;
249072
249099
  if (functions.length > 0) {
249073
- this.verifyDenoIsInstalled();
249074
- }
249075
- }
249076
- verifyDenoIsInstalled() {
249077
- const result = spawnSync2("deno", ["--version"]);
249078
- if (result.error) {
249079
- throw new DependencyNotFoundError("Deno is required to run functions", {
249080
- hints: [{ message: "Install Deno from https://deno.com/download" }]
249081
- });
249100
+ verifyDenoInstalled("to run backend functions locally");
249082
249101
  }
249083
249102
  }
249084
249103
  getFunctionNames() {
@@ -251680,6 +251699,93 @@ function getDevCommand() {
251680
251699
  return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").action(devAction);
251681
251700
  }
251682
251701
 
251702
+ // src/core/exec/run-script.ts
251703
+ import { spawn as spawn3 } from "node:child_process";
251704
+ import { copyFileSync, writeFileSync as writeFileSync2 } from "node:fs";
251705
+ async function runScript(options8) {
251706
+ const { appId, code: code2 } = options8;
251707
+ verifyDenoInstalled("to run scripts with exec");
251708
+ const cleanupFns = [];
251709
+ const tempScript = await $file({ postfix: ".ts" });
251710
+ cleanupFns.push(tempScript.cleanup);
251711
+ writeFileSync2(tempScript.path, code2, "utf-8");
251712
+ const scriptPath = `file://${tempScript.path}`;
251713
+ const [appUserToken, appBaseUrl] = await Promise.all([
251714
+ getAppUserToken(),
251715
+ getSiteUrl()
251716
+ ]);
251717
+ const tempWrapper = await $file({ postfix: ".ts" });
251718
+ cleanupFns.push(tempWrapper.cleanup);
251719
+ copyFileSync(getExecWrapperPath(), tempWrapper.path);
251720
+ try {
251721
+ const exitCode = await new Promise((resolvePromise) => {
251722
+ const child = spawn3("deno", ["run", "--allow-all", "--node-modules-dir=auto", tempWrapper.path], {
251723
+ env: {
251724
+ ...process.env,
251725
+ SCRIPT_PATH: scriptPath,
251726
+ BASE44_APP_ID: appId,
251727
+ BASE44_ACCESS_TOKEN: appUserToken,
251728
+ BASE44_APP_BASE_URL: appBaseUrl
251729
+ },
251730
+ stdio: "inherit"
251731
+ });
251732
+ child.on("close", (code3) => {
251733
+ resolvePromise(code3 ?? 1);
251734
+ });
251735
+ });
251736
+ return { exitCode };
251737
+ } finally {
251738
+ for (const cleanup of cleanupFns) {
251739
+ cleanup();
251740
+ }
251741
+ }
251742
+ }
251743
+ // src/cli/commands/exec.ts
251744
+ function readStdin() {
251745
+ return new Promise((resolve8, reject) => {
251746
+ let data = "";
251747
+ process.stdin.setEncoding("utf-8");
251748
+ process.stdin.on("data", (chunk) => {
251749
+ data += chunk;
251750
+ });
251751
+ process.stdin.on("end", () => resolve8(data));
251752
+ process.stdin.on("error", reject);
251753
+ });
251754
+ }
251755
+ async function execAction(isNonInteractive) {
251756
+ const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
251757
+ hints: [
251758
+ { message: "File: cat ./script.ts | base44 exec" },
251759
+ {
251760
+ message: 'Eval: echo "const users = await base44.entities.User.list(); console.log(users)" | base44 exec'
251761
+ }
251762
+ ]
251763
+ });
251764
+ if (!isNonInteractive) {
251765
+ throw noInputError;
251766
+ }
251767
+ const code2 = await readStdin();
251768
+ if (!code2.trim()) {
251769
+ throw noInputError;
251770
+ }
251771
+ const { exitCode } = await runScript({ appId: getAppConfig().id, code: code2 });
251772
+ if (exitCode !== 0) {
251773
+ process.exitCode = exitCode;
251774
+ }
251775
+ return {};
251776
+ }
251777
+ function getExecCommand() {
251778
+ return new Base44Command("exec").description("Run a script with the Base44 SDK pre-authenticated as the current user").addHelpText("after", `
251779
+ Examples:
251780
+ Run a script file:
251781
+ $ cat ./script.ts | base44 exec
251782
+
251783
+ Inline script:
251784
+ $ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (_options, command2) => {
251785
+ return await execAction(command2.isNonInteractive);
251786
+ });
251787
+ }
251788
+
251683
251789
  // src/cli/commands/project/eject.ts
251684
251790
  import { resolve as resolve8 } from "node:path";
251685
251791
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
@@ -251810,6 +251916,7 @@ function createProgram(context) {
251810
251916
  program2.addCommand(getSecretsCommand());
251811
251917
  program2.addCommand(getSiteCommand());
251812
251918
  program2.addCommand(getTypesCommand());
251919
+ program2.addCommand(getExecCommand());
251813
251920
  program2.addCommand(getDevCommand(), { hidden: true });
251814
251921
  program2.addCommand(getLogsCommand(), { hidden: true });
251815
251922
  return program2;
@@ -256053,4 +256160,4 @@ export {
256053
256160
  CLIExitError
256054
256161
  };
256055
256162
 
256056
- //# debugId=7C07ED97097C7A7364756E2164756E21
256163
+ //# debugId=9699F2C168D6A27C64756E2164756E21