@base44-preview/cli 0.1.32-pr.663.d2e3c0d → 0.1.32-pr.663.da7454a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +203 -129
- package/dist/cli/index.js.map +14 -12
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -39570,9 +39570,9 @@ function tm(e, t, r) {
|
|
|
39570
39570
|
return l(["<", r("name"), r("typeArguments"), " ", ...e.map(r, "attributes"), n.selfClosing ? " />" : ">"]);
|
|
39571
39571
|
let i = n.attributes?.some((u) => V3(u.value) && u.value.value.includes(`
|
|
39572
39572
|
`)), o = t.singleAttributePerLine && n.attributes.length > 1 ? E : A;
|
|
39573
|
-
return l(["<", r("name"), r("typeArguments"), m(e.map(() => [o, r()], "attributes")), ...
|
|
39573
|
+
return l(["<", r("name"), r("typeArguments"), m(e.map(() => [o, r()], "attributes")), ...rm3(n, t, s)], { shouldBreak: i });
|
|
39574
39574
|
}
|
|
39575
|
-
function
|
|
39575
|
+
function rm3(e, t, r) {
|
|
39576
39576
|
return e.selfClosing ? [A, "/>"] : nm(e, t, r) ? [">"] : [f, ">"];
|
|
39577
39577
|
}
|
|
39578
39578
|
function nm(e, t, r) {
|
|
@@ -111521,7 +111521,7 @@ function N62(e) {
|
|
|
111521
111521
|
function nm2(e, t, a) {
|
|
111522
111522
|
return ie10(t, a, e.typeParameters) || ie10(t, a, e.parameters) || S7(t, e.type);
|
|
111523
111523
|
}
|
|
111524
|
-
function
|
|
111524
|
+
function rm4(e, t, a) {
|
|
111525
111525
|
return ie10(t, a, e.types);
|
|
111526
111526
|
}
|
|
111527
111527
|
function im2(e, t, a) {
|
|
@@ -114489,7 +114489,7 @@ ${Me.join(`
|
|
|
114489
114489
|
return S7(a, t.elementType);
|
|
114490
114490
|
}, 190: function(t, a, _) {
|
|
114491
114491
|
return ie10(a, _, t.elements);
|
|
114492
|
-
}, 193:
|
|
114492
|
+
}, 193: rm4, 194: rm4, 195: function(t, a, _) {
|
|
114493
114493
|
return S7(a, t.checkType) || S7(a, t.extendsType) || S7(a, t.trueType) || S7(a, t.falseType);
|
|
114494
114494
|
}, 196: function(t, a, _) {
|
|
114495
114495
|
return S7(a, t.typeParameter);
|
|
@@ -239451,7 +239451,7 @@ var package_default = {
|
|
|
239451
239451
|
jsonwebtoken: "^9.0.3",
|
|
239452
239452
|
ky: "^1.14.2",
|
|
239453
239453
|
lodash: "^4.17.23",
|
|
239454
|
-
minisearch: "7.1.2",
|
|
239454
|
+
minisearch: "^7.1.2",
|
|
239455
239455
|
ms: "^2.1.3",
|
|
239456
239456
|
multer: "^2.0.0",
|
|
239457
239457
|
nanoid: "^5.1.6",
|
|
@@ -249234,7 +249234,7 @@ var ParameterSchema = looseObject({
|
|
|
249234
249234
|
example: unknown().optional()
|
|
249235
249235
|
});
|
|
249236
249236
|
var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
|
|
249237
|
-
var
|
|
249237
|
+
var MediaContentSchema = looseObject({
|
|
249238
249238
|
content: MediaTypesSchema.optional()
|
|
249239
249239
|
});
|
|
249240
249240
|
var ResponseObjectSchema = looseObject({
|
|
@@ -249251,18 +249251,22 @@ var OperationSchema = looseObject({
|
|
|
249251
249251
|
responses: record(string2(), unknown()).optional(),
|
|
249252
249252
|
security: array(SecurityRequirementSchema).optional()
|
|
249253
249253
|
});
|
|
249254
|
-
var PathItemSchema = looseObject({
|
|
249255
|
-
...Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])),
|
|
249256
|
-
parameters: array(unknown()).optional()
|
|
249257
|
-
});
|
|
249258
249254
|
var OpenApiSpecSchema = looseObject({
|
|
249259
249255
|
openapi: string2(),
|
|
249260
|
-
paths: record(string2(),
|
|
249256
|
+
paths: record(string2(), record(string2(), unknown())),
|
|
249261
249257
|
components: looseObject({
|
|
249262
249258
|
schemas: record(string2(), unknown()).optional()
|
|
249263
249259
|
}).optional(),
|
|
249264
|
-
security: array(SecurityRequirementSchema).optional()
|
|
249260
|
+
security: array(SecurityRequirementSchema).optional().catch(undefined)
|
|
249265
249261
|
});
|
|
249262
|
+
var ParameterListSchema = array(unknown());
|
|
249263
|
+
|
|
249264
|
+
// src/core/api-spec/text.ts
|
|
249265
|
+
var DOCS_CALLOUT = /<(Info|Note|Tip|Check|Warning)>([\s\S]*?)<\/\1>/g;
|
|
249266
|
+
var RELATIVE_LINK = /\[([^\]]+)\]\(\/[^)]*\)/g;
|
|
249267
|
+
function cleanText(text) {
|
|
249268
|
+
return text.replace(DOCS_CALLOUT, (_, kind, body) => kind === "Warning" ? `Warning: ${body}` : body).replace(RELATIVE_LINK, "$1");
|
|
249269
|
+
}
|
|
249266
249270
|
|
|
249267
249271
|
// src/core/api-spec/operations.ts
|
|
249268
249272
|
var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
|
|
@@ -249274,9 +249278,19 @@ function isReadOnly(operation, spec) {
|
|
|
249274
249278
|
function parameterText(operation) {
|
|
249275
249279
|
return (operation.parameters ?? []).flatMap((parameter) => {
|
|
249276
249280
|
const parsed = ParameterSchema.safeParse(parameter);
|
|
249277
|
-
return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
|
|
249281
|
+
return parsed.success ? [parsed.data.name, cleanText(parsed.data.description ?? "")] : [];
|
|
249278
249282
|
}).join(" ");
|
|
249279
249283
|
}
|
|
249284
|
+
var COMPONENT_REF = /^#\/components\/([^/]+)\/([^/]+)$/;
|
|
249285
|
+
function resolveComponentRef(spec, value) {
|
|
249286
|
+
const ref = value !== null && typeof value === "object" ? value.$ref : undefined;
|
|
249287
|
+
const match = typeof ref === "string" ? COMPONENT_REF.exec(ref) : null;
|
|
249288
|
+
if (!match?.[1] || !match[2]) {
|
|
249289
|
+
return value;
|
|
249290
|
+
}
|
|
249291
|
+
const components = spec.components;
|
|
249292
|
+
return components?.[match[1]]?.[match[2]] ?? value;
|
|
249293
|
+
}
|
|
249280
249294
|
function mergeParameters(shared, own) {
|
|
249281
249295
|
if (!shared?.length) {
|
|
249282
249296
|
return own;
|
|
@@ -249293,13 +249307,15 @@ function mergeParameters(shared, own) {
|
|
|
249293
249307
|
}
|
|
249294
249308
|
function listOperations(spec) {
|
|
249295
249309
|
return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
|
|
249296
|
-
const
|
|
249297
|
-
if (!
|
|
249310
|
+
const parsed = OperationSchema.safeParse(item[method]);
|
|
249311
|
+
if (!parsed.success) {
|
|
249298
249312
|
return [];
|
|
249299
249313
|
}
|
|
249314
|
+
const shared = ParameterListSchema.safeParse(item.parameters);
|
|
249315
|
+
const resolve = (list) => list?.map((parameter) => resolveComponentRef(spec, parameter));
|
|
249300
249316
|
const operation = {
|
|
249301
|
-
...
|
|
249302
|
-
parameters: mergeParameters(
|
|
249317
|
+
...parsed.data,
|
|
249318
|
+
parameters: mergeParameters(resolve(shared.success ? shared.data : undefined), resolve(parsed.data.parameters))
|
|
249303
249319
|
};
|
|
249304
249320
|
return [
|
|
249305
249321
|
{
|
|
@@ -249307,7 +249323,7 @@ function listOperations(spec) {
|
|
|
249307
249323
|
method: method.toUpperCase(),
|
|
249308
249324
|
path,
|
|
249309
249325
|
summary: operation.summary ?? "",
|
|
249310
|
-
description: operation.description ?? "",
|
|
249326
|
+
description: cleanText(operation.description ?? ""),
|
|
249311
249327
|
parameterText: parameterText(operation),
|
|
249312
249328
|
readOnly: isReadOnly(operation, spec),
|
|
249313
249329
|
operation
|
|
@@ -249317,22 +249333,14 @@ function listOperations(spec) {
|
|
|
249317
249333
|
}
|
|
249318
249334
|
function pathSegments(path) {
|
|
249319
249335
|
const pathname = path.split(/[?#]/, 1)[0] ?? "";
|
|
249320
|
-
return pathname.
|
|
249336
|
+
return pathname.replace(/^\/+|\/+$/g, "").split("/");
|
|
249321
249337
|
}
|
|
249322
249338
|
function segmentPattern(segment) {
|
|
249323
249339
|
const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
249324
249340
|
return new RegExp(`^${source}$`);
|
|
249325
249341
|
}
|
|
249326
|
-
function
|
|
249327
|
-
return
|
|
249328
|
-
}
|
|
249329
|
-
function compareSpecificity(a, b) {
|
|
249330
|
-
for (let i = 0;i < a.length; i++) {
|
|
249331
|
-
if (a[i] !== b[i]) {
|
|
249332
|
-
return (b[i] ?? 0) - (a[i] ?? 0);
|
|
249333
|
-
}
|
|
249334
|
-
}
|
|
249335
|
-
return 0;
|
|
249342
|
+
function literalSegments(path) {
|
|
249343
|
+
return pathSegments(path).map((segment) => segment.includes("{") ? "0" : "1").join("");
|
|
249336
249344
|
}
|
|
249337
249345
|
function matchOperation(operations, method, concretePath) {
|
|
249338
249346
|
const upperMethod = method.toUpperCase();
|
|
@@ -249344,11 +249352,12 @@ function matchOperation(operations, method, concretePath) {
|
|
|
249344
249352
|
const template = pathSegments(op.path);
|
|
249345
249353
|
return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
|
|
249346
249354
|
});
|
|
249347
|
-
return candidates.sort((a, b) =>
|
|
249355
|
+
return candidates.sort((a, b) => literalSegments(b.path).localeCompare(literalSegments(a.path)))[0];
|
|
249348
249356
|
}
|
|
249357
|
+
|
|
249358
|
+
// src/core/api-spec/contract.ts
|
|
249349
249359
|
var SCHEMA_REF_PREFIX = "#/components/schemas/";
|
|
249350
249360
|
var MAX_REF_DEPTH = 4;
|
|
249351
|
-
var FRAMEWORK_VALIDATION_ERROR = "Validation Error";
|
|
249352
249361
|
function inlineRefs(node, schemas, seen = new Set, depth = 0) {
|
|
249353
249362
|
if (depth > MAX_REF_DEPTH) {
|
|
249354
249363
|
return node;
|
|
@@ -249373,12 +249382,8 @@ function inlineRefs(node, schemas, seen = new Set, depth = 0) {
|
|
|
249373
249382
|
inlineRefs(value, schemas, seen, depth)
|
|
249374
249383
|
]));
|
|
249375
249384
|
}
|
|
249376
|
-
function
|
|
249377
|
-
const parsed =
|
|
249378
|
-
return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
|
|
249379
|
-
}
|
|
249380
|
-
function requestBodyOf(value) {
|
|
249381
|
-
const parsed = RequestBodySchema.safeParse(value);
|
|
249385
|
+
function bodyOf(value) {
|
|
249386
|
+
const parsed = MediaContentSchema.safeParse(value);
|
|
249382
249387
|
const content = parsed.success ? parsed.data.content ?? {} : {};
|
|
249383
249388
|
const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
|
|
249384
249389
|
return contentType ? { contentType, schema: content[contentType]?.schema } : {};
|
|
@@ -249392,8 +249397,10 @@ function leftoverRefs(node, schemas, found = new Map) {
|
|
|
249392
249397
|
for (const [key, value] of Object.entries(node)) {
|
|
249393
249398
|
if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
|
|
249394
249399
|
const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
|
|
249395
|
-
|
|
249396
|
-
|
|
249400
|
+
if (schema !== undefined) {
|
|
249401
|
+
found.set(value, schema);
|
|
249402
|
+
leftoverRefs(schema, schemas, found);
|
|
249403
|
+
}
|
|
249397
249404
|
} else {
|
|
249398
249405
|
leftoverRefs(value, schemas, found);
|
|
249399
249406
|
}
|
|
@@ -249408,11 +249415,6 @@ var SCHEMA_DATA_KEYS = new Set([
|
|
|
249408
249415
|
"enum",
|
|
249409
249416
|
"const"
|
|
249410
249417
|
]);
|
|
249411
|
-
var DOCS_CALLOUT = /<(Info|Note|Tip|Check|Warning)>([\s\S]*?)<\/\1>/g;
|
|
249412
|
-
var RELATIVE_LINK = /\[([^\]]+)\]\(\/[^)]*\)/g;
|
|
249413
|
-
function cleanText(text) {
|
|
249414
|
-
return text.replace(DOCS_CALLOUT, (_, kind, body) => kind === "Warning" ? `Warning: ${body}` : body).replace(RELATIVE_LINK, "$1");
|
|
249415
|
-
}
|
|
249416
249418
|
function slimSchema(node, isPropertyMap = false) {
|
|
249417
249419
|
if (Array.isArray(node)) {
|
|
249418
249420
|
return node.map((item) => slimSchema(item));
|
|
@@ -249446,22 +249448,21 @@ function getOperationContract(spec, op) {
|
|
|
249446
249448
|
const schemas = spec.components?.schemas ?? {};
|
|
249447
249449
|
const inline = (node) => node === undefined ? null : slimSchema(inlineRefs(node, schemas));
|
|
249448
249450
|
const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
|
|
249449
|
-
const parsed = ResponseObjectSchema.safeParse(response);
|
|
249451
|
+
const parsed = ResponseObjectSchema.safeParse(resolveComponentRef(spec, response));
|
|
249450
249452
|
return parsed.success ? [[status, parsed.data]] : [];
|
|
249451
249453
|
});
|
|
249452
|
-
const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) =>
|
|
249453
|
-
const
|
|
249454
|
-
const requestBody = requestBodyOf(op.operation.requestBody);
|
|
249454
|
+
const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => bodyOf(response).schema).find(Boolean);
|
|
249455
|
+
const requestBody = bodyOf(resolveComponentRef(spec, op.operation.requestBody));
|
|
249455
249456
|
const contract = {
|
|
249456
249457
|
endpoint: op.endpoint,
|
|
249457
249458
|
method: op.method,
|
|
249458
249459
|
path: op.path,
|
|
249459
249460
|
summary: op.summary,
|
|
249460
|
-
description:
|
|
249461
|
+
description: op.description,
|
|
249461
249462
|
parameters: (op.operation.parameters ?? []).flatMap((parameter) => {
|
|
249462
249463
|
const parsed = ParameterSchema.safeParse(parameter);
|
|
249463
249464
|
if (!parsed.success) {
|
|
249464
|
-
return [];
|
|
249465
|
+
return [parameter];
|
|
249465
249466
|
}
|
|
249466
249467
|
const { name, in: location2, required, schema, description } = parsed.data;
|
|
249467
249468
|
const inSchema = schema !== null && typeof schema === "object" && "description" in schema;
|
|
@@ -249478,11 +249479,7 @@ function getOperationContract(spec, op) {
|
|
|
249478
249479
|
}),
|
|
249479
249480
|
...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
|
|
249480
249481
|
requestBodySchema: inline(requestBody.schema),
|
|
249481
|
-
responseSchema: inline(success)
|
|
249482
|
-
errors: Object.fromEntries(errors.map(([status, response]) => [
|
|
249483
|
-
status,
|
|
249484
|
-
cleanText(response.description ?? "")
|
|
249485
|
-
]))
|
|
249482
|
+
responseSchema: inline(success)
|
|
249486
249483
|
};
|
|
249487
249484
|
const refs = leftoverRefs(contract, schemas);
|
|
249488
249485
|
return {
|
|
@@ -249492,7 +249489,6 @@ function getOperationContract(spec, op) {
|
|
|
249492
249489
|
} : {}
|
|
249493
249490
|
};
|
|
249494
249491
|
}
|
|
249495
|
-
|
|
249496
249492
|
// src/core/api-spec/grep.ts
|
|
249497
249493
|
function grepOperations(spec, operations, pattern, options = {}) {
|
|
249498
249494
|
const regex = new RegExp(pattern, options.ignoreCase ? "i" : "");
|
|
@@ -249500,6 +249496,7 @@ function grepOperations(spec, operations, pattern, options = {}) {
|
|
|
249500
249496
|
}
|
|
249501
249497
|
// src/core/api-spec/request.ts
|
|
249502
249498
|
var MAX_ERROR_BODY_CHARS = 4000;
|
|
249499
|
+
var QUERY_STRING = /\?\S*/g;
|
|
249503
249500
|
async function readBody(response) {
|
|
249504
249501
|
try {
|
|
249505
249502
|
const text = (await response.clone().text()).trim();
|
|
@@ -249508,13 +249505,18 @@ async function readBody(response) {
|
|
|
249508
249505
|
return;
|
|
249509
249506
|
}
|
|
249510
249507
|
}
|
|
249508
|
+
function normalizePath(path) {
|
|
249509
|
+
const url = new URL(path.replace(/^\/*/, "/"), "http://placeholder");
|
|
249510
|
+
return `${url.pathname}${url.search}`;
|
|
249511
|
+
}
|
|
249511
249512
|
async function sendApiRequest(method, path, body) {
|
|
249512
249513
|
try {
|
|
249513
249514
|
const response = await base44Client(path.replace(/^\/+/, ""), {
|
|
249514
249515
|
method,
|
|
249515
249516
|
body,
|
|
249516
|
-
headers: body ===
|
|
249517
|
-
timeout: false
|
|
249517
|
+
headers: typeof body === "string" ? { "Content-Type": "application/json" } : {},
|
|
249518
|
+
timeout: false,
|
|
249519
|
+
retry: { methods: ["get", "head"] }
|
|
249518
249520
|
});
|
|
249519
249521
|
return {
|
|
249520
249522
|
status: response.status,
|
|
@@ -249523,20 +249525,30 @@ async function sendApiRequest(method, path, body) {
|
|
|
249523
249525
|
};
|
|
249524
249526
|
} catch (error) {
|
|
249525
249527
|
const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
|
|
249526
|
-
const
|
|
249527
|
-
const
|
|
249528
|
-
|
|
249529
|
-
|
|
249530
|
-
|
|
249531
|
-
|
|
249532
|
-
|
|
249533
|
-
|
|
249534
|
-
|
|
249535
|
-
|
|
249536
|
-
|
|
249528
|
+
const response = error instanceof HTTPError ? error.response : undefined;
|
|
249529
|
+
const raw = response ? await readBody(response) : undefined;
|
|
249530
|
+
const retryAfter = response?.headers.get("retry-after") ?? undefined;
|
|
249531
|
+
throw redactedApiError(apiError, raw, method, path, retryAfter);
|
|
249532
|
+
}
|
|
249533
|
+
}
|
|
249534
|
+
function redactedApiError(apiError, raw, method, path, retryAfter) {
|
|
249535
|
+
const wait = retryAfter ? ` (retry after ${/^\d+$/.test(retryAfter) ? `${retryAfter} s` : retryAfter})` : "";
|
|
249536
|
+
const reason = apiError.statusCode !== undefined ? `HTTP ${apiError.statusCode}${wait}` : (apiError.cause?.message ?? "request failed").replace(QUERY_STRING, "");
|
|
249537
|
+
const message = `Error calling ${method} ${path.split("?", 1)[0]}: ${reason}`;
|
|
249538
|
+
return new ApiError(message, {
|
|
249539
|
+
statusCode: apiError.statusCode,
|
|
249540
|
+
requestUrl: apiError.requestUrl?.split("?", 1)[0],
|
|
249541
|
+
requestMethod: apiError.requestMethod,
|
|
249542
|
+
requestId: apiError.requestId,
|
|
249543
|
+
hints: apiError.hints,
|
|
249544
|
+
details: [
|
|
249545
|
+
...raw ? [`Response body: ${raw}`] : apiError.details ?? [],
|
|
249546
|
+
...apiError.requestId ? [`Request ID: ${apiError.requestId}`] : []
|
|
249547
|
+
]
|
|
249548
|
+
});
|
|
249537
249549
|
}
|
|
249538
249550
|
// src/core/api-spec/spec.ts
|
|
249539
|
-
import { rename, stat as stat3 } from "node:fs/promises";
|
|
249551
|
+
import { rename, rm, stat as stat3 } from "node:fs/promises";
|
|
249540
249552
|
import { join as join22 } from "node:path";
|
|
249541
249553
|
var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
|
|
249542
249554
|
function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
|
|
@@ -249591,12 +249603,18 @@ async function loadSpec(options = {}) {
|
|
|
249591
249603
|
const text = await downloadSpec();
|
|
249592
249604
|
const spec = parseSpec(text);
|
|
249593
249605
|
const partial = `${path}.${process.pid}.tmp`;
|
|
249594
|
-
|
|
249595
|
-
|
|
249606
|
+
try {
|
|
249607
|
+
await writeFile(partial, text);
|
|
249608
|
+
await rename(partial, path);
|
|
249609
|
+
} catch {
|
|
249610
|
+
await rm(partial, { force: true }).catch(() => {
|
|
249611
|
+
return;
|
|
249612
|
+
});
|
|
249613
|
+
}
|
|
249596
249614
|
return { text, spec };
|
|
249597
249615
|
}
|
|
249598
249616
|
// src/cli/commands/api/shared.ts
|
|
249599
|
-
import {
|
|
249617
|
+
import { basename as basename6 } from "node:path";
|
|
249600
249618
|
function formatJson(value) {
|
|
249601
249619
|
return toJsonStdout(value, { compact: !process.stdout.isTTY });
|
|
249602
249620
|
}
|
|
@@ -249628,36 +249646,60 @@ function operationsInArea(operations, area) {
|
|
|
249628
249646
|
}
|
|
249629
249647
|
return inArea;
|
|
249630
249648
|
}
|
|
249631
|
-
function
|
|
249632
|
-
try {
|
|
249633
|
-
const stats = fstatSync(0);
|
|
249634
|
-
return stats.isFIFO() || stats.isFile();
|
|
249635
|
-
} catch {
|
|
249636
|
-
return false;
|
|
249637
|
-
}
|
|
249638
|
-
}
|
|
249639
|
-
async function readRequestBody(flag, log) {
|
|
249649
|
+
async function readRequestBody(flag) {
|
|
249640
249650
|
if (flag === "@-") {
|
|
249641
249651
|
return readStdin("--body @-", { trim: false });
|
|
249642
249652
|
}
|
|
249643
249653
|
if (flag?.startsWith("@")) {
|
|
249644
249654
|
return readTextFile(flag.slice(1));
|
|
249645
249655
|
}
|
|
249646
|
-
if (flag === undefined && isPipedStdin()) {
|
|
249647
|
-
log.warn("stdin is ignored; pass --body @- to send it as the body.");
|
|
249648
|
-
}
|
|
249649
249656
|
return flag;
|
|
249650
249657
|
}
|
|
249658
|
+
var FORM_FILE = /^@(.+?)(?:;type=([^;]+))?$/;
|
|
249659
|
+
async function readFormBody(fields) {
|
|
249660
|
+
const form = new FormData;
|
|
249661
|
+
for (const field of fields) {
|
|
249662
|
+
const separator = field.indexOf("=");
|
|
249663
|
+
if (separator < 1) {
|
|
249664
|
+
throw new InvalidInputError(`--form takes name=value or name=@file, got "${field}".`);
|
|
249665
|
+
}
|
|
249666
|
+
const name = field.slice(0, separator);
|
|
249667
|
+
const value = field.slice(separator + 1);
|
|
249668
|
+
const file = FORM_FILE.exec(value);
|
|
249669
|
+
if (file?.[1]) {
|
|
249670
|
+
const type = file[2] ?? "application/octet-stream";
|
|
249671
|
+
const blob = new Blob([await readFile(file[1])], { type });
|
|
249672
|
+
form.append(name, blob, basename6(file[1]));
|
|
249673
|
+
} else {
|
|
249674
|
+
form.append(name, value);
|
|
249675
|
+
}
|
|
249676
|
+
}
|
|
249677
|
+
return form;
|
|
249678
|
+
}
|
|
249679
|
+
function withoutQuery(path) {
|
|
249680
|
+
return path.split("?", 1)[0] ?? "";
|
|
249681
|
+
}
|
|
249682
|
+
function reportedFetchCommand(method, path, options) {
|
|
249683
|
+
return {
|
|
249684
|
+
name: "api fetch",
|
|
249685
|
+
args: [method, withoutQuery(path)],
|
|
249686
|
+
options: {
|
|
249687
|
+
...options,
|
|
249688
|
+
...options.body === undefined ? {} : { body: "[not reported]" },
|
|
249689
|
+
...Array.isArray(options.form) && options.form.length > 0 ? { form: "[not reported]" } : {}
|
|
249690
|
+
}
|
|
249691
|
+
};
|
|
249692
|
+
}
|
|
249651
249693
|
|
|
249652
249694
|
// src/cli/commands/api/catalog.ts
|
|
249653
249695
|
async function catalogAction(ctx, area, options) {
|
|
249654
249696
|
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249655
249697
|
const operations = listOperations(spec);
|
|
249656
|
-
const
|
|
249657
|
-
if (area
|
|
249658
|
-
return { stdout: formatJson(catalogIndex(
|
|
249698
|
+
const filterReadOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
|
|
249699
|
+
if (!area) {
|
|
249700
|
+
return { stdout: formatJson(catalogIndex(filterReadOnly(operations))) };
|
|
249659
249701
|
}
|
|
249660
|
-
const inArea =
|
|
249702
|
+
const inArea = filterReadOnly(operationsInArea(operations, area));
|
|
249661
249703
|
return { stdout: formatJson(areaListing(area, inArea)) };
|
|
249662
249704
|
}
|
|
249663
249705
|
function getApiCatalogCommand() {
|
|
@@ -249672,7 +249714,7 @@ async function findOperation(ctx, method, path, { refresh, flag }) {
|
|
|
249672
249714
|
const { spec } = await loadSpecTask(ctx, refresh);
|
|
249673
249715
|
const op = matchOperation(listOperations(spec), method, path);
|
|
249674
249716
|
if (!op) {
|
|
249675
|
-
throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
|
|
249717
|
+
throw new InvalidInputError(`No operation in the API spec matches ${method} ${withoutQuery(path)}.`, {
|
|
249676
249718
|
hints: [
|
|
249677
249719
|
{
|
|
249678
249720
|
message: "The cached spec may predate this route; fetch it again",
|
|
@@ -249687,6 +249729,22 @@ async function findOperation(ctx, method, path, { refresh, flag }) {
|
|
|
249687
249729
|
}
|
|
249688
249730
|
return { spec, op };
|
|
249689
249731
|
}
|
|
249732
|
+
var ENCODED_SEPARATOR = /%(2f|5c|2e)/i;
|
|
249733
|
+
async function fillAppId(ctx, path, command) {
|
|
249734
|
+
let filled = path;
|
|
249735
|
+
if (withoutQuery(path).includes("{app_id}")) {
|
|
249736
|
+
const { appId } = command.optsWithGlobals();
|
|
249737
|
+
await ensureAppContext(ctx, { appId });
|
|
249738
|
+
filled = path.replaceAll("{app_id}", requireApp(ctx).id);
|
|
249739
|
+
}
|
|
249740
|
+
const placeholder = withoutQuery(filled).match(/\{[^}/]*\}/);
|
|
249741
|
+
if (placeholder) {
|
|
249742
|
+
throw new InvalidInputError(`Replace ${placeholder[0]} in the path with a real value; only {app_id} is filled in.`);
|
|
249743
|
+
}
|
|
249744
|
+
return filled;
|
|
249745
|
+
}
|
|
249746
|
+
var MULTIPART_HINT = "Send this body with --form name=value, and --form name=@path for files.";
|
|
249747
|
+
var CONTRACT_HELP = "The contract is JSON; cut it down with e.g. | jq '.parameters, .requestBodySchema'";
|
|
249690
249748
|
var TEXT_CONTENT_TYPES = [
|
|
249691
249749
|
"json",
|
|
249692
249750
|
"text/",
|
|
@@ -249694,18 +249752,27 @@ var TEXT_CONTENT_TYPES = [
|
|
|
249694
249752
|
"javascript",
|
|
249695
249753
|
"x-www-form-urlencoded"
|
|
249696
249754
|
];
|
|
249697
|
-
function
|
|
249698
|
-
|
|
249755
|
+
function decodeText(body, contentType) {
|
|
249756
|
+
const type = contentType.toLowerCase();
|
|
249757
|
+
if (type && !TEXT_CONTENT_TYPES.some((hint) => type.includes(hint))) {
|
|
249758
|
+
return;
|
|
249759
|
+
}
|
|
249760
|
+
try {
|
|
249761
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
249762
|
+
} catch {
|
|
249763
|
+
return;
|
|
249764
|
+
}
|
|
249699
249765
|
}
|
|
249700
249766
|
async function formatResponse({ status, contentType, body }, output, jsonMode) {
|
|
249701
|
-
if (output
|
|
249767
|
+
if (output) {
|
|
249702
249768
|
await writeFile(output, body);
|
|
249703
249769
|
return formatJson({ status, contentType, bytes: body.length, output });
|
|
249704
249770
|
}
|
|
249705
249771
|
if (body.length === 0) {
|
|
249706
249772
|
return formatJson({ status });
|
|
249707
249773
|
}
|
|
249708
|
-
|
|
249774
|
+
const text = decodeText(body, contentType);
|
|
249775
|
+
if (text === undefined) {
|
|
249709
249776
|
return formatJson({
|
|
249710
249777
|
status,
|
|
249711
249778
|
contentType,
|
|
@@ -249713,36 +249780,46 @@ async function formatResponse({ status, contentType, body }, output, jsonMode) {
|
|
|
249713
249780
|
note: "Binary body not printed; add --output <file> to save it."
|
|
249714
249781
|
});
|
|
249715
249782
|
}
|
|
249716
|
-
const
|
|
249717
|
-
try {
|
|
249718
|
-
return formatJson(JSON.parse(text));
|
|
249719
|
-
} catch {
|
|
249720
|
-
if (jsonMode) {
|
|
249721
|
-
return formatJson({ status, contentType, body: text });
|
|
249722
|
-
}
|
|
249723
|
-
return text.endsWith(`
|
|
249783
|
+
const asIs = text.endsWith(`
|
|
249724
249784
|
`) ? text : `${text}
|
|
249725
249785
|
`;
|
|
249786
|
+
try {
|
|
249787
|
+
const parsed = JSON.parse(text);
|
|
249788
|
+
return process.stdout.isTTY ? formatJson(parsed) : asIs;
|
|
249789
|
+
} catch {
|
|
249790
|
+
return jsonMode ? formatJson({ status, contentType, body: text }) : asIs;
|
|
249726
249791
|
}
|
|
249727
249792
|
}
|
|
249728
249793
|
async function fetchAction(ctx, methodArg, path, options, command) {
|
|
249794
|
+
ctx.errorReporter.setContext({
|
|
249795
|
+
command: reportedFetchCommand(methodArg ?? "", path ?? "", { ...options })
|
|
249796
|
+
});
|
|
249729
249797
|
if (!methodArg || !path) {
|
|
249730
249798
|
if (options.help) {
|
|
249731
|
-
const usage = command.helpInformation()
|
|
249799
|
+
const usage = `${command.helpInformation()}
|
|
249800
|
+
${CONTRACT_HELP}
|
|
249801
|
+
`;
|
|
249732
249802
|
return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
|
|
249733
249803
|
}
|
|
249734
249804
|
throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
|
|
249735
249805
|
}
|
|
249736
249806
|
const method = methodArg.toUpperCase();
|
|
249737
249807
|
if (options.help) {
|
|
249738
|
-
const { spec, op } = await findOperation(ctx, method, path, {
|
|
249808
|
+
const { spec, op } = await findOperation(ctx, method, normalizePath(path), {
|
|
249739
249809
|
refresh: options.refresh,
|
|
249740
249810
|
flag: "--help"
|
|
249741
249811
|
});
|
|
249742
|
-
|
|
249812
|
+
const contract = getOperationContract(spec, op);
|
|
249813
|
+
return {
|
|
249814
|
+
stdout: formatJson(contract.requestBodyContentType === "multipart/form-data" ? { ...contract, hint: MULTIPART_HINT } : contract)
|
|
249815
|
+
};
|
|
249743
249816
|
}
|
|
249817
|
+
const target = normalizePath(await fillAppId(ctx, path, command));
|
|
249744
249818
|
if (options.readOnly) {
|
|
249745
|
-
|
|
249819
|
+
if (ENCODED_SEPARATOR.test(withoutQuery(target))) {
|
|
249820
|
+
throw new InvalidInputError("Refused under --read-only: the path has an encoded /, \\ or ., so it can't be checked. Nothing was sent.");
|
|
249821
|
+
}
|
|
249822
|
+
const { op } = await findOperation(ctx, method, target, {
|
|
249746
249823
|
refresh: options.refresh,
|
|
249747
249824
|
flag: "--read-only"
|
|
249748
249825
|
});
|
|
@@ -249750,17 +249827,13 @@ async function fetchAction(ctx, methodArg, path, options, command) {
|
|
|
249750
249827
|
throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
|
|
249751
249828
|
}
|
|
249752
249829
|
}
|
|
249753
|
-
|
|
249754
|
-
|
|
249755
|
-
|
|
249756
|
-
args: [method, path.split("?", 1)[0] ?? ""],
|
|
249757
|
-
options: { ...options, body: options.body && "[not reported]" }
|
|
249758
|
-
}
|
|
249759
|
-
});
|
|
249830
|
+
if (options.body !== undefined && options.form.length > 0) {
|
|
249831
|
+
throw new InvalidInputError("Use --body or --form, not both.");
|
|
249832
|
+
}
|
|
249760
249833
|
await ensureAuth(ctx);
|
|
249761
|
-
const body = await readRequestBody(options.body
|
|
249762
|
-
const response = await ctx.runTask(`Calling ${method} ${
|
|
249763
|
-
successMessage: `Called ${method} ${
|
|
249834
|
+
const body = options.form.length > 0 ? await readFormBody(options.form) : await readRequestBody(options.body);
|
|
249835
|
+
const response = await ctx.runTask(`Calling ${method} ${target}`, () => sendApiRequest(method, target, body), {
|
|
249836
|
+
successMessage: `Called ${method} ${target}`,
|
|
249764
249837
|
errorMessage: "Request failed"
|
|
249765
249838
|
});
|
|
249766
249839
|
return {
|
|
@@ -249771,7 +249844,8 @@ function getApiFetchCommand() {
|
|
|
249771
249844
|
return new Base44Command("fetch", {
|
|
249772
249845
|
requireAuth: false,
|
|
249773
249846
|
requireAppContext: false
|
|
249774
|
-
}).description("Call a Base44 API operation; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", '
|
|
249847
|
+
}).description("Call a Base44 API operation; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Path with any query string; {app_id} is filled from --app-id or the project, e.g. "/api/apps/{app_id}/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- to read it from stdin").option("--form <field>", "Multipart field: name=value, or name=@file to attach a file (repeatable)", (field, fields) => [...fields, field], []).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").addHelpText("after", `
|
|
249848
|
+
${CONTRACT_HELP}`).action(fetchAction);
|
|
249775
249849
|
}
|
|
249776
249850
|
|
|
249777
249851
|
// src/cli/commands/api/grep.ts
|
|
@@ -249787,7 +249861,7 @@ async function grepAction(ctx, pattern, options) {
|
|
|
249787
249861
|
assertValidRegex(pattern);
|
|
249788
249862
|
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249789
249863
|
let operations = listOperations(spec);
|
|
249790
|
-
if (options.area
|
|
249864
|
+
if (options.area) {
|
|
249791
249865
|
operations = operationsInArea(operations, options.area);
|
|
249792
249866
|
}
|
|
249793
249867
|
if (options.readOnly) {
|
|
@@ -249803,7 +249877,7 @@ function getApiGrepCommand() {
|
|
|
249803
249877
|
return new Base44Command("grep", {
|
|
249804
249878
|
requireAuth: false,
|
|
249805
249879
|
requireAppContext: false
|
|
249806
|
-
}).description("Search the API spec with a regular expression, for when search misses").argument("<pattern>",
|
|
249880
|
+
}).description("Search the API spec with a regular expression, for when search misses").argument("<pattern>", `Regular expression over each operation's contract as JSON text (quotes and newlines appear escaped), 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 to return (default 20)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
|
|
249807
249881
|
}
|
|
249808
249882
|
|
|
249809
249883
|
// src/cli/commands/api/search.ts
|
|
@@ -251590,7 +251664,7 @@ function getBuildCommand() {
|
|
|
251590
251664
|
}
|
|
251591
251665
|
|
|
251592
251666
|
// src/cli/commands/project/create.ts
|
|
251593
|
-
import { basename as
|
|
251667
|
+
import { basename as basename7, resolve as resolve11 } from "node:path";
|
|
251594
251668
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
251595
251669
|
|
|
251596
251670
|
// src/cli/commands/project/scaffold-shared.ts
|
|
@@ -251755,8 +251829,8 @@ async function createInteractive(options, ctx) {
|
|
|
251755
251829
|
name: () => {
|
|
251756
251830
|
return options.name ? Promise.resolve(options.name) : Ze({
|
|
251757
251831
|
message: "What is the name of your project?",
|
|
251758
|
-
placeholder:
|
|
251759
|
-
initialValue:
|
|
251832
|
+
placeholder: basename7(process.cwd()),
|
|
251833
|
+
initialValue: basename7(process.cwd()),
|
|
251760
251834
|
validate: (value) => {
|
|
251761
251835
|
if (!value || value.trim().length === 0) {
|
|
251762
251836
|
return "Every project deserves a name";
|
|
@@ -252451,7 +252525,7 @@ function getLogsCommand() {
|
|
|
252451
252525
|
}
|
|
252452
252526
|
|
|
252453
252527
|
// src/cli/commands/project/scaffold.ts
|
|
252454
|
-
import { basename as
|
|
252528
|
+
import { basename as basename8, resolve as resolve12 } from "node:path";
|
|
252455
252529
|
function resolveAppId(options) {
|
|
252456
252530
|
const appId = options.appId;
|
|
252457
252531
|
if (!appId) {
|
|
@@ -252468,7 +252542,7 @@ async function scaffoldAction(ctx, name, options, command) {
|
|
|
252468
252542
|
const { log, runTask } = ctx;
|
|
252469
252543
|
const appId = resolveAppId(command.optsWithGlobals());
|
|
252470
252544
|
const resolvedPath = resolve12("./");
|
|
252471
|
-
const projectName = (name ??
|
|
252545
|
+
const projectName = (name ?? basename8(resolvedPath)).trim();
|
|
252472
252546
|
const template = await getTemplateById("backend-only");
|
|
252473
252547
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
252474
252548
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
@@ -262393,7 +262467,7 @@ var bundleAppRequestSchema = objectType({
|
|
|
262393
262467
|
var ACTIVATION_MODE = "pull";
|
|
262394
262468
|
|
|
262395
262469
|
// ../functions-compiler/src/deno-bundle.ts
|
|
262396
|
-
import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
262470
|
+
import { mkdtemp, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
262397
262471
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
262398
262472
|
import path21 from "node:path";
|
|
262399
262473
|
|
|
@@ -263000,7 +263074,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
|
|
|
263000
263074
|
warnings: result.warnings.map((w) => w.text)
|
|
263001
263075
|
};
|
|
263002
263076
|
} finally {
|
|
263003
|
-
await
|
|
263077
|
+
await rm2(dir, { recursive: true, force: true });
|
|
263004
263078
|
}
|
|
263005
263079
|
}
|
|
263006
263080
|
function buildFailureErrors(e, dir) {
|
|
@@ -267991,7 +268065,7 @@ function createPattern(matcher) {
|
|
|
267991
268065
|
}
|
|
267992
268066
|
return () => false;
|
|
267993
268067
|
}
|
|
267994
|
-
function
|
|
268068
|
+
function normalizePath2(path) {
|
|
267995
268069
|
if (typeof path !== "string")
|
|
267996
268070
|
throw new Error("string expected");
|
|
267997
268071
|
path = sp3.normalize(path);
|
|
@@ -268005,7 +268079,7 @@ function normalizePath(path) {
|
|
|
268005
268079
|
return path;
|
|
268006
268080
|
}
|
|
268007
268081
|
function matchPatterns(patterns, testString, stats) {
|
|
268008
|
-
const path =
|
|
268082
|
+
const path = normalizePath2(testString);
|
|
268009
268083
|
for (let index = 0;index < patterns.length; index++) {
|
|
268010
268084
|
const pattern = patterns[index];
|
|
268011
268085
|
if (pattern(path, stats)) {
|
|
@@ -273365,4 +273439,4 @@ export {
|
|
|
273365
273439
|
runCLI
|
|
273366
273440
|
};
|
|
273367
273441
|
|
|
273368
|
-
//# debugId=
|
|
273442
|
+
//# debugId=4213AA6F0A5C795F64756E2164756E21
|