@base44-preview/cli 0.1.8-pr.589.9d22ef2 → 0.1.8-pr.600.002d9ac
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/templates/backend-and-client/package.json +2 -1
- package/dist/assets/templates/backend-and-client/src/api/base44Client.js +12 -0
- package/dist/assets/templates/backend-and-client/src/lib/app-params.js +28 -0
- package/dist/assets/templates/backend-and-client/vite.config.js +3 -8
- package/dist/cli/index.js +374 -69
- package/dist/cli/index.js.map +23 -15
- package/package.json +1 -1
- package/dist/assets/templates/backend-and-client/src/api/base44Client.js.ejs +0 -5
package/dist/cli/index.js
CHANGED
|
@@ -247201,24 +247201,33 @@ var ResourceSourceSchema = exports_external.discriminatedUnion("type", [
|
|
|
247201
247201
|
]);
|
|
247202
247202
|
|
|
247203
247203
|
// src/core/resources/entity/schema.ts
|
|
247204
|
-
var
|
|
247205
|
-
|
|
247206
|
-
|
|
247207
|
-
|
|
247208
|
-
|
|
247209
|
-
|
|
247210
|
-
|
|
247211
|
-
|
|
247212
|
-
|
|
247213
|
-
|
|
247214
|
-
|
|
247204
|
+
var fieldConditionOperators = new Set([
|
|
247205
|
+
"$eq",
|
|
247206
|
+
"$ne",
|
|
247207
|
+
"$in",
|
|
247208
|
+
"$nin",
|
|
247209
|
+
"$gt",
|
|
247210
|
+
"$gte",
|
|
247211
|
+
"$lt",
|
|
247212
|
+
"$lte",
|
|
247213
|
+
"$exists",
|
|
247214
|
+
"$all",
|
|
247215
|
+
"$size",
|
|
247216
|
+
"$elemMatch"
|
|
247215
247217
|
]);
|
|
247216
|
-
var
|
|
247217
|
-
var
|
|
247218
|
-
|
|
247219
|
-
|
|
247220
|
-
|
|
247221
|
-
|
|
247218
|
+
var isScalar = (value) => value === null || ["string", "number", "boolean"].includes(typeof value);
|
|
247219
|
+
var isValidFieldCondition = (value) => {
|
|
247220
|
+
if (isScalar(value)) {
|
|
247221
|
+
return true;
|
|
247222
|
+
}
|
|
247223
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
247224
|
+
return Object.keys(value).every((k2) => fieldConditionOperators.has(k2));
|
|
247225
|
+
}
|
|
247226
|
+
return false;
|
|
247227
|
+
};
|
|
247228
|
+
var supportedOperators = [...fieldConditionOperators].sort().join(", ");
|
|
247229
|
+
var FieldConditionSchema = exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean(), exports_external.null(), exports_external.looseObject({})]).refine(isValidFieldCondition, `Field condition values must be a primitive or an operator object (${supportedOperators})`);
|
|
247230
|
+
var UserConditionSchema = exports_external.looseObject({}).refine((val) => Object.keys(val).length > 0 && Object.entries(val).every(([key, value]) => !key.startsWith("$") && isScalar(value)), "user_condition compares user attributes by exact equality: a non-empty object of attribute: scalar pairs, no operators");
|
|
247222
247231
|
var rlsConditionAllowedKeys = new Set([
|
|
247223
247232
|
"user_condition",
|
|
247224
247233
|
"created_by",
|
|
@@ -247250,18 +247259,13 @@ var RLSConditionSchema = exports_external.looseObject({
|
|
|
247250
247259
|
return exports_external.array(RefineRLSConditionSchema).optional();
|
|
247251
247260
|
}
|
|
247252
247261
|
});
|
|
247253
|
-
var
|
|
247254
|
-
var
|
|
247255
|
-
|
|
247256
|
-
|
|
247257
|
-
|
|
247258
|
-
|
|
247259
|
-
|
|
247260
|
-
}
|
|
247261
|
-
return false;
|
|
247262
|
-
};
|
|
247263
|
-
var RefineRLSConditionSchema = RLSConditionSchema.refine((val) => Object.entries(val).every(([key, value]) => rlsConditionAllowedKeys.has(key) || isValidFieldCondition(value)), "Field condition values must be a primitive or an operator object ($in, $nin, $ne, $all)");
|
|
247264
|
-
var RLSRuleSchema = exports_external.union([exports_external.boolean(), RefineRLSConditionSchema]);
|
|
247262
|
+
var RefineRLSConditionSchema = RLSConditionSchema.refine((val) => Object.entries(val).every(([key, value]) => rlsConditionAllowedKeys.has(key) || isValidFieldCondition(value)), `Field condition values must be a primitive or an operator object (${supportedOperators})`);
|
|
247263
|
+
var RLSRuleSchema = exports_external.union([
|
|
247264
|
+
exports_external.boolean(),
|
|
247265
|
+
exports_external.null(),
|
|
247266
|
+
exports_external.literal(""),
|
|
247267
|
+
RefineRLSConditionSchema
|
|
247268
|
+
]);
|
|
247265
247269
|
var EntityRLSSchema = exports_external.looseObject({
|
|
247266
247270
|
create: RLSRuleSchema.optional(),
|
|
247267
247271
|
read: RLSRuleSchema.optional(),
|
|
@@ -247277,7 +247281,7 @@ var FieldRLSSchema = exports_external.looseObject({
|
|
|
247277
247281
|
delete: RLSRuleSchema.optional()
|
|
247278
247282
|
});
|
|
247279
247283
|
var PropertyDefinitionSchema = exports_external.looseObject({
|
|
247280
|
-
type: exports_external.string(),
|
|
247284
|
+
type: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]),
|
|
247281
247285
|
title: exports_external.string().optional(),
|
|
247282
247286
|
description: exports_external.string().optional(),
|
|
247283
247287
|
minLength: exports_external.number().int().min(0).optional(),
|
|
@@ -247301,7 +247305,7 @@ var PropertyDefinitionSchema = exports_external.looseObject({
|
|
|
247301
247305
|
});
|
|
247302
247306
|
var EntitySchema = exports_external.looseObject({
|
|
247303
247307
|
type: exports_external.literal("object").default("object"),
|
|
247304
|
-
name: exports_external.string().min(1).regex(
|
|
247308
|
+
name: exports_external.string().min(1).regex(/^\w+$/, "Entity name must contain only letters, numbers, and underscores"),
|
|
247305
247309
|
title: exports_external.string().optional(),
|
|
247306
247310
|
description: exports_external.string().optional(),
|
|
247307
247311
|
properties: exports_external.record(exports_external.string(), PropertyDefinitionSchema).default({}),
|
|
@@ -247871,10 +247875,15 @@ var functionResource = {
|
|
|
247871
247875
|
// src/core/project/config.ts
|
|
247872
247876
|
class ProjectConfigReader {
|
|
247873
247877
|
pluginSourceByNamespace = new Map;
|
|
247874
|
-
async
|
|
247878
|
+
async readProjectSettings(projectRoot) {
|
|
247875
247879
|
const { root, configPath } = await this.findConfigOrThrow(projectRoot);
|
|
247876
247880
|
const project = await this.readConfigFile(configPath);
|
|
247877
247881
|
this.assertPluginProjectDoesNotLoadPlugins(project, configPath);
|
|
247882
|
+
return { ...project, root, configPath };
|
|
247883
|
+
}
|
|
247884
|
+
async readProjectConfig(projectRoot) {
|
|
247885
|
+
const project = await this.readProjectSettings(projectRoot);
|
|
247886
|
+
const { configPath } = project;
|
|
247878
247887
|
const localResources = await this.readProjectResources(configPath, project);
|
|
247879
247888
|
const pluginResources = await this.readPlugins(project.plugins, configPath);
|
|
247880
247889
|
const entities = mergeProjectAndPluginEntities(localResources.entities, pluginResources.entities, configPath);
|
|
@@ -247884,7 +247893,7 @@ class ProjectConfigReader {
|
|
|
247884
247893
|
];
|
|
247885
247894
|
this.validateFunctionNames(functions, configPath);
|
|
247886
247895
|
return {
|
|
247887
|
-
project
|
|
247896
|
+
project,
|
|
247888
247897
|
entities,
|
|
247889
247898
|
functions,
|
|
247890
247899
|
agents: localResources.agents,
|
|
@@ -248022,6 +248031,10 @@ async function readProjectConfig(projectRoot) {
|
|
|
248022
248031
|
const reader = new ProjectConfigReader;
|
|
248023
248032
|
return await reader.readProjectConfig(projectRoot);
|
|
248024
248033
|
}
|
|
248034
|
+
async function readProjectSettings(projectRoot) {
|
|
248035
|
+
const reader = new ProjectConfigReader;
|
|
248036
|
+
return await reader.readProjectSettings(projectRoot);
|
|
248037
|
+
}
|
|
248025
248038
|
// src/core/project/template.ts
|
|
248026
248039
|
var import_ejs = __toESM(require_ejs(), 1);
|
|
248027
248040
|
var import_front_matter2 = __toESM(require_front_matter(), 1);
|
|
@@ -248335,7 +248348,9 @@ async function deploySite(siteOutputDir) {
|
|
|
248335
248348
|
if (!await pathExists(siteOutputDir)) {
|
|
248336
248349
|
throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
|
|
248337
248350
|
hints: [
|
|
248338
|
-
{
|
|
248351
|
+
{
|
|
248352
|
+
message: "Run 'base44 build' first (it injects your app id; a bare 'npm run build' does not)"
|
|
248353
|
+
}
|
|
248339
248354
|
]
|
|
248340
248355
|
});
|
|
248341
248356
|
}
|
|
@@ -248343,7 +248358,9 @@ async function deploySite(siteOutputDir) {
|
|
|
248343
248358
|
if (filePaths.length === 0) {
|
|
248344
248359
|
throw new ConfigInvalidError(`No files found in output directory: ${siteOutputDir}. Make sure to build your project first.`, siteOutputDir, {
|
|
248345
248360
|
hints: [
|
|
248346
|
-
{
|
|
248361
|
+
{
|
|
248362
|
+
message: "Run 'base44 build' first (it injects your app id; a bare 'npm run build' does not)"
|
|
248363
|
+
}
|
|
248347
248364
|
]
|
|
248348
248365
|
});
|
|
248349
248366
|
}
|
|
@@ -255586,6 +255603,14 @@ function writeJsonError(error48) {
|
|
|
255586
255603
|
envelope.hints = error48.hints;
|
|
255587
255604
|
}
|
|
255588
255605
|
}
|
|
255606
|
+
if (error48 instanceof ApiError) {
|
|
255607
|
+
if (error48.statusCode !== undefined) {
|
|
255608
|
+
envelope.statusCode = error48.statusCode;
|
|
255609
|
+
}
|
|
255610
|
+
if (error48.requestId !== undefined) {
|
|
255611
|
+
envelope.requestId = error48.requestId;
|
|
255612
|
+
}
|
|
255613
|
+
}
|
|
255589
255614
|
process.stdout.write(`${JSON.stringify(envelope)}
|
|
255590
255615
|
`);
|
|
255591
255616
|
}
|
|
@@ -255682,6 +255707,18 @@ async function confirmPush({
|
|
|
255682
255707
|
});
|
|
255683
255708
|
return !Ct(proceed) && proceed;
|
|
255684
255709
|
}
|
|
255710
|
+
// src/cli/utils/datetime.ts
|
|
255711
|
+
var import_ms2 = __toESM(require_ms(), 1);
|
|
255712
|
+
var HAS_TIMEZONE_SUFFIX = /Z$|[+-]\d{2}:\d{2}$/;
|
|
255713
|
+
function normalizeDatetime(value) {
|
|
255714
|
+
const duration3 = import_ms2.default(value);
|
|
255715
|
+
if (duration3 !== undefined) {
|
|
255716
|
+
return new Date(Date.now() - duration3).toISOString();
|
|
255717
|
+
}
|
|
255718
|
+
if (HAS_TIMEZONE_SUFFIX.test(value))
|
|
255719
|
+
return value;
|
|
255720
|
+
return `${value}Z`;
|
|
255721
|
+
}
|
|
255685
255722
|
// src/cli/utils/json.ts
|
|
255686
255723
|
function toJsonStdout(result) {
|
|
255687
255724
|
return `${JSON.stringify(result, null, 2)}
|
|
@@ -257539,8 +257576,8 @@ function getDeleteCommand() {
|
|
|
257539
257576
|
}
|
|
257540
257577
|
|
|
257541
257578
|
// src/cli/commands/functions/formatDeployResult.ts
|
|
257542
|
-
function formatDuration(
|
|
257543
|
-
return `${(
|
|
257579
|
+
function formatDuration(ms2) {
|
|
257580
|
+
return `${(ms2 / 1000).toFixed(1)}s`;
|
|
257544
257581
|
}
|
|
257545
257582
|
function formatDeployResult(result, log) {
|
|
257546
257583
|
const label = result.name.padEnd(25);
|
|
@@ -257873,7 +257910,11 @@ async function completeProjectSetup({
|
|
|
257873
257910
|
const { appUrl } = await runTask2("Installing dependencies...", async (updateMessage) => {
|
|
257874
257911
|
await execa({ cwd: resolvedPath, shell: true })`${installCommand}`;
|
|
257875
257912
|
updateMessage("Building project...");
|
|
257876
|
-
await execa({
|
|
257913
|
+
await execa({
|
|
257914
|
+
cwd: resolvedPath,
|
|
257915
|
+
shell: true,
|
|
257916
|
+
env: { VITE_BASE44_APP_ID: projectId }
|
|
257917
|
+
})`${buildCommand}`;
|
|
257877
257918
|
updateMessage("Deploying site...");
|
|
257878
257919
|
return await deploySite(join25(resolvedPath, outputDirectory));
|
|
257879
257920
|
}, {
|
|
@@ -258353,7 +258394,6 @@ function getLinkCommand() {
|
|
|
258353
258394
|
}
|
|
258354
258395
|
|
|
258355
258396
|
// src/cli/commands/project/logs.ts
|
|
258356
|
-
var import_ms2 = __toESM(require_ms(), 1);
|
|
258357
258397
|
function parseFunctionFilters(options) {
|
|
258358
258398
|
const filters = {};
|
|
258359
258399
|
if (options.since) {
|
|
@@ -258381,15 +258421,6 @@ function parseFunctionNames(option) {
|
|
|
258381
258421
|
return [];
|
|
258382
258422
|
return option.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
258383
258423
|
}
|
|
258384
|
-
function normalizeDatetime(value) {
|
|
258385
|
-
const duration3 = import_ms2.default(value);
|
|
258386
|
-
if (duration3 !== undefined) {
|
|
258387
|
-
return new Date(Date.now() - duration3).toISOString();
|
|
258388
|
-
}
|
|
258389
|
-
if (/Z$|[+-]\d{2}:\d{2}$/.test(value))
|
|
258390
|
-
return value;
|
|
258391
|
-
return `${value}Z`;
|
|
258392
|
-
}
|
|
258393
258424
|
function formatEntry(entry) {
|
|
258394
258425
|
const time3 = entry.time.substring(0, 19).replace("T", " ");
|
|
258395
258426
|
const level = entry.level.toUpperCase().padEnd(5);
|
|
@@ -259030,7 +259061,7 @@ async function deployAction2(ctx, options) {
|
|
|
259030
259061
|
if (isNonInteractive && !options.yes) {
|
|
259031
259062
|
throw new InvalidInputError("--yes is required in non-interactive mode");
|
|
259032
259063
|
}
|
|
259033
|
-
const
|
|
259064
|
+
const project2 = await readProjectSettings();
|
|
259034
259065
|
const outputDirectory = project2.site?.outputDirectory;
|
|
259035
259066
|
if (!outputDirectory) {
|
|
259036
259067
|
throw new ConfigNotFoundError("No site configuration found.", {
|
|
@@ -259267,6 +259298,235 @@ function getTypesCommand() {
|
|
|
259267
259298
|
return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
259268
259299
|
}
|
|
259269
259300
|
|
|
259301
|
+
// src/core/resources/workflow/schema.ts
|
|
259302
|
+
var WorkflowRunStatusSchema = exports_external.enum([
|
|
259303
|
+
"running",
|
|
259304
|
+
"completed",
|
|
259305
|
+
"failed",
|
|
259306
|
+
"cancelled"
|
|
259307
|
+
]);
|
|
259308
|
+
var WorkflowListItemSchema = exports_external.object({
|
|
259309
|
+
id: exports_external.string(),
|
|
259310
|
+
name: exports_external.string(),
|
|
259311
|
+
description: exports_external.string().nullable().optional(),
|
|
259312
|
+
status: exports_external.string(),
|
|
259313
|
+
status_reason: exports_external.string().nullable().optional(),
|
|
259314
|
+
total_runs: exports_external.number().default(0),
|
|
259315
|
+
consecutive_failures: exports_external.number().default(0),
|
|
259316
|
+
last_run_at: exports_external.string().nullable().optional(),
|
|
259317
|
+
last_run_status: exports_external.string().nullable().optional()
|
|
259318
|
+
}).transform((data) => ({
|
|
259319
|
+
id: data.id,
|
|
259320
|
+
name: data.name,
|
|
259321
|
+
description: data.description ?? null,
|
|
259322
|
+
status: data.status,
|
|
259323
|
+
statusReason: data.status_reason ?? null,
|
|
259324
|
+
totalRuns: data.total_runs,
|
|
259325
|
+
consecutiveFailures: data.consecutive_failures,
|
|
259326
|
+
lastRunAt: data.last_run_at ?? null,
|
|
259327
|
+
lastRunStatus: data.last_run_status ?? null
|
|
259328
|
+
}));
|
|
259329
|
+
var ListWorkflowsResponseSchema = exports_external.array(WorkflowListItemSchema);
|
|
259330
|
+
var WorkflowRunSchema = exports_external.object({
|
|
259331
|
+
run_id: exports_external.string(),
|
|
259332
|
+
workflow_id: exports_external.string(),
|
|
259333
|
+
workflow_name: exports_external.string().default(""),
|
|
259334
|
+
trigger_type: exports_external.string().default(""),
|
|
259335
|
+
status: exports_external.string(),
|
|
259336
|
+
started_at: exports_external.string().nullable().optional(),
|
|
259337
|
+
completed_at: exports_external.string().nullable().optional(),
|
|
259338
|
+
duration_ms: exports_external.number().default(0),
|
|
259339
|
+
steps_count: exports_external.number().default(0),
|
|
259340
|
+
error_message: exports_external.string().nullable().optional(),
|
|
259341
|
+
is_test_run: exports_external.boolean().default(false),
|
|
259342
|
+
status_reason: exports_external.string().default("")
|
|
259343
|
+
}).transform((data) => ({
|
|
259344
|
+
runId: data.run_id,
|
|
259345
|
+
workflowId: data.workflow_id,
|
|
259346
|
+
workflowName: data.workflow_name,
|
|
259347
|
+
triggerType: data.trigger_type,
|
|
259348
|
+
status: data.status,
|
|
259349
|
+
startedAt: data.started_at ?? null,
|
|
259350
|
+
completedAt: data.completed_at ?? null,
|
|
259351
|
+
durationMs: data.duration_ms,
|
|
259352
|
+
stepsCount: data.steps_count,
|
|
259353
|
+
errorMessage: data.error_message ?? null,
|
|
259354
|
+
isTestRun: data.is_test_run,
|
|
259355
|
+
statusReason: data.status_reason
|
|
259356
|
+
}));
|
|
259357
|
+
var ListWorkflowRunsResponseSchema = exports_external.array(WorkflowRunSchema);
|
|
259358
|
+
|
|
259359
|
+
// src/core/resources/workflow/api.ts
|
|
259360
|
+
async function listWorkflows(limit) {
|
|
259361
|
+
const appClient = getAppClient();
|
|
259362
|
+
const searchParams = new URLSearchParams;
|
|
259363
|
+
if (limit !== undefined) {
|
|
259364
|
+
searchParams.set("limit", String(limit));
|
|
259365
|
+
}
|
|
259366
|
+
let response;
|
|
259367
|
+
try {
|
|
259368
|
+
response = await appClient.get("workflows", { searchParams });
|
|
259369
|
+
} catch (error48) {
|
|
259370
|
+
throw await ApiError.fromHttpError(error48, "listing workflows");
|
|
259371
|
+
}
|
|
259372
|
+
const result = ListWorkflowsResponseSchema.safeParse(await response.json());
|
|
259373
|
+
if (!result.success) {
|
|
259374
|
+
throw new SchemaValidationError("Invalid workflows response from server", result.error);
|
|
259375
|
+
}
|
|
259376
|
+
return result.data;
|
|
259377
|
+
}
|
|
259378
|
+
function buildRunsQueryString(filters) {
|
|
259379
|
+
const params = new URLSearchParams;
|
|
259380
|
+
if (filters.status) {
|
|
259381
|
+
params.set("status", filters.status);
|
|
259382
|
+
}
|
|
259383
|
+
if (filters.since) {
|
|
259384
|
+
params.set("since", filters.since);
|
|
259385
|
+
}
|
|
259386
|
+
if (filters.limit !== undefined) {
|
|
259387
|
+
params.set("limit", String(filters.limit));
|
|
259388
|
+
}
|
|
259389
|
+
return params;
|
|
259390
|
+
}
|
|
259391
|
+
async function listWorkflowRuns(filters = {}) {
|
|
259392
|
+
const appClient = getAppClient();
|
|
259393
|
+
let response;
|
|
259394
|
+
try {
|
|
259395
|
+
response = await appClient.get("workflows/runs", {
|
|
259396
|
+
searchParams: buildRunsQueryString(filters)
|
|
259397
|
+
});
|
|
259398
|
+
} catch (error48) {
|
|
259399
|
+
throw await ApiError.fromHttpError(error48, "listing workflow runs");
|
|
259400
|
+
}
|
|
259401
|
+
const result = ListWorkflowRunsResponseSchema.safeParse(await response.json());
|
|
259402
|
+
if (!result.success) {
|
|
259403
|
+
throw new SchemaValidationError("Invalid workflow runs response from server", result.error);
|
|
259404
|
+
}
|
|
259405
|
+
return result.data;
|
|
259406
|
+
}
|
|
259407
|
+
// src/cli/commands/workflows/legacy-app.ts
|
|
259408
|
+
var isWorkflowsNotEnabled = (error48) => error48 instanceof ApiError && error48.statusCode === 403;
|
|
259409
|
+
function rethrowLegacyAppAsExplanation(error48) {
|
|
259410
|
+
if (isWorkflowsNotEnabled(error48)) {
|
|
259411
|
+
throw new InvalidInputError("Workflows are not enabled for this app — it predates the Workflows system, so its automation runs are not readable via this command.");
|
|
259412
|
+
}
|
|
259413
|
+
throw error48;
|
|
259414
|
+
}
|
|
259415
|
+
|
|
259416
|
+
// src/cli/commands/workflows/limit.ts
|
|
259417
|
+
var MAX_LIMIT = 200;
|
|
259418
|
+
function parseLimit(limit) {
|
|
259419
|
+
if (limit === undefined)
|
|
259420
|
+
return;
|
|
259421
|
+
const parsed = Number.parseInt(limit, 10);
|
|
259422
|
+
if (Number.isNaN(parsed) || parsed < 1 || parsed > MAX_LIMIT) {
|
|
259423
|
+
throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and ${MAX_LIMIT}.`);
|
|
259424
|
+
}
|
|
259425
|
+
return parsed;
|
|
259426
|
+
}
|
|
259427
|
+
|
|
259428
|
+
// src/cli/commands/workflows/list.ts
|
|
259429
|
+
function formatWorkflowLine(workflow) {
|
|
259430
|
+
const lastRun = workflow.lastRunAt ? `last run ${workflow.lastRunStatus ?? "unknown"} at ${workflow.lastRunAt}` : "never ran";
|
|
259431
|
+
const failures = workflow.consecutiveFailures > 0 ? ` (${workflow.consecutiveFailures} consecutive failures)` : "";
|
|
259432
|
+
return `${workflow.name} [${workflow.status}] runs: ${workflow.totalRuns}, ${lastRun}${failures}`;
|
|
259433
|
+
}
|
|
259434
|
+
async function listAction({ log, runTask: runTask2, jsonMode }, options8) {
|
|
259435
|
+
const limit = parseLimit(options8.limit);
|
|
259436
|
+
const workflows = await runTask2("Fetching workflows from Base44", async () => listWorkflows(limit).catch(rethrowLegacyAppAsExplanation), {
|
|
259437
|
+
successMessage: "Workflows fetched successfully",
|
|
259438
|
+
errorMessage: "Failed to fetch workflows"
|
|
259439
|
+
});
|
|
259440
|
+
if (jsonMode) {
|
|
259441
|
+
return {
|
|
259442
|
+
outroMessage: `Found ${workflows.length} workflows.`,
|
|
259443
|
+
stdout: `${JSON.stringify({ workflows }, null, 2)}
|
|
259444
|
+
`
|
|
259445
|
+
};
|
|
259446
|
+
}
|
|
259447
|
+
if (workflows.length === 0) {
|
|
259448
|
+
return { outroMessage: "This app has no workflows." };
|
|
259449
|
+
}
|
|
259450
|
+
for (const workflow of workflows) {
|
|
259451
|
+
log.info(formatWorkflowLine(workflow));
|
|
259452
|
+
}
|
|
259453
|
+
return { outroMessage: `Found ${workflows.length} workflows.` };
|
|
259454
|
+
}
|
|
259455
|
+
function getWorkflowsListCommand() {
|
|
259456
|
+
return new Base44Command("list").description("List this app's workflows").option("-n, --limit <n>", `Number of workflows to return (1-${MAX_LIMIT}, default: 30)`).action(listAction);
|
|
259457
|
+
}
|
|
259458
|
+
|
|
259459
|
+
// src/cli/commands/workflows/runs.ts
|
|
259460
|
+
function formatDuration2(durationMs) {
|
|
259461
|
+
if (durationMs === 0)
|
|
259462
|
+
return "";
|
|
259463
|
+
return ` ${(durationMs / 1000).toFixed(1)}s`;
|
|
259464
|
+
}
|
|
259465
|
+
function formatRunTags(run) {
|
|
259466
|
+
const tags = [run.triggerType, run.isTestRun ? "test" : null].filter(Boolean);
|
|
259467
|
+
return tags.length > 0 ? ` (${tags.join(", ")})` : "";
|
|
259468
|
+
}
|
|
259469
|
+
function formatFailureDetail(run) {
|
|
259470
|
+
const reason = run.statusReason ? ` [${run.statusReason}]` : "";
|
|
259471
|
+
const message = run.errorMessage ? `
|
|
259472
|
+
${run.errorMessage}` : "";
|
|
259473
|
+
return `${reason}${message}`;
|
|
259474
|
+
}
|
|
259475
|
+
function formatRunLine(run) {
|
|
259476
|
+
const time3 = (run.startedAt ?? "").substring(0, 19).replace("T", " ");
|
|
259477
|
+
const status = run.status.toUpperCase().padEnd(9);
|
|
259478
|
+
const base = `${time3} ${status} ${run.workflowName}${formatRunTags(run)}${formatDuration2(run.durationMs)}`;
|
|
259479
|
+
const failureDetail = run.status === "failed" || run.status === "cancelled" ? formatFailureDetail(run) : "";
|
|
259480
|
+
return `${base}${failureDetail}`;
|
|
259481
|
+
}
|
|
259482
|
+
async function describeEmptyResult(hasFilters) {
|
|
259483
|
+
const workflows = await listWorkflows().catch(() => null);
|
|
259484
|
+
if (workflows === null) {
|
|
259485
|
+
return "No runs found.";
|
|
259486
|
+
}
|
|
259487
|
+
if (workflows.length === 0) {
|
|
259488
|
+
return "This app has no workflows, so there are no runs.";
|
|
259489
|
+
}
|
|
259490
|
+
const names = workflows.map((workflow) => workflow.name).join(", ");
|
|
259491
|
+
return hasFilters ? `No runs match your filters. Workflows in this app: ${names}.` : `No runs yet. Workflows in this app: ${names}.`;
|
|
259492
|
+
}
|
|
259493
|
+
async function runsAction(ctx, options8) {
|
|
259494
|
+
const limit = parseLimit(options8.limit);
|
|
259495
|
+
const runs = await ctx.runTask("Fetching workflow runs from Base44", async () => listWorkflowRuns({
|
|
259496
|
+
status: options8.status,
|
|
259497
|
+
since: options8.since,
|
|
259498
|
+
limit
|
|
259499
|
+
}).catch(rethrowLegacyAppAsExplanation), {
|
|
259500
|
+
successMessage: "Workflow runs fetched successfully",
|
|
259501
|
+
errorMessage: "Failed to fetch workflow runs"
|
|
259502
|
+
});
|
|
259503
|
+
if (ctx.jsonMode) {
|
|
259504
|
+
return {
|
|
259505
|
+
outroMessage: `Found ${runs.length} runs.`,
|
|
259506
|
+
stdout: `${JSON.stringify({ runs }, null, 2)}
|
|
259507
|
+
`
|
|
259508
|
+
};
|
|
259509
|
+
}
|
|
259510
|
+
if (runs.length === 0) {
|
|
259511
|
+
const hasFilters = Boolean(options8.status || options8.since);
|
|
259512
|
+
return { outroMessage: await describeEmptyResult(hasFilters) };
|
|
259513
|
+
}
|
|
259514
|
+
for (const run of runs) {
|
|
259515
|
+
ctx.log.info(formatRunLine(run));
|
|
259516
|
+
}
|
|
259517
|
+
return { outroMessage: `Found ${runs.length} runs.` };
|
|
259518
|
+
}
|
|
259519
|
+
function getWorkflowsRunsCommand() {
|
|
259520
|
+
return new Base44Command("runs").description("List workflow runs for this app, newest first (includes scheduled, manual, and test runs)").addOption(new Option("--status <status>", "Filter by run status").choices([
|
|
259521
|
+
...WorkflowRunStatusSchema.options
|
|
259522
|
+
])).option("--since <datetime>", "Show runs started after this time. ISO datetime or relative shorthand (e.g. 1h, 30m, 2d)", normalizeDatetime).option("-n, --limit <n>", `Number of runs to return (1-${MAX_LIMIT}, default: 30)`).action(runsAction);
|
|
259523
|
+
}
|
|
259524
|
+
|
|
259525
|
+
// src/cli/commands/workflows/index.ts
|
|
259526
|
+
function getWorkflowsCommand() {
|
|
259527
|
+
return new Command("workflows").description("Inspect this app's workflows and their runs").addCommand(getWorkflowsListCommand()).addCommand(getWorkflowsRunsCommand());
|
|
259528
|
+
}
|
|
259529
|
+
|
|
259270
259530
|
// src/cli/commands/workspace/shared.ts
|
|
259271
259531
|
function workspaceTag(workspace2) {
|
|
259272
259532
|
const role = workspace2.userRole ?? "member";
|
|
@@ -260261,7 +260521,8 @@ var fieldTypes = [
|
|
|
260261
260521
|
"number",
|
|
260262
260522
|
"boolean",
|
|
260263
260523
|
"array",
|
|
260264
|
-
"object"
|
|
260524
|
+
"object",
|
|
260525
|
+
"null"
|
|
260265
260526
|
];
|
|
260266
260527
|
|
|
260267
260528
|
class Validator {
|
|
@@ -260321,6 +260582,14 @@ class Validator {
|
|
|
260321
260582
|
if (!property) {
|
|
260322
260583
|
return { hasError: false };
|
|
260323
260584
|
}
|
|
260585
|
+
if (Array.isArray(property.type)) {
|
|
260586
|
+
const types = property.type;
|
|
260587
|
+
const matched = types.some((type) => !this.validateValue(value, { ...property, type }, fieldPath).hasError);
|
|
260588
|
+
return matched ? { hasError: false } : {
|
|
260589
|
+
hasError: true,
|
|
260590
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be a valid ${types.join(" or ")}`)
|
|
260591
|
+
};
|
|
260592
|
+
}
|
|
260324
260593
|
const propertyType = property.type;
|
|
260325
260594
|
if (!fieldTypes.includes(propertyType)) {
|
|
260326
260595
|
return {
|
|
@@ -260361,6 +260630,14 @@ class Validator {
|
|
|
260361
260630
|
}
|
|
260362
260631
|
}
|
|
260363
260632
|
break;
|
|
260633
|
+
case "null":
|
|
260634
|
+
if (value !== null) {
|
|
260635
|
+
return {
|
|
260636
|
+
hasError: true,
|
|
260637
|
+
error: this.createValidationError(`Error in field ${fieldPath}: Input should be null`)
|
|
260638
|
+
};
|
|
260639
|
+
}
|
|
260640
|
+
break;
|
|
260364
260641
|
case "integer":
|
|
260365
260642
|
if (!Number.isInteger(value)) {
|
|
260366
260643
|
return {
|
|
@@ -260780,7 +261057,9 @@ function evaluateCondition(condition, record2, user) {
|
|
|
260780
261057
|
function checkRLS(rule, record2, user) {
|
|
260781
261058
|
if (user?.is_service === true)
|
|
260782
261059
|
return true;
|
|
260783
|
-
if (rule === undefined)
|
|
261060
|
+
if (rule === undefined || rule === null || rule === "")
|
|
261061
|
+
return true;
|
|
261062
|
+
if (typeof rule === "object" && Object.keys(rule).length === 0)
|
|
260784
261063
|
return true;
|
|
260785
261064
|
if (typeof rule === "boolean")
|
|
260786
261065
|
return rule;
|
|
@@ -263331,6 +263610,10 @@ function validateDevOptions(command2) {
|
|
|
263331
263610
|
if (appId !== undefined) {
|
|
263332
263611
|
command2.error(`base44 dev cannot be used with --app-id or ${BASE44_APP_ID_ENV_VAR}.`);
|
|
263333
263612
|
}
|
|
263613
|
+
const { port, remote } = command2.opts();
|
|
263614
|
+
if (remote && port !== undefined) {
|
|
263615
|
+
command2.error("--port applies to the local backend, which --remote does not start.");
|
|
263616
|
+
}
|
|
263334
263617
|
}
|
|
263335
263618
|
function requireLinkedProject({ app }) {
|
|
263336
263619
|
if (!app?.projectRoot) {
|
|
@@ -263338,31 +263621,44 @@ function requireLinkedProject({ app }) {
|
|
|
263338
263621
|
}
|
|
263339
263622
|
return { id: app.id, projectRoot: app.projectRoot };
|
|
263340
263623
|
}
|
|
263341
|
-
async function
|
|
263624
|
+
async function resolveConfiguredSite(app) {
|
|
263342
263625
|
const { project: project2 } = await readProjectConfig(app.projectRoot);
|
|
263343
263626
|
const serveCommand = project2.site?.serveCommand;
|
|
263344
|
-
|
|
263345
|
-
return;
|
|
263346
|
-
}
|
|
263347
|
-
return createServeCommandRunner({
|
|
263348
|
-
serveCommand,
|
|
263349
|
-
projectRoot: project2.root,
|
|
263350
|
-
appId: app.id,
|
|
263351
|
-
appBaseUrl: backendUrl
|
|
263352
|
-
});
|
|
263627
|
+
return serveCommand ? { serveCommand, projectRoot: project2.root } : undefined;
|
|
263353
263628
|
}
|
|
263354
|
-
function
|
|
263629
|
+
function stopRunnerOnProcessSignals(runner) {
|
|
263355
263630
|
const stop2 = () => void runner.stop();
|
|
263356
263631
|
process.on("SIGINT", stop2);
|
|
263357
263632
|
process.on("SIGTERM", stop2);
|
|
263633
|
+
}
|
|
263634
|
+
function startServeCommand(runner, backend) {
|
|
263635
|
+
stopRunnerOnProcessSignals(runner);
|
|
263358
263636
|
runner.onExit(() => {
|
|
263359
263637
|
backend.shutdown().finally(() => process.exit(1));
|
|
263360
263638
|
});
|
|
263361
263639
|
createDevLogger("backend", theme.styles.info).log(`Backend running on ${backend.url}`);
|
|
263362
263640
|
runner.start();
|
|
263363
263641
|
}
|
|
263364
|
-
async function
|
|
263365
|
-
const
|
|
263642
|
+
async function remoteDevAction(app) {
|
|
263643
|
+
const site2 = await resolveConfiguredSite(app);
|
|
263644
|
+
if (!site2) {
|
|
263645
|
+
throw new ConfigInvalidError("base44 dev --remote serves the frontend against the production backend, but this project has no site.serveCommand in base44/config.jsonc.");
|
|
263646
|
+
}
|
|
263647
|
+
const appBaseUrl = await getSiteUrl();
|
|
263648
|
+
const runner = createServeCommandRunner({
|
|
263649
|
+
...site2,
|
|
263650
|
+
appId: app.id,
|
|
263651
|
+
appBaseUrl
|
|
263652
|
+
});
|
|
263653
|
+
stopRunnerOnProcessSignals(runner);
|
|
263654
|
+
runner.onExit((code2) => process.exit(code2 ?? 1));
|
|
263655
|
+
runner.start();
|
|
263656
|
+
return {
|
|
263657
|
+
outroMessage: `Frontend dev server targets ${theme.styles.bold(appBaseUrl)} — every write hits your live app`
|
|
263658
|
+
};
|
|
263659
|
+
}
|
|
263660
|
+
async function localDevAction(ctx, app, options8) {
|
|
263661
|
+
const site2 = await resolveConfiguredSite(app);
|
|
263366
263662
|
const siteUrlPromise = getSiteUrl().catch(() => {
|
|
263367
263663
|
return;
|
|
263368
263664
|
});
|
|
@@ -263377,15 +263673,23 @@ async function devAction(ctx, options8) {
|
|
|
263377
263673
|
}
|
|
263378
263674
|
});
|
|
263379
263675
|
const backendUrl = localServerUrl(backend.port);
|
|
263380
|
-
|
|
263381
|
-
|
|
263676
|
+
if (site2) {
|
|
263677
|
+
const runner = createServeCommandRunner({
|
|
263678
|
+
...site2,
|
|
263679
|
+
appId: app.id,
|
|
263680
|
+
appBaseUrl: backendUrl
|
|
263681
|
+
});
|
|
263382
263682
|
startServeCommand(runner, { url: backendUrl, shutdown: backend.shutdown });
|
|
263383
263683
|
}
|
|
263384
|
-
const outroMessage =
|
|
263684
|
+
const outroMessage = site2 ? "Open your app using the frontend dev server URL" : `Dev server is available at ${theme.colors.links(backendUrl)}`;
|
|
263385
263685
|
return { outroMessage };
|
|
263386
263686
|
}
|
|
263687
|
+
async function devAction(ctx, options8) {
|
|
263688
|
+
const app = requireLinkedProject(ctx);
|
|
263689
|
+
return options8.remote ? remoteDevAction(app) : localDevAction(ctx, app, options8);
|
|
263690
|
+
}
|
|
263387
263691
|
function getDevCommand() {
|
|
263388
|
-
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").hook("preAction", validateDevOptions).action(devAction);
|
|
263692
|
+
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);
|
|
263389
263693
|
}
|
|
263390
263694
|
|
|
263391
263695
|
// src/core/exec/run-script.ts
|
|
@@ -263648,6 +263952,7 @@ function createProgram(context) {
|
|
|
263648
263952
|
program2.addCommand(getAgentSkillsCommand());
|
|
263649
263953
|
program2.addCommand(getConnectorsCommand());
|
|
263650
263954
|
program2.addCommand(getFunctionsCommand());
|
|
263955
|
+
program2.addCommand(getWorkflowsCommand());
|
|
263651
263956
|
program2.addCommand(getSecretsCommand());
|
|
263652
263957
|
program2.addCommand(getSandboxCommand());
|
|
263653
263958
|
program2.addCommand(getAuthCommand());
|
|
@@ -267903,4 +268208,4 @@ export {
|
|
|
267903
268208
|
CLIExitError
|
|
267904
268209
|
};
|
|
267905
268210
|
|
|
267906
|
-
//# debugId=
|
|
268211
|
+
//# debugId=BD8B328810C7720964756E2164756E21
|