@base44-preview/cli 0.1.32-pr.663.447e6da → 0.1.32-pr.663.539e770

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 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")), ...rm2(n, t, s)], { shouldBreak: i });
39573
+ return l(["<", r("name"), r("typeArguments"), m(e.map(() => [o, r()], "attributes")), ...rm3(n, t, s)], { shouldBreak: i });
39574
39574
  }
39575
- function rm2(e, t, r) {
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 rm3(e, t, a) {
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: rm3, 194: rm3, 195: function(t, a, _) {
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);
@@ -249102,23 +249102,30 @@ var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
249102
249102
  var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
249103
249103
 
249104
249104
  // src/core/api-spec/search.ts
249105
- var BOOST = { path: 8, summary: 5, description: 2, parameters: 0.5 };
249105
+ var BOOST = {
249106
+ method: 1,
249107
+ path: 8,
249108
+ summary: 5,
249109
+ description: 2,
249110
+ parameters: 0.5
249111
+ };
249106
249112
  var MIN_RELATIVE_SCORE = 0.2;
249107
249113
  var TOKEN_SEPARATOR = /[\n\r\p{Z}\p{P}\p{S}]+/u;
249108
- var STOPWORDS = new Set("a an and are at be by do does for from how i in is it its me my of on or our that the this to we what who with you your".split(" "));
249114
+ var STOPWORDS = new Set("a an and are at be by do does for from how i id in is it its me my of on or our that the this to we what who with you your".split(" "));
249109
249115
  function tokenize(text) {
249110
- return text.split(TOKEN_SEPARATOR).filter((word) => word && !STOPWORDS.has(word.toLowerCase()));
249116
+ return text.split(TOKEN_SEPARATOR).filter((word) => word.length >= 2 && !STOPWORDS.has(word.toLowerCase()));
249111
249117
  }
249112
249118
  function toOperationSummary(op) {
249113
249119
  return { endpoint: op.endpoint, summary: op.summary };
249114
249120
  }
249115
249121
  function buildSearchIndex(operations) {
249116
249122
  const index = new MiniSearch({
249117
- fields: ["path", "summary", "description", "parameters"],
249123
+ fields: ["method", "path", "summary", "description", "parameters"],
249118
249124
  tokenize
249119
249125
  });
249120
249126
  index.addAll(operations.map((op, id) => ({
249121
249127
  id,
249128
+ method: op.method,
249122
249129
  path: op.path.replace(/\{[^}]*\}/g, ""),
249123
249130
  summary: op.summary,
249124
249131
  description: op.description,
@@ -249126,27 +249133,37 @@ function buildSearchIndex(operations) {
249126
249133
  })));
249127
249134
  return index;
249128
249135
  }
249129
- function summaryCoverage(query, op) {
249130
- const terms = tokenize(query.toLowerCase());
249131
- if (!op || terms.length === 0) {
249132
- return 0;
249133
- }
249134
- const words = tokenize(op.summary.toLowerCase());
249135
- return terms.filter((term) => words.some((word) => word.startsWith(term))).length / terms.length;
249136
+ function summaryMatch(terms, op) {
249137
+ const words = tokenize(op?.summary.toLowerCase() ?? "");
249138
+ const named = (word) => terms.some((term) => word.startsWith(term));
249139
+ return {
249140
+ coverage: terms.filter((term) => words.some((word) => word.startsWith(term))).length / terms.length,
249141
+ precision: words.length ? words.filter(named).length / words.length : 0
249142
+ };
249136
249143
  }
249144
+ var readsFirst = (op) => op?.method === "GET" ? 0 : 1;
249137
249145
  function searchOperations(operations, query, options = {}) {
249146
+ const terms = tokenize(query.toLowerCase());
249147
+ if (terms.length === 0) {
249148
+ return [];
249149
+ }
249138
249150
  const index = buildSearchIndex(operations);
249139
249151
  const hits = index.search(query, {
249140
249152
  prefix: (term) => term.length >= 3,
249141
249153
  fuzzy: (term) => term.length >= 4 ? 0.2 : false,
249142
249154
  boost: BOOST,
249143
249155
  filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
249144
- }).map((hit) => ({
249145
- ...hit,
249146
- score: hit.score * (1 + summaryCoverage(query, operations[hit.id]))
249147
- })).sort((a, b) => b.score - a.score);
249148
- const baseline = (hits[0]?.score ?? 0) * MIN_RELATIVE_SCORE;
249149
- return hits.filter((hit) => hit.score >= baseline).slice(0, options.limit ?? 5).flatMap((hit) => {
249156
+ }).map((hit) => {
249157
+ const match = summaryMatch(terms, operations[hit.id]);
249158
+ return {
249159
+ ...hit,
249160
+ ...match,
249161
+ full: match.coverage === 1,
249162
+ score: hit.score * (1 + match.coverage)
249163
+ };
249164
+ }).sort((a, b) => Number(b.full) - Number(a.full) || (a.full ? b.precision - a.precision || readsFirst(operations[a.id]) - readsFirst(operations[b.id]) : 0) || b.score - a.score);
249165
+ const baseline = Math.max(0, ...hits.map((hit) => hit.score)) * MIN_RELATIVE_SCORE;
249166
+ return hits.filter((hit) => hit.full || hit.score >= baseline).slice(0, options.limit ?? 5).flatMap((hit) => {
249150
249167
  const op = operations[hit.id];
249151
249168
  return op ? [toOperationSummary(op)] : [];
249152
249169
  });
@@ -249177,7 +249194,7 @@ function groupByArea(operations) {
249177
249194
  }
249178
249195
  return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
249179
249196
  }
249180
- function readsFirst(ops) {
249197
+ function readsFirst2(ops) {
249181
249198
  const isRead = (op) => op.method === "GET" ? 0 : 1;
249182
249199
  return [...ops].sort((a, b) => isRead(a) - isRead(b));
249183
249200
  }
@@ -249185,7 +249202,7 @@ function catalogIndex(operations) {
249185
249202
  const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
249186
249203
  area,
249187
249204
  operationCount: ops.length,
249188
- sample: readsFirst(ops).slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
249205
+ sample: readsFirst2(ops).slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
249189
249206
  });
249190
249207
  return { areas, total: operations.length };
249191
249208
  }
@@ -249197,44 +249214,6 @@ function areaListing(area, operations, max = AREA_OPERATIONS_MAX) {
249197
249214
  truncated: operations.length > max
249198
249215
  };
249199
249216
  }
249200
- // src/core/api-spec/grep.ts
249201
- var CONTEXT_CHARS = 40;
249202
- var MAX_SNIPPETS = 3;
249203
- var MAX_SNIPPET_CHARS = 200;
249204
- function unescapeJson(snippet) {
249205
- return snippet.replace(/\\[nrt]/g, " ").replace(/\\"/g, '"');
249206
- }
249207
- function snippets(text, pattern) {
249208
- const found = [];
249209
- for (const match of text.matchAll(pattern)) {
249210
- const start = Math.max(0, match.index - CONTEXT_CHARS);
249211
- const end = match.index + match[0].length + CONTEXT_CHARS;
249212
- found.push(unescapeJson(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS))));
249213
- if (found.length === MAX_SNIPPETS || match[0].length === 0) {
249214
- break;
249215
- }
249216
- }
249217
- return found;
249218
- }
249219
- function grepSpec(spec, operations, pattern, options = {}) {
249220
- const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249221
- const hits = [];
249222
- for (const op of operations) {
249223
- const { summary, description, parameters, requestBody, responses } = op.operation;
249224
- const matches = snippets(`${op.endpoint} ${JSON.stringify({ summary, description, parameters, requestBody, responses })}`, regex);
249225
- if (matches.length > 0) {
249226
- hits.push({ ...toOperationSummary(op), matches });
249227
- }
249228
- }
249229
- const schemas = options.schemas === false ? {} : spec.components?.schemas;
249230
- for (const [schema, definition] of Object.entries(schemas ?? {})) {
249231
- const matches = snippets(JSON.stringify(definition), regex);
249232
- if (matches.length > 0) {
249233
- hits.push({ schema, matches });
249234
- }
249235
- }
249236
- return hits.slice(0, options.limit ?? 20);
249237
- }
249238
249217
  // src/core/api-spec/schema.ts
249239
249218
  var HTTP_METHODS = [
249240
249219
  "get",
@@ -249255,7 +249234,7 @@ var ParameterSchema = looseObject({
249255
249234
  example: unknown().optional()
249256
249235
  });
249257
249236
  var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
249258
- var RequestBodySchema = looseObject({
249237
+ var MediaContentSchema = looseObject({
249259
249238
  content: MediaTypesSchema.optional()
249260
249239
  });
249261
249240
  var ResponseObjectSchema = looseObject({
@@ -249285,91 +249264,16 @@ var OpenApiSpecSchema = looseObject({
249285
249264
  security: array(SecurityRequirementSchema).optional()
249286
249265
  });
249287
249266
 
249288
- // src/core/api-spec/operations.ts
249289
- var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
249290
- var READ_ONLY_SCOPE = "read_only";
249291
- function isReadOnly(operation, spec) {
249292
- const security = operation.security ?? spec.security ?? [];
249293
- return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
249294
- }
249295
- function parameterText(operation) {
249296
- return (operation.parameters ?? []).flatMap((parameter) => {
249297
- const parsed = ParameterSchema.safeParse(parameter);
249298
- return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249299
- }).join(" ");
249300
- }
249301
- function mergeParameters(shared, own) {
249302
- if (!shared?.length) {
249303
- return own;
249304
- }
249305
- const key = (parameter) => {
249306
- const parsed = ParameterSchema.safeParse(parameter);
249307
- return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249308
- };
249309
- const ownKeys = new Set((own ?? []).map(key));
249310
- return [
249311
- ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249312
- ...own ?? []
249313
- ];
249314
- }
249315
- function listOperations(spec) {
249316
- return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249317
- const declared = item[method];
249318
- if (!declared) {
249319
- return [];
249320
- }
249321
- const operation = {
249322
- ...declared,
249323
- parameters: mergeParameters(item.parameters, declared.parameters)
249324
- };
249325
- return [
249326
- {
249327
- endpoint: `${method.toUpperCase()} ${path}`,
249328
- method: method.toUpperCase(),
249329
- path,
249330
- summary: operation.summary ?? "",
249331
- description: operation.description ?? "",
249332
- parameterText: parameterText(operation),
249333
- readOnly: isReadOnly(operation, spec),
249334
- operation
249335
- }
249336
- ];
249337
- }));
249338
- }
249339
- function pathSegments(path) {
249340
- const pathname = path.split(/[?#]/, 1)[0] ?? "";
249341
- return pathname.split("/").filter(Boolean);
249342
- }
249343
- function segmentPattern(segment) {
249344
- const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
249345
- return new RegExp(`^${source}$`);
249346
- }
249347
- function specificity(templateSegments) {
249348
- return templateSegments.map((segment) => segment.includes("{") ? 0 : 1);
249349
- }
249350
- function compareSpecificity(a, b) {
249351
- for (let i = 0;i < a.length; i++) {
249352
- if (a[i] !== b[i]) {
249353
- return (b[i] ?? 0) - (a[i] ?? 0);
249354
- }
249355
- }
249356
- return 0;
249357
- }
249358
- function matchOperation(operations, method, concretePath) {
249359
- const upperMethod = method.toUpperCase();
249360
- const segments = pathSegments(concretePath);
249361
- const candidates = operations.filter((op) => {
249362
- if (op.method !== upperMethod) {
249363
- return false;
249364
- }
249365
- const template = pathSegments(op.path);
249366
- return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
249367
- });
249368
- return candidates.sort((a, b) => compareSpecificity(specificity(pathSegments(a.path)), specificity(pathSegments(b.path))))[0];
249267
+ // src/core/api-spec/text.ts
249268
+ var DOCS_CALLOUT = /<(Info|Note|Tip|Check|Warning)>([\s\S]*?)<\/\1>/g;
249269
+ var RELATIVE_LINK = /\[([^\]]+)\]\(\/[^)]*\)/g;
249270
+ function cleanText(text) {
249271
+ return text.replace(DOCS_CALLOUT, (_, kind, body) => kind === "Warning" ? `Warning: ${body}` : body).replace(RELATIVE_LINK, "$1");
249369
249272
  }
249273
+
249274
+ // src/core/api-spec/contract.ts
249370
249275
  var SCHEMA_REF_PREFIX = "#/components/schemas/";
249371
249276
  var MAX_REF_DEPTH = 4;
249372
- var FRAMEWORK_VALIDATION_ERROR = "Validation Error";
249373
249277
  function inlineRefs(node, schemas, seen = new Set, depth = 0) {
249374
249278
  if (depth > MAX_REF_DEPTH) {
249375
249279
  return node;
@@ -249394,12 +249298,8 @@ function inlineRefs(node, schemas, seen = new Set, depth = 0) {
249394
249298
  inlineRefs(value, schemas, seen, depth)
249395
249299
  ]));
249396
249300
  }
249397
- function jsonSchemaOf(value) {
249398
- const parsed = RequestBodySchema.safeParse(value);
249399
- return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
249400
- }
249401
- function requestBodyOf(value) {
249402
- const parsed = RequestBodySchema.safeParse(value);
249301
+ function bodyOf(value) {
249302
+ const parsed = MediaContentSchema.safeParse(value);
249403
249303
  const content = parsed.success ? parsed.data.content ?? {} : {};
249404
249304
  const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
249405
249305
  return contentType ? { contentType, schema: content[contentType]?.schema } : {};
@@ -249413,8 +249313,10 @@ function leftoverRefs(node, schemas, found = new Map) {
249413
249313
  for (const [key, value] of Object.entries(node)) {
249414
249314
  if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
249415
249315
  const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
249416
- found.set(value, schema);
249417
- leftoverRefs(schema, schemas, found);
249316
+ if (schema !== undefined) {
249317
+ found.set(value, schema);
249318
+ leftoverRefs(schema, schemas, found);
249319
+ }
249418
249320
  } else {
249419
249321
  leftoverRefs(value, schemas, found);
249420
249322
  }
@@ -249422,16 +249324,51 @@ function leftoverRefs(node, schemas, found = new Map) {
249422
249324
  }
249423
249325
  return found;
249424
249326
  }
249327
+ var SCHEMA_DATA_KEYS = new Set([
249328
+ "example",
249329
+ "examples",
249330
+ "default",
249331
+ "enum",
249332
+ "const"
249333
+ ]);
249334
+ function slimSchema(node, isPropertyMap = false) {
249335
+ if (Array.isArray(node)) {
249336
+ return node.map((item) => slimSchema(item));
249337
+ }
249338
+ if (node === null || typeof node !== "object") {
249339
+ return node;
249340
+ }
249341
+ const entries = Object.entries(node);
249342
+ if (isPropertyMap) {
249343
+ return Object.fromEntries(entries.map(([name, value]) => [name, slimSchema(value)]));
249344
+ }
249345
+ const slim = {};
249346
+ for (const [key, value] of entries) {
249347
+ if (key === "title" && typeof value === "string") {
249348
+ continue;
249349
+ }
249350
+ slim[key] = SCHEMA_DATA_KEYS.has(key) ? value : key === "properties" ? slimSchema(value, true) : key === "description" && typeof value === "string" ? cleanText(value) : slimSchema(value);
249351
+ }
249352
+ const { anyOf, ...rest } = slim;
249353
+ const nullable = Array.isArray(anyOf) && anyOf.length === 2 ? nullableType(anyOf) : undefined;
249354
+ return nullable ? { type: [nullable, "null"], ...rest } : slim;
249355
+ }
249356
+ function nullableType(variants) {
249357
+ const types = variants.map((variant) => variant !== null && typeof variant === "object" && Object.keys(variant).length === 1 && typeof variant.type === "string" ? variant.type : undefined);
249358
+ if (types.includes(undefined) || !types.includes("null")) {
249359
+ return;
249360
+ }
249361
+ return types.find((type) => type !== "null");
249362
+ }
249425
249363
  function getOperationContract(spec, op) {
249426
249364
  const schemas = spec.components?.schemas ?? {};
249427
- const inline = (node) => node === undefined ? null : inlineRefs(node, schemas);
249365
+ const inline = (node) => node === undefined ? null : slimSchema(inlineRefs(node, schemas));
249428
249366
  const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
249429
249367
  const parsed = ResponseObjectSchema.safeParse(response);
249430
249368
  return parsed.success ? [[status, parsed.data]] : [];
249431
249369
  });
249432
- const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
249433
- const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
249434
- const requestBody = requestBodyOf(op.operation.requestBody);
249370
+ const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => bodyOf(response).schema).find(Boolean);
249371
+ const requestBody = bodyOf(op.operation.requestBody);
249435
249372
  const contract = {
249436
249373
  endpoint: op.endpoint,
249437
249374
  method: op.method,
@@ -249451,24 +249388,105 @@ function getOperationContract(spec, op) {
249451
249388
  in: location2,
249452
249389
  required: required ?? false,
249453
249390
  schema: inline(schema ?? {}),
249454
- ...description && !inSchema ? { description } : {},
249391
+ ...description && !inSchema ? { description: cleanText(description) } : {},
249455
249392
  ..."example" in parsed.data ? { example: parsed.data.example } : {}
249456
249393
  }
249457
249394
  ];
249458
249395
  }),
249459
249396
  ...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
249460
249397
  requestBodySchema: inline(requestBody.schema),
249461
- responseSchema: inline(success),
249462
- errors: Object.fromEntries(errors.map(([status, response]) => [status, response.description ?? ""]))
249398
+ responseSchema: inline(success)
249463
249399
  };
249464
249400
  const refs = leftoverRefs(contract, schemas);
249465
249401
  return {
249466
249402
  ...contract,
249467
- ...refs.size > 0 ? { refs: Object.fromEntries(refs) } : {}
249403
+ ...refs.size > 0 ? {
249404
+ refs: Object.fromEntries([...refs].map(([ref, schema]) => [ref, slimSchema(schema)]))
249405
+ } : {}
249406
+ };
249407
+ }
249408
+ // src/core/api-spec/grep.ts
249409
+ function grepOperations(spec, operations, pattern, options = {}) {
249410
+ const regex = new RegExp(pattern, options.ignoreCase ? "i" : "");
249411
+ return operations.filter((op) => regex.test(JSON.stringify(getOperationContract(spec, op)))).slice(0, options.limit ?? 20).map(toOperationSummary);
249412
+ }
249413
+ // src/core/api-spec/operations.ts
249414
+ var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
249415
+ var READ_ONLY_SCOPE = "read_only";
249416
+ function isReadOnly(operation, spec) {
249417
+ const security = operation.security ?? spec.security ?? [];
249418
+ return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
249419
+ }
249420
+ function parameterText(operation) {
249421
+ return (operation.parameters ?? []).flatMap((parameter) => {
249422
+ const parsed = ParameterSchema.safeParse(parameter);
249423
+ return parsed.success ? [parsed.data.name, cleanText(parsed.data.description ?? "")] : [];
249424
+ }).join(" ");
249425
+ }
249426
+ function mergeParameters(shared, own) {
249427
+ if (!shared?.length) {
249428
+ return own;
249429
+ }
249430
+ const key = (parameter) => {
249431
+ const parsed = ParameterSchema.safeParse(parameter);
249432
+ return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249468
249433
  };
249434
+ const ownKeys = new Set((own ?? []).map(key));
249435
+ return [
249436
+ ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249437
+ ...own ?? []
249438
+ ];
249439
+ }
249440
+ function listOperations(spec) {
249441
+ return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249442
+ const declared = item[method];
249443
+ if (!declared) {
249444
+ return [];
249445
+ }
249446
+ const operation = {
249447
+ ...declared,
249448
+ parameters: mergeParameters(item.parameters, declared.parameters)
249449
+ };
249450
+ return [
249451
+ {
249452
+ endpoint: `${method.toUpperCase()} ${path}`,
249453
+ method: method.toUpperCase(),
249454
+ path,
249455
+ summary: operation.summary ?? "",
249456
+ description: cleanText(operation.description ?? ""),
249457
+ parameterText: parameterText(operation),
249458
+ readOnly: isReadOnly(operation, spec),
249459
+ operation
249460
+ }
249461
+ ];
249462
+ }));
249463
+ }
249464
+ function pathSegments(path) {
249465
+ const pathname = path.split(/[?#]/, 1)[0] ?? "";
249466
+ return pathname.split("/").filter(Boolean);
249467
+ }
249468
+ function segmentPattern(segment) {
249469
+ const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
249470
+ return new RegExp(`^${source}$`);
249471
+ }
249472
+ function literalSegments(path) {
249473
+ return pathSegments(path).map((segment) => segment.includes("{") ? "0" : "1").join("");
249474
+ }
249475
+ function matchOperation(operations, method, concretePath) {
249476
+ const upperMethod = method.toUpperCase();
249477
+ const segments = pathSegments(concretePath);
249478
+ const candidates = operations.filter((op) => {
249479
+ if (op.method !== upperMethod) {
249480
+ return false;
249481
+ }
249482
+ const template = pathSegments(op.path);
249483
+ return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
249484
+ });
249485
+ return candidates.sort((a, b) => literalSegments(b.path).localeCompare(literalSegments(a.path)))[0];
249469
249486
  }
249470
249487
  // src/core/api-spec/request.ts
249471
249488
  var MAX_ERROR_BODY_CHARS = 4000;
249489
+ var QUERY_STRING = /\?\S*/g;
249472
249490
  async function readBody(response) {
249473
249491
  try {
249474
249492
  const text = (await response.clone().text()).trim();
@@ -249483,7 +249501,8 @@ async function sendApiRequest(method, path, body) {
249483
249501
  method,
249484
249502
  body,
249485
249503
  headers: body === undefined ? {} : { "Content-Type": "application/json" },
249486
- timeout: false
249504
+ timeout: false,
249505
+ retry: { methods: ["get", "head"] }
249487
249506
  });
249488
249507
  return {
249489
249508
  status: response.status,
@@ -249493,18 +249512,23 @@ async function sendApiRequest(method, path, body) {
249493
249512
  } catch (error) {
249494
249513
  const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249495
249514
  const raw = error instanceof HTTPError ? await readBody(error.response) : undefined;
249496
- throw new ApiError(apiError.message, {
249497
- statusCode: apiError.statusCode,
249498
- requestUrl: apiError.requestUrl,
249499
- requestMethod: apiError.requestMethod,
249500
- requestId: apiError.requestId,
249501
- hints: apiError.hints,
249502
- details: raw ? [`Response body: ${raw}`] : apiError.details
249503
- });
249515
+ throw redactedApiError(apiError, raw, method, path);
249504
249516
  }
249505
249517
  }
249518
+ function redactedApiError(apiError, raw, method, path) {
249519
+ const reason = apiError.statusCode !== undefined ? `HTTP ${apiError.statusCode}` : (apiError.cause?.message ?? "request failed").replace(QUERY_STRING, "");
249520
+ const message = `Error calling ${method} ${path.split("?", 1)[0]}: ${reason}`;
249521
+ return new ApiError(message, {
249522
+ statusCode: apiError.statusCode,
249523
+ requestUrl: apiError.requestUrl?.split("?", 1)[0],
249524
+ requestMethod: apiError.requestMethod,
249525
+ requestId: apiError.requestId,
249526
+ hints: apiError.hints,
249527
+ details: raw ? [`Response body: ${raw}`] : apiError.details
249528
+ });
249529
+ }
249506
249530
  // src/core/api-spec/spec.ts
249507
- import { rename, stat as stat3 } from "node:fs/promises";
249531
+ import { rename, rm, stat as stat3 } from "node:fs/promises";
249508
249532
  import { join as join22 } from "node:path";
249509
249533
  var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
249510
249534
  function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
@@ -249559,8 +249583,14 @@ async function loadSpec(options = {}) {
249559
249583
  const text = await downloadSpec();
249560
249584
  const spec = parseSpec(text);
249561
249585
  const partial = `${path}.${process.pid}.tmp`;
249562
- await writeFile(partial, text);
249563
- await rename(partial, path);
249586
+ try {
249587
+ await writeFile(partial, text);
249588
+ await rename(partial, path);
249589
+ } catch {
249590
+ await rm(partial, { force: true }).catch(() => {
249591
+ return;
249592
+ });
249593
+ }
249564
249594
  return { text, spec };
249565
249595
  }
249566
249596
  // src/cli/commands/api/shared.ts
@@ -249616,6 +249646,19 @@ async function readRequestBody(flag, log) {
249616
249646
  }
249617
249647
  return flag;
249618
249648
  }
249649
+ function withoutQuery(path) {
249650
+ return path.split("?", 1)[0] ?? "";
249651
+ }
249652
+ function reportedFetchCommand(method, path, options) {
249653
+ return {
249654
+ name: "api fetch",
249655
+ args: [method, withoutQuery(path)],
249656
+ options: {
249657
+ ...options,
249658
+ ...options.body === undefined ? {} : { body: "[not reported]" }
249659
+ }
249660
+ };
249661
+ }
249619
249662
 
249620
249663
  // src/cli/commands/api/catalog.ts
249621
249664
  async function catalogAction(ctx, area, options) {
@@ -249636,15 +249679,15 @@ function getApiCatalogCommand() {
249636
249679
  }
249637
249680
 
249638
249681
  // src/cli/commands/api/fetch.ts
249639
- async function findOperation(ctx, method, path, refresh) {
249682
+ async function findOperation(ctx, method, path, { refresh, flag }) {
249640
249683
  const { spec } = await loadSpecTask(ctx, refresh);
249641
249684
  const op = matchOperation(listOperations(spec), method, path);
249642
249685
  if (!op) {
249643
- throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
249686
+ throw new InvalidInputError(`No operation in the API spec matches ${method} ${withoutQuery(path)}.`, {
249644
249687
  hints: [
249645
249688
  {
249646
249689
  message: "The cached spec may predate this route; fetch it again",
249647
- command: "base44 api fetch <METHOD> <path> --help --refresh"
249690
+ command: `base44 api fetch ${method} ${path} ${flag} --refresh`
249648
249691
  },
249649
249692
  {
249650
249693
  message: "Find the operation and its path template",
@@ -249655,6 +249698,8 @@ async function findOperation(ctx, method, path, refresh) {
249655
249698
  }
249656
249699
  return { spec, op };
249657
249700
  }
249701
+ var CONTRACT_HELP = `
249702
+ The contract is JSON; cut it down with e.g. | jq '.parameters, .requestBodySchema'`;
249658
249703
  var TEXT_CONTENT_TYPES = [
249659
249704
  "json",
249660
249705
  "text/",
@@ -249694,31 +249739,34 @@ async function formatResponse({ status, contentType, body }, output, jsonMode) {
249694
249739
  }
249695
249740
  }
249696
249741
  async function fetchAction(ctx, methodArg, path, options, command) {
249742
+ ctx.errorReporter.setContext({
249743
+ command: reportedFetchCommand(methodArg ?? "", path ?? "", { ...options })
249744
+ });
249697
249745
  if (!methodArg || !path) {
249698
249746
  if (options.help) {
249699
- const usage = command.helpInformation();
249747
+ const usage = `${command.helpInformation()}${CONTRACT_HELP}
249748
+ `;
249700
249749
  return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
249701
249750
  }
249702
249751
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249703
249752
  }
249704
249753
  const method = methodArg.toUpperCase();
249705
249754
  if (options.help) {
249706
- const { spec, op } = await findOperation(ctx, method, path, options.refresh);
249755
+ const { spec, op } = await findOperation(ctx, method, path, {
249756
+ refresh: options.refresh,
249757
+ flag: "--help"
249758
+ });
249707
249759
  return { stdout: formatJson(getOperationContract(spec, op)) };
249708
249760
  }
249709
249761
  if (options.readOnly) {
249710
- const { op } = await findOperation(ctx, method, path, options.refresh);
249762
+ const { op } = await findOperation(ctx, method, path, {
249763
+ refresh: options.refresh,
249764
+ flag: "--read-only"
249765
+ });
249711
249766
  if (!op.readOnly) {
249712
249767
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249713
249768
  }
249714
249769
  }
249715
- ctx.errorReporter.setContext({
249716
- command: {
249717
- name: "api fetch",
249718
- args: [method, path.split("?", 1)[0] ?? ""],
249719
- options: { ...options, body: options.body && "[not reported]" }
249720
- }
249721
- });
249722
249770
  await ensureAuth(ctx);
249723
249771
  const body = await readRequestBody(options.body, ctx.log);
249724
249772
  const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
@@ -249733,7 +249781,7 @@ function getApiFetchCommand() {
249733
249781
  return new Base44Command("fetch", {
249734
249782
  requireAuth: false,
249735
249783
  requireAppContext: false
249736
- }).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 @- to read it from stdin").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);
249784
+ }).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]", '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 @- to read it from stdin").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", CONTRACT_HELP).action(fetchAction);
249737
249785
  }
249738
249786
 
249739
249787
  // src/cli/commands/api/grep.ts
@@ -249755,11 +249803,9 @@ async function grepAction(ctx, pattern, options) {
249755
249803
  if (options.readOnly) {
249756
249804
  operations = operations.filter((op) => op.readOnly);
249757
249805
  }
249758
- const narrowed = options.area !== undefined || options.readOnly === true;
249759
- const hits = grepSpec(spec, operations, pattern, {
249806
+ const hits = grepOperations(spec, operations, pattern, {
249760
249807
  ignoreCase: options.ignoreCase,
249761
- limit,
249762
- schemas: !narrowed
249808
+ limit
249763
249809
  });
249764
249810
  return { stdout: formatJson(hits) };
249765
249811
  }
@@ -249767,7 +249813,7 @@ function getApiGrepCommand() {
249767
249813
  return new Base44Command("grep", {
249768
249814
  requireAuth: false,
249769
249815
  requireAppContext: false
249770
- }).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);
249816
+ }).description("Search the 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 to return (default 20)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
249771
249817
  }
249772
249818
 
249773
249819
  // src/cli/commands/api/search.ts
@@ -262327,7 +262373,7 @@ var nativeEnumType = ZodNativeEnum.create;
262327
262373
  var promiseType = ZodPromise.create;
262328
262374
  var effectsType = ZodEffects.create;
262329
262375
  var optionalType = ZodOptional2.create;
262330
- var nullableType = ZodNullable2.create;
262376
+ var nullableType2 = ZodNullable2.create;
262331
262377
  var preprocessType = ZodEffects.createWithPreprocess;
262332
262378
  var pipelineType = ZodPipeline.create;
262333
262379
  // ../functions-compiler/src/contracts.ts
@@ -262357,7 +262403,7 @@ var bundleAppRequestSchema = objectType({
262357
262403
  var ACTIVATION_MODE = "pull";
262358
262404
 
262359
262405
  // ../functions-compiler/src/deno-bundle.ts
262360
- import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
262406
+ import { mkdtemp, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
262361
262407
  import { tmpdir as tmpdir2 } from "node:os";
262362
262408
  import path21 from "node:path";
262363
262409
 
@@ -262964,7 +263010,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
262964
263010
  warnings: result.warnings.map((w) => w.text)
262965
263011
  };
262966
263012
  } finally {
262967
- await rm(dir, { recursive: true, force: true });
263013
+ await rm2(dir, { recursive: true, force: true });
262968
263014
  }
262969
263015
  }
262970
263016
  function buildFailureErrors(e, dir) {
@@ -273329,4 +273375,4 @@ export {
273329
273375
  runCLI
273330
273376
  };
273331
273377
 
273332
- //# debugId=4F218AD4EF632ED564756E2164756E21
273378
+ //# debugId=A6B266663FAD34EF64756E2164756E21