@base44-preview/cli 0.1.21-pr.642.259f7d0 → 0.1.22-pr.644.4a848b7
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/assets/backend-runtime/exec.ts +13 -1
- package/dist/cli/index.js +106 -25
- package/dist/cli/index.js.map +8 -8
- package/package.json +1 -1
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
* - BASE44_APP_BASE_URL: App's published URL / subdomain (used for function calls)
|
|
12
12
|
* - BASE44_PRIVILEGED: When "true", adds the X-Bypass-RLS header (bypass RLS)
|
|
13
13
|
* - BASE44_DATA_ENV: When set, adds the X-Data-Env header (target data environment)
|
|
14
|
+
* - BASE44_SERVICE_TOKEN: When set, passed as `serviceToken` (enables `base44.asServiceRole`)
|
|
15
|
+
* - BASE44_EXTRA_HEADERS: When set, a JSON object of extra headers on every SDK request
|
|
16
|
+
*
|
|
17
|
+
* BASE44_SERVICE_TOKEN and BASE44_EXTRA_HEADERS are removed from the environment
|
|
18
|
+
* before the user script runs.
|
|
14
19
|
*/
|
|
15
20
|
|
|
16
21
|
export {};
|
|
@@ -21,6 +26,10 @@ const accessToken = Deno.env.get("BASE44_ACCESS_TOKEN");
|
|
|
21
26
|
const appBaseUrl = Deno.env.get("BASE44_APP_BASE_URL");
|
|
22
27
|
const isPrivileged = Deno.env.get("BASE44_PRIVILEGED") === "true";
|
|
23
28
|
const dataEnv = Deno.env.get("BASE44_DATA_ENV");
|
|
29
|
+
const serviceToken = Deno.env.get("BASE44_SERVICE_TOKEN");
|
|
30
|
+
const extraHeaders = Deno.env.get("BASE44_EXTRA_HEADERS");
|
|
31
|
+
Deno.env.delete("BASE44_SERVICE_TOKEN");
|
|
32
|
+
Deno.env.delete("BASE44_EXTRA_HEADERS");
|
|
24
33
|
|
|
25
34
|
if (!scriptPath) {
|
|
26
35
|
console.error("SCRIPT_PATH environment variable is required");
|
|
@@ -39,13 +48,16 @@ if (!appBaseUrl) {
|
|
|
39
48
|
|
|
40
49
|
import { createClient } from "npm:@base44/sdk";
|
|
41
50
|
|
|
42
|
-
const customHeaders: Record<string, string> =
|
|
51
|
+
const customHeaders: Record<string, string> = extraHeaders
|
|
52
|
+
? JSON.parse(extraHeaders)
|
|
53
|
+
: {};
|
|
43
54
|
if (isPrivileged) customHeaders["X-Bypass-RLS"] = "true";
|
|
44
55
|
if (dataEnv) customHeaders["X-Data-Env"] = dataEnv;
|
|
45
56
|
|
|
46
57
|
const base44 = createClient({
|
|
47
58
|
appId,
|
|
48
59
|
token: accessToken,
|
|
60
|
+
...(serviceToken ? { serviceToken } : {}),
|
|
49
61
|
serverUrl: appBaseUrl,
|
|
50
62
|
headers: customHeaders,
|
|
51
63
|
});
|
package/dist/cli/index.js
CHANGED
|
@@ -239265,7 +239265,7 @@ import { join as join13 } from "node:path";
|
|
|
239265
239265
|
// package.json
|
|
239266
239266
|
var package_default = {
|
|
239267
239267
|
name: "base44",
|
|
239268
|
-
version: "0.1.
|
|
239268
|
+
version: "0.1.22",
|
|
239269
239269
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
239270
239270
|
type: "module",
|
|
239271
239271
|
bin: {
|
|
@@ -247411,7 +247411,8 @@ class Base44Command extends Command2 {
|
|
|
247411
247411
|
if (branch !== undefined && !branch.trim()) {
|
|
247412
247412
|
throw new InvalidInputError("--branch must not be empty.");
|
|
247413
247413
|
}
|
|
247414
|
-
|
|
247414
|
+
const { requireAuth } = this._commandOptions;
|
|
247415
|
+
if (typeof requireAuth === "function" ? requireAuth() : requireAuth) {
|
|
247415
247416
|
await ensureAuth(this.context);
|
|
247416
247417
|
}
|
|
247417
247418
|
if (this._commandOptions.requireAppContext) {
|
|
@@ -251495,21 +251496,6 @@ function parseConcurrency(value) {
|
|
|
251495
251496
|
return parsed;
|
|
251496
251497
|
}
|
|
251497
251498
|
|
|
251498
|
-
// src/cli/dev/append-serve-args.ts
|
|
251499
|
-
var SHELL_SAFE = /^[\w@%+=:,./-]+$/;
|
|
251500
|
-
function quote(arg, platform) {
|
|
251501
|
-
if (SHELL_SAFE.test(arg)) {
|
|
251502
|
-
return arg;
|
|
251503
|
-
}
|
|
251504
|
-
if (platform === "win32") {
|
|
251505
|
-
return `"${arg.replace(/"/g, "\\\"")}"`;
|
|
251506
|
-
}
|
|
251507
|
-
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
251508
|
-
}
|
|
251509
|
-
function appendServeArgs(command, args, platform = process.platform) {
|
|
251510
|
-
return [command, ...args.map((arg) => quote(arg, platform))].join(" ");
|
|
251511
|
-
}
|
|
251512
|
-
|
|
251513
251499
|
// src/cli/dev/createDevLogger.ts
|
|
251514
251500
|
var colorByType = {
|
|
251515
251501
|
error: theme.styles.error,
|
|
@@ -251688,7 +251674,8 @@ async function siteDevAction(ctx, forwarded) {
|
|
|
251688
251674
|
if (!site) {
|
|
251689
251675
|
throw new InvalidInputError(`This project has no 'site' block in base44/config.jsonc, so there is no frontend to serve. Add one naming its serveCommand; site dev falls back to "npm run dev".`);
|
|
251690
251676
|
}
|
|
251691
|
-
const
|
|
251677
|
+
const serveCommand = site.serveCommand ?? DEFAULT_SERVE_COMMAND;
|
|
251678
|
+
const command = [serveCommand, ...forwarded].join(" ");
|
|
251692
251679
|
const runner = createServeCommandRunner({
|
|
251693
251680
|
serveCommand: command,
|
|
251694
251681
|
projectRoot: project.root,
|
|
@@ -256177,11 +256164,91 @@ function getDevCommand() {
|
|
|
256177
256164
|
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").option("--remote", "Serve the frontend against the production backend instead of a local one").hook("preAction", validateDevOptions).action(devAction);
|
|
256178
256165
|
}
|
|
256179
256166
|
|
|
256167
|
+
// src/core/exec/env-target.ts
|
|
256168
|
+
var ACCESS_TOKEN_VAR = "BASE44_EXEC_ACCESS_TOKEN";
|
|
256169
|
+
var SERVER_URL_VAR = "BASE44_EXEC_SERVER_URL";
|
|
256170
|
+
var SERVICE_TOKEN_VAR = "BASE44_EXEC_SERVICE_TOKEN";
|
|
256171
|
+
var HEADERS_VAR = "BASE44_EXEC_HEADERS";
|
|
256172
|
+
var EXEC_ENV_VARS = [
|
|
256173
|
+
ACCESS_TOKEN_VAR,
|
|
256174
|
+
SERVER_URL_VAR,
|
|
256175
|
+
SERVICE_TOKEN_VAR,
|
|
256176
|
+
HEADERS_VAR
|
|
256177
|
+
];
|
|
256178
|
+
function read3(env, name) {
|
|
256179
|
+
return env[name]?.trim() || undefined;
|
|
256180
|
+
}
|
|
256181
|
+
function hasExecEnvTarget(env = process.env) {
|
|
256182
|
+
return EXEC_ENV_VARS.some((name) => read3(env, name) !== undefined);
|
|
256183
|
+
}
|
|
256184
|
+
var HeadersSchema = record(string2(), string2());
|
|
256185
|
+
function parseHeaders(raw) {
|
|
256186
|
+
let parsed;
|
|
256187
|
+
try {
|
|
256188
|
+
parsed = JSON.parse(raw);
|
|
256189
|
+
} catch {
|
|
256190
|
+
throw new InvalidInputError(`${HEADERS_VAR} is not valid JSON.`, {
|
|
256191
|
+
hints: [{ message: `Set ${HEADERS_VAR} to e.g. '{"X-Header":"value"}'` }]
|
|
256192
|
+
});
|
|
256193
|
+
}
|
|
256194
|
+
const result = HeadersSchema.safeParse(parsed);
|
|
256195
|
+
if (!result.success) {
|
|
256196
|
+
throw new InvalidInputError(`${HEADERS_VAR} must be a JSON object of string header values.`, {
|
|
256197
|
+
hints: [
|
|
256198
|
+
{ message: `Set ${HEADERS_VAR} to e.g. '{"X-Header":"value"}'` }
|
|
256199
|
+
]
|
|
256200
|
+
});
|
|
256201
|
+
}
|
|
256202
|
+
return result.data;
|
|
256203
|
+
}
|
|
256204
|
+
function readExecEnvTarget(env = process.env) {
|
|
256205
|
+
if (!hasExecEnvTarget(env)) {
|
|
256206
|
+
return;
|
|
256207
|
+
}
|
|
256208
|
+
const token = read3(env, ACCESS_TOKEN_VAR);
|
|
256209
|
+
const serverUrl = read3(env, SERVER_URL_VAR);
|
|
256210
|
+
if (!token || !serverUrl) {
|
|
256211
|
+
const missing = token ? SERVER_URL_VAR : ACCESS_TOKEN_VAR;
|
|
256212
|
+
throw new InvalidInputError(`${missing} is not set. ${ACCESS_TOKEN_VAR} and ${SERVER_URL_VAR} must be set together.`, {
|
|
256213
|
+
hints: [
|
|
256214
|
+
{
|
|
256215
|
+
message: `Set both ${ACCESS_TOKEN_VAR} and ${SERVER_URL_VAR}, or unset all BASE44_EXEC_* variables to use your login`
|
|
256216
|
+
}
|
|
256217
|
+
]
|
|
256218
|
+
});
|
|
256219
|
+
}
|
|
256220
|
+
if (!URL.canParse(serverUrl)) {
|
|
256221
|
+
throw new InvalidInputError(`${SERVER_URL_VAR} is not a valid URL.`);
|
|
256222
|
+
}
|
|
256223
|
+
const serviceToken = read3(env, SERVICE_TOKEN_VAR);
|
|
256224
|
+
const rawHeaders = read3(env, HEADERS_VAR);
|
|
256225
|
+
return {
|
|
256226
|
+
token,
|
|
256227
|
+
serverUrl,
|
|
256228
|
+
...serviceToken ? { serviceToken } : {},
|
|
256229
|
+
...rawHeaders ? { headers: parseHeaders(rawHeaders) } : {}
|
|
256230
|
+
};
|
|
256231
|
+
}
|
|
256180
256232
|
// src/core/exec/run-script.ts
|
|
256181
256233
|
import { spawn as spawn4 } from "node:child_process";
|
|
256182
256234
|
import { copyFileSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
256235
|
+
var SERVICE_TOKEN_ENV = "BASE44_SERVICE_TOKEN";
|
|
256236
|
+
var EXTRA_HEADERS_ENV = "BASE44_EXTRA_HEADERS";
|
|
256237
|
+
function wrapperOnlyEnv(serviceToken, headers) {
|
|
256238
|
+
return {
|
|
256239
|
+
...serviceToken ? { [SERVICE_TOKEN_ENV]: serviceToken } : {},
|
|
256240
|
+
...headers ? { [EXTRA_HEADERS_ENV]: JSON.stringify(headers) } : {}
|
|
256241
|
+
};
|
|
256242
|
+
}
|
|
256243
|
+
function inheritedEnv() {
|
|
256244
|
+
const env = { ...process.env };
|
|
256245
|
+
for (const name of [...EXEC_ENV_VARS, SERVICE_TOKEN_ENV, EXTRA_HEADERS_ENV]) {
|
|
256246
|
+
delete env[name];
|
|
256247
|
+
}
|
|
256248
|
+
return env;
|
|
256249
|
+
}
|
|
256183
256250
|
async function runScript(options) {
|
|
256184
|
-
const { appId, code, local, privileged, dataEnv } = options;
|
|
256251
|
+
const { appId, code, local, privileged, dataEnv, serviceToken, headers } = options;
|
|
256185
256252
|
verifyDenoInstalled("to run scripts with exec");
|
|
256186
256253
|
const cleanupFns = [];
|
|
256187
256254
|
const tempScript = await $file({ postfix: ".ts" });
|
|
@@ -256196,7 +256263,8 @@ async function runScript(options) {
|
|
|
256196
256263
|
const exitCode = await new Promise((resolvePromise) => {
|
|
256197
256264
|
const child = spawn4("deno", ["run", "--allow-all", "--node-modules-dir=auto", tempWrapper.path], {
|
|
256198
256265
|
env: {
|
|
256199
|
-
...
|
|
256266
|
+
...inheritedEnv(),
|
|
256267
|
+
...wrapperOnlyEnv(serviceToken, headers),
|
|
256200
256268
|
SCRIPT_PATH: scriptPath,
|
|
256201
256269
|
BASE44_APP_ID: appId,
|
|
256202
256270
|
BASE44_ACCESS_TOKEN: appUserToken,
|
|
@@ -256251,6 +256319,10 @@ async function execAction({ app, isNonInteractive }, options) {
|
|
|
256251
256319
|
hints: [{ message: "Usage: base44 exec --local --port <port>" }]
|
|
256252
256320
|
});
|
|
256253
256321
|
}
|
|
256322
|
+
const envTarget = readExecEnvTarget();
|
|
256323
|
+
if (envTarget && options.local) {
|
|
256324
|
+
throw new InvalidInputError("--local cannot be used when BASE44_EXEC_ACCESS_TOKEN and BASE44_EXEC_SERVER_URL are set.");
|
|
256325
|
+
}
|
|
256254
256326
|
const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
|
|
256255
256327
|
hints: [
|
|
256256
256328
|
{ message: "File: cat ./script.ts | base44 exec" },
|
|
@@ -256266,13 +256338,15 @@ async function execAction({ app, isNonInteractive }, options) {
|
|
|
256266
256338
|
if (!code.trim()) {
|
|
256267
256339
|
throw noInputError;
|
|
256268
256340
|
}
|
|
256269
|
-
const local = options.local ? await resolveLocalTarget(options.port !== undefined ? parsePort(options.port) : DEFAULT_DEV_SERVER_PORT) : undefined;
|
|
256341
|
+
const local = envTarget ? { serverUrl: envTarget.serverUrl, token: envTarget.token } : options.local ? await resolveLocalTarget(options.port !== undefined ? parsePort(options.port) : DEFAULT_DEV_SERVER_PORT) : undefined;
|
|
256270
256342
|
const { exitCode } = await runScript({
|
|
256271
256343
|
appId: app.id,
|
|
256272
256344
|
code,
|
|
256273
256345
|
local,
|
|
256274
256346
|
privileged: options.privileged,
|
|
256275
|
-
dataEnv: options.dataEnv
|
|
256347
|
+
dataEnv: options.dataEnv,
|
|
256348
|
+
serviceToken: envTarget?.serviceToken,
|
|
256349
|
+
headers: envTarget?.headers
|
|
256276
256350
|
});
|
|
256277
256351
|
if (exitCode !== 0) {
|
|
256278
256352
|
process.exitCode = exitCode;
|
|
@@ -256280,7 +256354,7 @@ async function execAction({ app, isNonInteractive }, options) {
|
|
|
256280
256354
|
return {};
|
|
256281
256355
|
}
|
|
256282
256356
|
function getExecCommand() {
|
|
256283
|
-
return new Base44Command("exec").description("Run a script with the Base44 SDK pre-authenticated as the current user").option("--local", "Run against the local `base44 dev` server instead of the deployed app").option("--port <number>", `Port the local dev server is on (with --local; defaults to ${DEFAULT_DEV_SERVER_PORT})`).option("--privileged", "Run with admin privileges (bypass RLS). Requires app owner/editor role.").option("--data-env <environment>", "Data environment to run against (e.g. dev, prod)").addHelpText("after", `
|
|
256357
|
+
return new Base44Command("exec", { requireAuth: () => !hasExecEnvTarget() }).description("Run a script with the Base44 SDK pre-authenticated as the current user").option("--local", "Run against the local `base44 dev` server instead of the deployed app").option("--port <number>", `Port the local dev server is on (with --local; defaults to ${DEFAULT_DEV_SERVER_PORT})`).option("--privileged", "Run with admin privileges (bypass RLS). Requires app owner/editor role.").option("--data-env <environment>", "Data environment to run against (e.g. dev, prod)").addHelpText("after", `
|
|
256284
256358
|
Examples:
|
|
256285
256359
|
Run a script file:
|
|
256286
256360
|
$ cat ./script.ts | base44 exec
|
|
@@ -256292,7 +256366,14 @@ Examples:
|
|
|
256292
256366
|
$ echo "await base44.entities.Task.create({ title: 'seed' })" | base44 exec --local
|
|
256293
256367
|
|
|
256294
256368
|
With privileged access (bypass RLS):
|
|
256295
|
-
$ echo "const all = await base44.entities.Task.list()" | base44 exec --privileged
|
|
256369
|
+
$ echo "const all = await base44.entities.Task.list()" | base44 exec --privileged
|
|
256370
|
+
|
|
256371
|
+
Environment (for sandboxes and agents; no login or linked project needed):
|
|
256372
|
+
BASE44_EXEC_ACCESS_TOKEN App-user token for the SDK (requires BASE44_EXEC_SERVER_URL)
|
|
256373
|
+
BASE44_EXEC_SERVER_URL SDK server URL (requires BASE44_EXEC_ACCESS_TOKEN)
|
|
256374
|
+
BASE44_EXEC_SERVICE_TOKEN Optional service token, enables base44.asServiceRole
|
|
256375
|
+
BASE44_EXEC_HEADERS Optional JSON object of extra request headers
|
|
256376
|
+
The app id comes from --app-id or BASE44_APP_ID.`).action(execAction);
|
|
256296
256377
|
}
|
|
256297
256378
|
|
|
256298
256379
|
// src/cli/commands/project/eject.ts
|
|
@@ -260504,4 +260585,4 @@ export {
|
|
|
260504
260585
|
runCLI
|
|
260505
260586
|
};
|
|
260506
260587
|
|
|
260507
|
-
//# debugId=
|
|
260588
|
+
//# debugId=FD7BADBA9A7011E864756E2164756E21
|