@base44-preview/cli 0.1.32-pr.663.57b7b28 → 0.1.32-pr.663.8c44c88
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 +2 -1
- package/dist/cli/index.js +394 -94
- package/dist/cli/index.js.map +20 -18
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -248042,28 +248042,6 @@ function getAgentsCommand() {
|
|
|
248042
248042
|
return new Command2("agents").description("Manage project agents").addCommand(getAgentsPushCommand()).addCommand(getAgentsPullCommand());
|
|
248043
248043
|
}
|
|
248044
248044
|
|
|
248045
|
-
// src/core/api-spec/body.ts
|
|
248046
|
-
var METHODS_WITHOUT_BODY = new Set(["GET", "HEAD"]);
|
|
248047
|
-
async function resolveRequestBody(method, flag, source) {
|
|
248048
|
-
const takesBody = !METHODS_WITHOUT_BODY.has(method.toUpperCase());
|
|
248049
|
-
if (flag !== undefined && !takesBody) {
|
|
248050
|
-
throw new InvalidInputError(`${method.toUpperCase()} requests cannot have a body.`);
|
|
248051
|
-
}
|
|
248052
|
-
if (flag === "@-") {
|
|
248053
|
-
return source.readStdin();
|
|
248054
|
-
}
|
|
248055
|
-
if (flag?.startsWith("@")) {
|
|
248056
|
-
return readTextFile(flag.slice(1));
|
|
248057
|
-
}
|
|
248058
|
-
if (flag !== undefined) {
|
|
248059
|
-
return flag;
|
|
248060
|
-
}
|
|
248061
|
-
if (!takesBody || source.stdinIsTTY) {
|
|
248062
|
-
return;
|
|
248063
|
-
}
|
|
248064
|
-
const piped = await source.readStdin();
|
|
248065
|
-
return piped.trim() ? piped : undefined;
|
|
248066
|
-
}
|
|
248067
248045
|
// ../../node_modules/minisearch/dist/es/index.js
|
|
248068
248046
|
var ENTRIES = "ENTRIES";
|
|
248069
248047
|
var KEYS = "KEYS";
|
|
@@ -249128,12 +249106,7 @@ var BOOST = { path: 8, summary: 5, description: 2, parameters: 0.5 };
|
|
|
249128
249106
|
var MIN_RELATIVE_SCORE = 0.2;
|
|
249129
249107
|
var TOKEN_SEPARATOR = /[\n\r\p{Z}\p{P}\p{S}]+/u;
|
|
249130
249108
|
function toOperationSummary(op) {
|
|
249131
|
-
return {
|
|
249132
|
-
method: op.method,
|
|
249133
|
-
path: op.path,
|
|
249134
|
-
summary: op.summary,
|
|
249135
|
-
readOnly: op.readOnly
|
|
249136
|
-
};
|
|
249109
|
+
return { endpoint: op.endpoint, summary: op.summary };
|
|
249137
249110
|
}
|
|
249138
249111
|
function buildSearchIndex(operations) {
|
|
249139
249112
|
const index = new MiniSearch({
|
|
@@ -249164,16 +249137,55 @@ function searchOperations(operations, query, options = {}) {
|
|
|
249164
249137
|
});
|
|
249165
249138
|
}
|
|
249166
249139
|
|
|
249140
|
+
// src/core/api-spec/catalog.ts
|
|
249141
|
+
var INLINE_AREA_MAX = 2;
|
|
249142
|
+
var AREA_SAMPLE_MAX = 3;
|
|
249143
|
+
var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
249144
|
+
function areaOf(path) {
|
|
249145
|
+
const parts = path.split("/").filter(Boolean);
|
|
249146
|
+
const appIdIndex = parts.indexOf("{app_id}");
|
|
249147
|
+
if (appIdIndex !== -1 && appIdIndex + 1 < parts.length) {
|
|
249148
|
+
return parts[appIdIndex + 1] ?? "other";
|
|
249149
|
+
}
|
|
249150
|
+
if (parts[0] === "api" && parts.length > 1) {
|
|
249151
|
+
return parts[1] ?? "other";
|
|
249152
|
+
}
|
|
249153
|
+
return parts[0] ?? "other";
|
|
249154
|
+
}
|
|
249155
|
+
function groupByArea(operations) {
|
|
249156
|
+
const sorted = [...operations].sort((a, b) => byCodePoint(`${a.method} ${a.path}`, `${b.method} ${b.path}`));
|
|
249157
|
+
const areas = new Map;
|
|
249158
|
+
for (const op of sorted) {
|
|
249159
|
+
const area = areaOf(op.path);
|
|
249160
|
+
areas.set(area, [...areas.get(area) ?? [], op]);
|
|
249161
|
+
}
|
|
249162
|
+
return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
|
|
249163
|
+
}
|
|
249164
|
+
function readsFirst(ops) {
|
|
249165
|
+
const isRead = (op) => op.method === "GET" ? 0 : 1;
|
|
249166
|
+
return [...ops].sort((a, b) => isRead(a) - isRead(b));
|
|
249167
|
+
}
|
|
249168
|
+
function catalogIndex(operations) {
|
|
249169
|
+
const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
|
|
249170
|
+
area,
|
|
249171
|
+
operationCount: ops.length,
|
|
249172
|
+
sample: readsFirst(ops).slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
|
|
249173
|
+
});
|
|
249174
|
+
return { areas, total: operations.length };
|
|
249175
|
+
}
|
|
249167
249176
|
// src/core/api-spec/grep.ts
|
|
249168
249177
|
var CONTEXT_CHARS = 40;
|
|
249169
249178
|
var MAX_SNIPPETS = 3;
|
|
249170
249179
|
var MAX_SNIPPET_CHARS = 200;
|
|
249180
|
+
function unescapeJson(snippet) {
|
|
249181
|
+
return snippet.replace(/\\[nrt]/g, " ").replace(/\\"/g, '"');
|
|
249182
|
+
}
|
|
249171
249183
|
function snippets(text, pattern) {
|
|
249172
249184
|
const found = [];
|
|
249173
249185
|
for (const match of text.matchAll(pattern)) {
|
|
249174
249186
|
const start = Math.max(0, match.index - CONTEXT_CHARS);
|
|
249175
249187
|
const end = match.index + match[0].length + CONTEXT_CHARS;
|
|
249176
|
-
found.push(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS)));
|
|
249188
|
+
found.push(unescapeJson(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS))));
|
|
249177
249189
|
if (found.length === MAX_SNIPPETS || match[0].length === 0) {
|
|
249178
249190
|
break;
|
|
249179
249191
|
}
|
|
@@ -249183,13 +249195,16 @@ function snippets(text, pattern) {
|
|
|
249183
249195
|
function grepSpec(spec, operations, pattern, options = {}) {
|
|
249184
249196
|
const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
|
|
249185
249197
|
const hits = [];
|
|
249186
|
-
|
|
249187
|
-
|
|
249198
|
+
const selected = (op) => (options.area === undefined || areaOf(op.path) === options.area) && (!options.readOnly || op.readOnly);
|
|
249199
|
+
for (const op of operations.filter(selected)) {
|
|
249200
|
+
const { summary, description, parameters, requestBody, responses } = op.operation;
|
|
249201
|
+
const matches = snippets(`${op.endpoint} ${JSON.stringify({ summary, description, parameters, requestBody, responses })}`, regex);
|
|
249188
249202
|
if (matches.length > 0) {
|
|
249189
249203
|
hits.push({ ...toOperationSummary(op), matches });
|
|
249190
249204
|
}
|
|
249191
249205
|
}
|
|
249192
|
-
|
|
249206
|
+
const schemas = options.area === undefined && !options.readOnly ? spec.components?.schemas : {};
|
|
249207
|
+
for (const [schema, definition] of Object.entries(schemas ?? {})) {
|
|
249193
249208
|
const matches = snippets(JSON.stringify(definition), regex);
|
|
249194
249209
|
if (matches.length > 0) {
|
|
249195
249210
|
hits.push({ schema, matches });
|
|
@@ -249213,7 +249228,16 @@ var ParameterSchema = looseObject({
|
|
|
249213
249228
|
in: string2(),
|
|
249214
249229
|
required: boolean2().optional(),
|
|
249215
249230
|
description: string2().optional(),
|
|
249216
|
-
schema: unknown().optional()
|
|
249231
|
+
schema: unknown().optional(),
|
|
249232
|
+
example: unknown().optional()
|
|
249233
|
+
});
|
|
249234
|
+
var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
|
|
249235
|
+
var RequestBodySchema = looseObject({
|
|
249236
|
+
content: MediaTypesSchema.optional()
|
|
249237
|
+
});
|
|
249238
|
+
var ResponseObjectSchema = looseObject({
|
|
249239
|
+
description: string2().optional(),
|
|
249240
|
+
content: MediaTypesSchema.optional()
|
|
249217
249241
|
});
|
|
249218
249242
|
var SecurityRequirementSchema = record(string2(), array(string2()));
|
|
249219
249243
|
var OperationSchema = looseObject({
|
|
@@ -249256,6 +249280,7 @@ function listOperations(spec) {
|
|
|
249256
249280
|
}
|
|
249257
249281
|
return [
|
|
249258
249282
|
{
|
|
249283
|
+
endpoint: `${method.toUpperCase()} ${path}`,
|
|
249259
249284
|
method: method.toUpperCase(),
|
|
249260
249285
|
path,
|
|
249261
249286
|
summary: operation.summary ?? "",
|
|
@@ -249298,46 +249323,73 @@ function matchOperation(operations, method, concretePath) {
|
|
|
249298
249323
|
});
|
|
249299
249324
|
return candidates.sort((a, b) => compareSpecificity(specificity(pathSegments(a.path)), specificity(pathSegments(b.path))))[0];
|
|
249300
249325
|
}
|
|
249301
|
-
|
|
249302
|
-
|
|
249303
|
-
|
|
249304
|
-
|
|
249305
|
-
|
|
249306
|
-
return;
|
|
249326
|
+
var SCHEMA_REF_PREFIX = "#/components/schemas/";
|
|
249327
|
+
var MAX_REF_DEPTH = 4;
|
|
249328
|
+
var FRAMEWORK_VALIDATION_ERROR = "Validation Error";
|
|
249329
|
+
function inlineRefs(node, schemas, seen = new Set, depth = 0) {
|
|
249330
|
+
if (depth > MAX_REF_DEPTH) {
|
|
249331
|
+
return node;
|
|
249307
249332
|
}
|
|
249308
|
-
if (
|
|
249309
|
-
return;
|
|
249333
|
+
if (Array.isArray(node)) {
|
|
249334
|
+
return node.map((item) => inlineRefs(item, schemas, seen, depth));
|
|
249310
249335
|
}
|
|
249311
|
-
|
|
249312
|
-
|
|
249313
|
-
|
|
249314
|
-
|
|
249315
|
-
|
|
249316
|
-
|
|
249317
|
-
|
|
249336
|
+
if (node === null || typeof node !== "object") {
|
|
249337
|
+
return node;
|
|
249338
|
+
}
|
|
249339
|
+
const { $ref, ...siblings } = node;
|
|
249340
|
+
if (typeof $ref === "string" && $ref.startsWith(SCHEMA_REF_PREFIX)) {
|
|
249341
|
+
const name = $ref.slice(SCHEMA_REF_PREFIX.length);
|
|
249342
|
+
if (seen.has(name) || !(name in schemas)) {
|
|
249343
|
+
return node;
|
|
249318
249344
|
}
|
|
249345
|
+
const resolved = inlineRefs(schemas[name], schemas, new Set([...seen, name]), depth + 1);
|
|
249346
|
+
return resolved !== null && typeof resolved === "object" ? { ...resolved, ...siblings } : resolved;
|
|
249319
249347
|
}
|
|
249348
|
+
return Object.fromEntries(Object.entries(node).map(([key, value]) => [
|
|
249349
|
+
key,
|
|
249350
|
+
inlineRefs(value, schemas, seen, depth)
|
|
249351
|
+
]));
|
|
249320
249352
|
}
|
|
249321
|
-
function
|
|
249322
|
-
|
|
249323
|
-
|
|
249324
|
-
}
|
|
249325
|
-
return ref.slice(2).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~")).reduce((node, part) => node !== null && typeof node === "object" ? node[part] : undefined, spec);
|
|
249353
|
+
function jsonSchemaOf(value) {
|
|
249354
|
+
const parsed = RequestBodySchema.safeParse(value);
|
|
249355
|
+
return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
|
|
249326
249356
|
}
|
|
249327
249357
|
function getOperationContract(spec, op) {
|
|
249328
|
-
const
|
|
249329
|
-
const
|
|
249330
|
-
|
|
249358
|
+
const schemas = spec.components?.schemas ?? {};
|
|
249359
|
+
const inline = (node) => node === undefined ? null : inlineRefs(node, schemas);
|
|
249360
|
+
const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
|
|
249361
|
+
const parsed = ResponseObjectSchema.safeParse(response);
|
|
249362
|
+
return parsed.success ? [[status, parsed.data]] : [];
|
|
249363
|
+
});
|
|
249364
|
+
const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
|
|
249365
|
+
const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
|
|
249331
249366
|
return {
|
|
249367
|
+
endpoint: op.endpoint,
|
|
249332
249368
|
method: op.method,
|
|
249333
249369
|
path: op.path,
|
|
249334
249370
|
summary: op.summary,
|
|
249335
249371
|
description: op.description,
|
|
249336
|
-
|
|
249337
|
-
|
|
249338
|
-
|
|
249339
|
-
|
|
249340
|
-
|
|
249372
|
+
parameters: (op.operation.parameters ?? []).flatMap((parameter) => {
|
|
249373
|
+
const parsed = ParameterSchema.safeParse(parameter);
|
|
249374
|
+
if (!parsed.success) {
|
|
249375
|
+
return [];
|
|
249376
|
+
}
|
|
249377
|
+
const { name, in: location2, required, schema, description } = parsed.data;
|
|
249378
|
+
const inSchema = schema !== null && typeof schema === "object" && "description" in schema;
|
|
249379
|
+
return [
|
|
249380
|
+
{
|
|
249381
|
+
name,
|
|
249382
|
+
in: location2,
|
|
249383
|
+
required: required ?? false,
|
|
249384
|
+
schema: inline(schema ?? {}),
|
|
249385
|
+
...description && !inSchema ? { description } : {},
|
|
249386
|
+
..."example" in parsed.data ? { example: parsed.data.example } : {}
|
|
249387
|
+
}
|
|
249388
|
+
];
|
|
249389
|
+
}),
|
|
249390
|
+
requestBodySchema: inline(jsonSchemaOf(op.operation.requestBody)),
|
|
249391
|
+
responseSchema: inline(success),
|
|
249392
|
+
errors: Object.fromEntries(errors.map(([status, response]) => [status, response.description ?? ""]))
|
|
249341
249393
|
};
|
|
249342
249394
|
}
|
|
249343
249395
|
// src/core/api-spec/request.ts
|
|
@@ -249348,7 +249400,11 @@ async function sendApiRequest(method, path, body) {
|
|
|
249348
249400
|
body,
|
|
249349
249401
|
headers: body === undefined ? {} : { "Content-Type": "application/json" }
|
|
249350
249402
|
});
|
|
249351
|
-
return
|
|
249403
|
+
return {
|
|
249404
|
+
status: response.status,
|
|
249405
|
+
contentType: response.headers.get("content-type") ?? "",
|
|
249406
|
+
body: new Uint8Array(await response.arrayBuffer())
|
|
249407
|
+
};
|
|
249352
249408
|
} catch (error) {
|
|
249353
249409
|
throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
|
|
249354
249410
|
}
|
|
@@ -249409,18 +249465,6 @@ function formatJson(value) {
|
|
|
249409
249465
|
return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
|
|
249410
249466
|
`;
|
|
249411
249467
|
}
|
|
249412
|
-
function formatResponseBody(text) {
|
|
249413
|
-
if (!text) {
|
|
249414
|
-
return "";
|
|
249415
|
-
}
|
|
249416
|
-
try {
|
|
249417
|
-
return formatJson(JSON.parse(text));
|
|
249418
|
-
} catch {
|
|
249419
|
-
return text.endsWith(`
|
|
249420
|
-
`) ? text : `${text}
|
|
249421
|
-
`;
|
|
249422
|
-
}
|
|
249423
|
-
}
|
|
249424
249468
|
function parseLimit(value) {
|
|
249425
249469
|
if (value === undefined) {
|
|
249426
249470
|
return;
|
|
@@ -249431,12 +249475,63 @@ function parseLimit(value) {
|
|
|
249431
249475
|
}
|
|
249432
249476
|
return n;
|
|
249433
249477
|
}
|
|
249478
|
+
var READ_ONLY_FILTER_HELP = "Only read-only operations";
|
|
249434
249479
|
var REFRESH_OPTION_HELP = "Fetch the API spec again instead of using the cached copy (kept 1 hour)";
|
|
249435
249480
|
function loadSpecTask({ runTask }, refresh) {
|
|
249436
249481
|
return runTask("Loading the API spec", () => loadSpec({ refresh }), {
|
|
249437
249482
|
successMessage: "Loaded the API spec"
|
|
249438
249483
|
});
|
|
249439
249484
|
}
|
|
249485
|
+
function operationsInArea(operations, area) {
|
|
249486
|
+
const areas = groupByArea(operations);
|
|
249487
|
+
const inArea = areas.get(area);
|
|
249488
|
+
if (!inArea) {
|
|
249489
|
+
throw new InvalidInputError(`Unknown API area: ${area}`, {
|
|
249490
|
+
details: [`Areas: ${[...areas.keys()].join(", ")}`],
|
|
249491
|
+
hints: [{ message: "List the areas", command: "base44 api catalog" }]
|
|
249492
|
+
});
|
|
249493
|
+
}
|
|
249494
|
+
return inArea;
|
|
249495
|
+
}
|
|
249496
|
+
async function readRequestBody(method, flag) {
|
|
249497
|
+
if (flag === "@-") {
|
|
249498
|
+
return readStdin("--body @-", { trim: false });
|
|
249499
|
+
}
|
|
249500
|
+
if (flag?.startsWith("@")) {
|
|
249501
|
+
return readTextFile(flag.slice(1));
|
|
249502
|
+
}
|
|
249503
|
+
if (flag !== undefined) {
|
|
249504
|
+
return flag;
|
|
249505
|
+
}
|
|
249506
|
+
if (method === "GET" || method === "HEAD" || process.stdin.isTTY) {
|
|
249507
|
+
return;
|
|
249508
|
+
}
|
|
249509
|
+
const piped = await readStdin("--body", { trim: false });
|
|
249510
|
+
return piped.trim() ? piped : undefined;
|
|
249511
|
+
}
|
|
249512
|
+
|
|
249513
|
+
// src/cli/commands/api/catalog.ts
|
|
249514
|
+
async function catalogAction(ctx, area, options) {
|
|
249515
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249516
|
+
const operations = listOperations(spec).filter((op) => !options.readOnly || op.readOnly);
|
|
249517
|
+
if (area === undefined) {
|
|
249518
|
+
return { stdout: formatJson(catalogIndex(operations)) };
|
|
249519
|
+
}
|
|
249520
|
+
const inArea = operationsInArea(operations, area);
|
|
249521
|
+
return {
|
|
249522
|
+
stdout: formatJson({
|
|
249523
|
+
area,
|
|
249524
|
+
operations: inArea.map(toOperationSummary),
|
|
249525
|
+
total: inArea.length
|
|
249526
|
+
})
|
|
249527
|
+
};
|
|
249528
|
+
}
|
|
249529
|
+
function getApiCatalogCommand() {
|
|
249530
|
+
return new Base44Command("catalog", {
|
|
249531
|
+
requireAuth: false,
|
|
249532
|
+
requireAppContext: false
|
|
249533
|
+
}).description("List the API's areas, or every operation in one area").argument("[area]", 'An area from the list, e.g. "workflows"').option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(catalogAction);
|
|
249534
|
+
}
|
|
249440
249535
|
|
|
249441
249536
|
// src/cli/commands/api/fetch.ts
|
|
249442
249537
|
async function findOperation(ctx, method, path, refresh) {
|
|
@@ -249454,6 +249549,36 @@ async function findOperation(ctx, method, path, refresh) {
|
|
|
249454
249549
|
}
|
|
249455
249550
|
return { spec, op };
|
|
249456
249551
|
}
|
|
249552
|
+
var TEXT_CONTENT_TYPES = [
|
|
249553
|
+
"json",
|
|
249554
|
+
"text/",
|
|
249555
|
+
"xml",
|
|
249556
|
+
"javascript",
|
|
249557
|
+
"x-www-form-urlencoded"
|
|
249558
|
+
];
|
|
249559
|
+
function isText(contentType) {
|
|
249560
|
+
return !contentType || TEXT_CONTENT_TYPES.some((hint) => contentType.toLowerCase().includes(hint));
|
|
249561
|
+
}
|
|
249562
|
+
async function formatResponse({ status, contentType, body }, output) {
|
|
249563
|
+
if (output !== undefined) {
|
|
249564
|
+
await writeFile(output, body);
|
|
249565
|
+
return formatJson({ status, contentType, bytes: body.length, output });
|
|
249566
|
+
}
|
|
249567
|
+
if (body.length === 0) {
|
|
249568
|
+
return formatJson({ status });
|
|
249569
|
+
}
|
|
249570
|
+
if (!isText(contentType)) {
|
|
249571
|
+
throw new InvalidInputError(`The response is binary (${contentType}, ${body.length} bytes), so it was not printed. The request was sent; add --output <file> to save the response.`);
|
|
249572
|
+
}
|
|
249573
|
+
const text = new TextDecoder().decode(body);
|
|
249574
|
+
try {
|
|
249575
|
+
return formatJson(JSON.parse(text));
|
|
249576
|
+
} catch {
|
|
249577
|
+
return text.endsWith(`
|
|
249578
|
+
`) ? text : `${text}
|
|
249579
|
+
`;
|
|
249580
|
+
}
|
|
249581
|
+
}
|
|
249457
249582
|
async function fetchAction(ctx, methodArg, path, options, command) {
|
|
249458
249583
|
if (!methodArg || !path) {
|
|
249459
249584
|
if (options.help) {
|
|
@@ -249462,12 +249587,6 @@ async function fetchAction(ctx, methodArg, path, options, command) {
|
|
|
249462
249587
|
throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
|
|
249463
249588
|
}
|
|
249464
249589
|
const method = methodArg.toUpperCase();
|
|
249465
|
-
if (!HTTP_METHODS.some((m) => m.toUpperCase() === method)) {
|
|
249466
|
-
throw new InvalidInputError(`Unknown HTTP method: ${methodArg}`);
|
|
249467
|
-
}
|
|
249468
|
-
if (!path.startsWith("/")) {
|
|
249469
|
-
throw new InvalidInputError(`The path must start with "/", got ${path}.`);
|
|
249470
|
-
}
|
|
249471
249590
|
if (options.help) {
|
|
249472
249591
|
const { spec, op } = await findOperation(ctx, method, path, options.refresh);
|
|
249473
249592
|
return { stdout: formatJson(getOperationContract(spec, op)) };
|
|
@@ -249478,19 +249597,19 @@ async function fetchAction(ctx, methodArg, path, options, command) {
|
|
|
249478
249597
|
throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
|
|
249479
249598
|
}
|
|
249480
249599
|
}
|
|
249481
|
-
const body = await resolveRequestBody(method, options.body, {
|
|
249482
|
-
stdinIsTTY: Boolean(process.stdin.isTTY),
|
|
249483
|
-
readStdin: () => readStdin("--body @-", { trim: false })
|
|
249484
|
-
});
|
|
249485
249600
|
await ensureAuth(ctx);
|
|
249486
|
-
const
|
|
249487
|
-
|
|
249601
|
+
const body = await readRequestBody(method, options.body);
|
|
249602
|
+
const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
|
|
249603
|
+
successMessage: `Called ${method} ${path}`,
|
|
249604
|
+
errorMessage: "Request failed"
|
|
249605
|
+
});
|
|
249606
|
+
return { stdout: await formatResponse(response, options.output) };
|
|
249488
249607
|
}
|
|
249489
249608
|
function getApiFetchCommand() {
|
|
249490
249609
|
return new Base44Command("fetch", {
|
|
249491
249610
|
requireAuth: false,
|
|
249492
249611
|
requireAppContext: false
|
|
249493
|
-
}).description("Call a Base44 API operation, like curl; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Concrete path with any query string, e.g. "/api/apps/<app-id>/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- for stdin (piped stdin is read too)").option("--read-only", "Refuse, before sending, any operation the spec does not mark read-only").option("--refresh", REFRESH_OPTION_HELP).option("-h, --help", "With a method and path, print that operation's contract; otherwise this help").action(fetchAction);
|
|
249612
|
+
}).description("Call a Base44 API operation, like curl; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Concrete path with any query string, e.g. "/api/apps/<app-id>/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- for stdin (piped stdin is read too)").option("--output <file>", "Save the response body to a file").option("--read-only", "Refuse, before sending, any operation the spec does not mark read-only").option("--refresh", REFRESH_OPTION_HELP).option("-h, --help", "With a method and path, print that operation's contract; otherwise this help").action(fetchAction);
|
|
249494
249613
|
}
|
|
249495
249614
|
|
|
249496
249615
|
// src/cli/commands/api/grep.ts
|
|
@@ -249505,9 +249624,15 @@ async function grepAction(ctx, pattern, options) {
|
|
|
249505
249624
|
const limit = parseLimit(options.limit);
|
|
249506
249625
|
assertValidRegex(pattern);
|
|
249507
249626
|
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249508
|
-
const
|
|
249627
|
+
const operations = listOperations(spec);
|
|
249628
|
+
if (options.area !== undefined) {
|
|
249629
|
+
operationsInArea(operations, options.area);
|
|
249630
|
+
}
|
|
249631
|
+
const hits = grepSpec(spec, operations, pattern, {
|
|
249632
|
+
area: options.area,
|
|
249509
249633
|
ignoreCase: options.ignoreCase,
|
|
249510
|
-
limit
|
|
249634
|
+
limit,
|
|
249635
|
+
readOnly: options.readOnly
|
|
249511
249636
|
});
|
|
249512
249637
|
return { stdout: formatJson(hits) };
|
|
249513
249638
|
}
|
|
@@ -249515,7 +249640,7 @@ function getApiGrepCommand() {
|
|
|
249515
249640
|
return new Base44Command("grep", {
|
|
249516
249641
|
requireAuth: false,
|
|
249517
249642
|
requireAppContext: false
|
|
249518
|
-
}).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
|
|
249643
|
+
}).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("--area <area>", "Search only one area's operations (see base44 api catalog)").option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
|
|
249519
249644
|
}
|
|
249520
249645
|
|
|
249521
249646
|
// src/cli/commands/api/search.ts
|
|
@@ -249532,12 +249657,12 @@ function getApiSearchCommand() {
|
|
|
249532
249657
|
return new Base44Command("search", {
|
|
249533
249658
|
requireAuth: false,
|
|
249534
249659
|
requireAppContext: false
|
|
249535
|
-
}).description("Search every Base44 API operation by what it does").argument("<text...>", 'What you are looking for, e.g. "failed workflow runs"').option("--limit <n>", "Most results to return (default 5)").option("--read-only",
|
|
249660
|
+
}).description("Search every Base44 API operation by what it does").argument("<text...>", 'What you are looking for, e.g. "failed workflow runs"').option("--limit <n>", "Most results to return (default 5)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(searchAction);
|
|
249536
249661
|
}
|
|
249537
249662
|
|
|
249538
249663
|
// src/cli/commands/api/index.ts
|
|
249539
249664
|
function getApiCommand() {
|
|
249540
|
-
return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
|
|
249665
|
+
return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiCatalogCommand()).addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
|
|
249541
249666
|
}
|
|
249542
249667
|
|
|
249543
249668
|
// src/cli/commands/auth/password-login.ts
|
|
@@ -254901,6 +255026,12 @@ var deno2 = Object.freeze({
|
|
|
254901
255026
|
});
|
|
254902
255027
|
globalThis.Deno = deno2;
|
|
254903
255028
|
globalThis.Buffer = Buffer2;
|
|
255029
|
+
try {
|
|
255030
|
+
new AsyncLocalStorage().enterWith(void 0);
|
|
255031
|
+
} catch {
|
|
255032
|
+
AsyncLocalStorage.prototype.enterWith = () => {
|
|
255033
|
+
};
|
|
255034
|
+
}
|
|
254904
255035
|
function getRegisteredHandler() {
|
|
254905
255036
|
return registeredHandler;
|
|
254906
255037
|
}
|
|
@@ -257866,7 +257997,7 @@ var TELEMETRY_PATCH = [
|
|
|
257866
257997
|
var TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
|
|
257867
257998
|
|
|
257868
257999
|
// ../functions-compiler/src/version.ts
|
|
257869
|
-
var COMPILER_VERSION = "0.1.
|
|
258000
|
+
var COMPILER_VERSION = "0.1.8";
|
|
257870
258001
|
|
|
257871
258002
|
// ../functions-compiler/src/worker-entry.ts
|
|
257872
258003
|
function denoShimSource() {
|
|
@@ -262490,6 +262621,174 @@ function runtimeVirtualPlugin() {
|
|
|
262490
262621
|
};
|
|
262491
262622
|
}
|
|
262492
262623
|
|
|
262624
|
+
// ../functions-compiler/src/esbuild/ws-native-virtual.ts
|
|
262625
|
+
var NAMESPACE4 = "base44-ws-native";
|
|
262626
|
+
var WS_SPECIFIER = /^(npm:)?ws(@[^/]+)?$/;
|
|
262627
|
+
var ADAPTER = `"use strict";
|
|
262628
|
+
const toBuffer = (value) => (globalThis.Buffer ? globalThis.Buffer.from(value) : value);
|
|
262629
|
+
const READY_STATES = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
|
|
262630
|
+
const later = (fn, ...args) => queueMicrotask(() => fn(...args));
|
|
262631
|
+
const upgradeHeaders = (options) => {
|
|
262632
|
+
const headers = new Headers(options?.headers);
|
|
262633
|
+
for (const name of headers.keys()) if (name !== "user-agent") return headers;
|
|
262634
|
+
return null;
|
|
262635
|
+
};
|
|
262636
|
+
class WebSocket {
|
|
262637
|
+
static CONNECTING = 0;
|
|
262638
|
+
static OPEN = 1;
|
|
262639
|
+
static CLOSING = 2;
|
|
262640
|
+
static CLOSED = 3;
|
|
262641
|
+
#socket = null;
|
|
262642
|
+
#state = 0;
|
|
262643
|
+
#url;
|
|
262644
|
+
#closeRequested = null;
|
|
262645
|
+
#terminated = false;
|
|
262646
|
+
#listeners = new Map();
|
|
262647
|
+
constructor(address, protocols, options) {
|
|
262648
|
+
if (protocols && typeof protocols === "object" && !Array.isArray(protocols)) {
|
|
262649
|
+
options = protocols;
|
|
262650
|
+
protocols = undefined;
|
|
262651
|
+
}
|
|
262652
|
+
this.#url = String(address);
|
|
262653
|
+
const headers = upgradeHeaders(options);
|
|
262654
|
+
if (headers) {
|
|
262655
|
+
this.#upgrade(headers, protocols);
|
|
262656
|
+
} else {
|
|
262657
|
+
this.#attach(new globalThis.WebSocket(this.#url, protocols));
|
|
262658
|
+
}
|
|
262659
|
+
}
|
|
262660
|
+
get readyState() {
|
|
262661
|
+
if (this.#terminated) return 3;
|
|
262662
|
+
return this.#socket ? this.#socket.readyState : this.#state;
|
|
262663
|
+
}
|
|
262664
|
+
get url() { return this.#url; }
|
|
262665
|
+
get protocol() { return this.#socket ? this.#socket.protocol ?? "" : ""; }
|
|
262666
|
+
on(name, listener) { return this.#add(name, listener, false); }
|
|
262667
|
+
addListener(name, listener) { return this.#add(name, listener, false); }
|
|
262668
|
+
once(name, listener) { return this.#add(name, listener, true); }
|
|
262669
|
+
off(name, listener) { return this.removeListener(name, listener); }
|
|
262670
|
+
removeListener(name, listener) {
|
|
262671
|
+
const listeners = this.#listeners.get(name);
|
|
262672
|
+
if (listeners) this.#listeners.set(name, listeners.filter((entry) => entry.listener !== listener));
|
|
262673
|
+
return this;
|
|
262674
|
+
}
|
|
262675
|
+
removeAllListeners(name) {
|
|
262676
|
+
if (name === undefined) this.#listeners.clear();
|
|
262677
|
+
else this.#listeners.delete(name);
|
|
262678
|
+
return this;
|
|
262679
|
+
}
|
|
262680
|
+
emit(name, ...args) {
|
|
262681
|
+
const listeners = this.#listeners.get(name) ?? [];
|
|
262682
|
+
this.#listeners.set(name, listeners.filter((entry) => !entry.once));
|
|
262683
|
+
for (const entry of listeners) entry.listener.apply(this, args);
|
|
262684
|
+
return listeners.length > 0;
|
|
262685
|
+
}
|
|
262686
|
+
send(data, options, callback) {
|
|
262687
|
+
const done = typeof options === "function" ? options : callback;
|
|
262688
|
+
try {
|
|
262689
|
+
if (!this.#socket) {
|
|
262690
|
+
throw new Error("WebSocket is not open: readyState " + this.#state + " (" + READY_STATES[this.#state] + ")");
|
|
262691
|
+
}
|
|
262692
|
+
this.#socket.send(data);
|
|
262693
|
+
done?.();
|
|
262694
|
+
} catch (error) {
|
|
262695
|
+
if (!done) throw error;
|
|
262696
|
+
done(error);
|
|
262697
|
+
}
|
|
262698
|
+
}
|
|
262699
|
+
close(code, reason) {
|
|
262700
|
+
if (this.#socket) this.#socket.close(code, reason);
|
|
262701
|
+
else if (this.#state === 0) {
|
|
262702
|
+
// Upgrade still in flight: close as soon as it lands.
|
|
262703
|
+
this.#closeRequested = [code, reason];
|
|
262704
|
+
this.#state = 2;
|
|
262705
|
+
}
|
|
262706
|
+
}
|
|
262707
|
+
// \`ws\` tears the connection down at once. workerd has no abrupt close, so the
|
|
262708
|
+
// socket is closed normally and "close" is reported now, not on the reply.
|
|
262709
|
+
terminate() {
|
|
262710
|
+
if (this.#terminated || this.readyState === 3) return;
|
|
262711
|
+
this.#terminated = true;
|
|
262712
|
+
if (this.#socket) {
|
|
262713
|
+
try { this.#socket.close(); } catch {}
|
|
262714
|
+
} else {
|
|
262715
|
+
// Upgrade still in flight: close it on arrival, without an "open".
|
|
262716
|
+
this.#closeRequested = [];
|
|
262717
|
+
this.#state = 3;
|
|
262718
|
+
}
|
|
262719
|
+
later(() => this.emit("close", 1006, toBuffer("")));
|
|
262720
|
+
}
|
|
262721
|
+
#attach(socket) {
|
|
262722
|
+
this.#socket = socket;
|
|
262723
|
+
try { socket.binaryType = "arraybuffer"; } catch {}
|
|
262724
|
+
socket.addEventListener("open", () => this.emit("open"));
|
|
262725
|
+
socket.addEventListener("message", (event) => {
|
|
262726
|
+
const isBinary = typeof event.data !== "string";
|
|
262727
|
+
this.emit("message", toBuffer(isBinary ? new Uint8Array(event.data) : event.data), isBinary);
|
|
262728
|
+
});
|
|
262729
|
+
socket.addEventListener("error", (event) => this.emit("error", event.error ?? new Error(event.message || "WebSocket error")));
|
|
262730
|
+
socket.addEventListener("close", (event) => {
|
|
262731
|
+
if (!this.#terminated) this.emit("close", event.code, toBuffer(event.reason ?? ""));
|
|
262732
|
+
});
|
|
262733
|
+
}
|
|
262734
|
+
#upgrade(headers, protocols) {
|
|
262735
|
+
headers.set("Upgrade", "websocket");
|
|
262736
|
+
if (protocols) headers.set("Sec-WebSocket-Protocol", [].concat(protocols).join(", "));
|
|
262737
|
+
const httpUrl = this.#url.replace(/^ws(s?):/i, "http$1:");
|
|
262738
|
+
const fail = (error) => {
|
|
262739
|
+
this.#state = 3;
|
|
262740
|
+
if (this.#terminated) return;
|
|
262741
|
+
this.emit("error", error);
|
|
262742
|
+
this.emit("close", 1006, toBuffer(""));
|
|
262743
|
+
};
|
|
262744
|
+
// Two-argument then(): an exception from an "open" listener must not be
|
|
262745
|
+
// reported as a failed upgrade.
|
|
262746
|
+
fetch(httpUrl, { headers }).then((response) => {
|
|
262747
|
+
const socket = response.webSocket;
|
|
262748
|
+
if (!socket) {
|
|
262749
|
+
response.body?.cancel();
|
|
262750
|
+
return fail(new Error("Unexpected server response: " + response.status));
|
|
262751
|
+
}
|
|
262752
|
+
socket.accept();
|
|
262753
|
+
this.#attach(socket);
|
|
262754
|
+
if (this.#closeRequested) return socket.close(...this.#closeRequested);
|
|
262755
|
+
// accept() opens the socket without dispatching an "open" event.
|
|
262756
|
+
this.emit("open");
|
|
262757
|
+
}, fail);
|
|
262758
|
+
}
|
|
262759
|
+
#add(name, listener, once) {
|
|
262760
|
+
const listeners = this.#listeners.get(name) ?? [];
|
|
262761
|
+
listeners.push({ listener, once });
|
|
262762
|
+
this.#listeners.set(name, listeners);
|
|
262763
|
+
return this;
|
|
262764
|
+
}
|
|
262765
|
+
}
|
|
262766
|
+
class WebSocketServer {
|
|
262767
|
+
constructor() {
|
|
262768
|
+
throw new Error("ws WebSocketServer is not available in Base44 functions: a function can open WebSocket connections but cannot listen for them.");
|
|
262769
|
+
}
|
|
262770
|
+
}
|
|
262771
|
+
module.exports = WebSocket;
|
|
262772
|
+
module.exports.WebSocket = WebSocket;
|
|
262773
|
+
module.exports.WebSocketServer = WebSocketServer;
|
|
262774
|
+
module.exports.default = WebSocket;
|
|
262775
|
+
`;
|
|
262776
|
+
function wsNativeVirtualPlugin() {
|
|
262777
|
+
return {
|
|
262778
|
+
name: "base44-ws-native",
|
|
262779
|
+
setup(build) {
|
|
262780
|
+
build.onResolve({ filter: WS_SPECIFIER }, () => ({
|
|
262781
|
+
path: "ws",
|
|
262782
|
+
namespace: NAMESPACE4
|
|
262783
|
+
}));
|
|
262784
|
+
build.onLoad({ filter: /.*/, namespace: NAMESPACE4 }, () => ({
|
|
262785
|
+
contents: ADAPTER,
|
|
262786
|
+
loader: "js"
|
|
262787
|
+
}));
|
|
262788
|
+
}
|
|
262789
|
+
};
|
|
262790
|
+
}
|
|
262791
|
+
|
|
262493
262792
|
// ../functions-compiler/src/deno-bundle.ts
|
|
262494
262793
|
async function bundleToModule(prepared, nodeModulesDir = "none") {
|
|
262495
262794
|
const dir = await mkdtemp(path21.join(tmpdir2(), "b44-bundle-"));
|
|
@@ -262513,6 +262812,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
|
|
|
262513
262812
|
sourcemap: false,
|
|
262514
262813
|
logLevel: "silent",
|
|
262515
262814
|
plugins: [
|
|
262815
|
+
wsNativeVirtualPlugin(),
|
|
262516
262816
|
nodeBuiltinRequirePlugin(),
|
|
262517
262817
|
userFilesPlugin(prepared.files, prepared.entry),
|
|
262518
262818
|
privateDataSourcesVirtualPlugin(),
|
|
@@ -272902,4 +273202,4 @@ export {
|
|
|
272902
273202
|
runCLI
|
|
272903
273203
|
};
|
|
272904
273204
|
|
|
272905
|
-
//# debugId=
|
|
273205
|
+
//# debugId=C89C416C808E439E64756E2164756E21
|