@base44-preview/cli 0.1.32-pr.663.8c44c88 → 0.1.32-pr.663.ab2ede0

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
@@ -119123,7 +119123,7 @@ import url22 from "url";
119123
119123
  function diffLines(oldStr, newStr, options8) {
119124
119124
  return lineDiff.diff(oldStr, newStr, options8);
119125
119125
  }
119126
- function tokenize(value, options8) {
119126
+ function tokenize2(value, options8) {
119127
119127
  if (options8.stripTrailingCr) {
119128
119128
  value = value.replace(/\r\n/g, `
119129
119129
  `);
@@ -120053,7 +120053,7 @@ function highlight(text) {
120053
120053
  for (const {
120054
120054
  type,
120055
120055
  value
120056
- } of tokenize2(text)) {
120056
+ } of tokenize22(text)) {
120057
120057
  if (type in defs) {
120058
120058
  highlighted += value.split(NEWLINE$1).map((str) => defs[type](str)).join(`
120059
120059
  `);
@@ -124581,7 +124581,7 @@ var require2, __filename2, __dirname3, __create2, __defProp3, __getOwnPropDesc2,
124581
124581
  return internalize({ "": root }, "", reviver);
124582
124582
  }
124583
124583
  return root;
124584
- }, lexState, buffer, doubleQuote, sign, c7, lexStates, parseStates, dist_default, import_picocolors4, import_js_tokens, nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࡰ-ࢇࢉ-࢏ࢠ-ࣉऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚ౜ౝౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ೜-ೞೠೡೱೲഄ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜑᜟ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭌᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲊᲐ-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-Ƛ꟱-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ", nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࢗ-࢟࣊-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍୕-ୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఄ఼ా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ೳഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ඁ-ඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ຼ່-໎໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜕ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠏-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᪿ-᫝᫠-᫫ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭᳴᳷-᳹᷀-᷿‌‍‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯・꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧ꠬ꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱ꣿ-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_・", nonASCIIidentifierStart, nonASCIIidentifier, reservedWords, keywords, reservedWordsStrictSet, reservedWordsStrictBindSet, compose = (f, g) => (v) => f(g(v)), defsOn, defsOff, sometimesKeywords, NEWLINE$1, BRACKET, tokenize2, NEWLINE, getOffsets = ({
124584
+ }, lexState, buffer, doubleQuote, sign, c7, lexStates, parseStates, dist_default, import_picocolors4, import_js_tokens, nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࡰ-ࢇࢉ-࢏ࢠ-ࣉऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚ౜ౝౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ೜-ೞೠೡೱೲഄ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜑᜟ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭌᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲊᲐ-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-Ƛ꟱-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ", nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࢗ-࢟࣊-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍୕-ୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఄ఼ా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ೳഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ඁ-ඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ຼ່-໎໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜕ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠏-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᪿ-᫝᫠-᫫ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭᳴᳷-᳹᷀-᷿‌‍‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯・꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧ꠬ꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱ꣿ-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_・", nonASCIIidentifierStart, nonASCIIidentifier, reservedWords, keywords, reservedWordsStrictSet, reservedWordsStrictBindSet, compose = (f, g) => (v) => f(g(v)), defsOn, defsOff, sometimesKeywords, NEWLINE$1, BRACKET, tokenize22, NEWLINE, getOffsets = ({
124585
124585
  oneBased,
124586
124586
  oneBasedLine = oneBased,
124587
124587
  oneBasedColumn = oneBased
@@ -133471,7 +133471,7 @@ globstar while`, file, fr, pattern, pr, swallowee);
133471
133471
  LineDiff = class extends Diff {
133472
133472
  constructor() {
133473
133473
  super(...arguments);
133474
- this.tokenize = tokenize;
133474
+ this.tokenize = tokenize2;
133475
133475
  }
133476
133476
  equals(left, right, options8) {
133477
133477
  if (options8.ignoreWhitespace) {
@@ -134348,7 +134348,7 @@ globstar while`, file, fr, pattern, pr, swallowee);
134348
134348
  return "uncolored";
134349
134349
  }
134350
134350
  };
134351
- tokenize2 = function* (text) {
134351
+ tokenize22 = function* (text) {
134352
134352
  for (const token2 of (0, import_js_tokens.default)(text, {
134353
134353
  jsx: true
134354
134354
  })) {
@@ -247587,8 +247587,8 @@ function normalizeDatetime(value) {
247587
247587
  return `${value}Z`;
247588
247588
  }
247589
247589
  // src/cli/utils/json.ts
247590
- function toJsonStdout(result) {
247591
- return `${JSON.stringify(result, null, 2)}
247590
+ function toJsonStdout(result, options = {}) {
247591
+ return `${JSON.stringify(result, null, options.compact ? undefined : 2)}
247592
247592
  `;
247593
247593
  }
247594
247594
  // src/cli/errors.ts
@@ -249102,19 +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;
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(" "));
249115
+ function tokenize(text) {
249116
+ return text.split(TOKEN_SEPARATOR).filter((word) => word.length >= 2 && !STOPWORDS.has(word.toLowerCase()));
249117
+ }
249108
249118
  function toOperationSummary(op) {
249109
249119
  return { endpoint: op.endpoint, summary: op.summary };
249110
249120
  }
249111
249121
  function buildSearchIndex(operations) {
249112
249122
  const index = new MiniSearch({
249113
- fields: ["path", "summary", "description", "parameters"],
249114
- tokenize: (text) => text.split(TOKEN_SEPARATOR).filter(Boolean)
249123
+ fields: ["method", "path", "summary", "description", "parameters"],
249124
+ tokenize
249115
249125
  });
249116
249126
  index.addAll(operations.map((op, id) => ({
249117
249127
  id,
249128
+ method: op.method,
249118
249129
  path: op.path.replace(/\{[^}]*\}/g, ""),
249119
249130
  summary: op.summary,
249120
249131
  description: op.description,
@@ -249122,16 +249133,37 @@ function buildSearchIndex(operations) {
249122
249133
  })));
249123
249134
  return index;
249124
249135
  }
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
+ };
249143
+ }
249144
+ var readsFirst = (op) => op?.method === "GET" ? 0 : 1;
249125
249145
  function searchOperations(operations, query, options = {}) {
249146
+ const terms = tokenize(query.toLowerCase());
249147
+ if (terms.length === 0) {
249148
+ return [];
249149
+ }
249126
249150
  const index = buildSearchIndex(operations);
249127
249151
  const hits = index.search(query, {
249128
- prefix: true,
249129
- fuzzy: 0.2,
249152
+ prefix: (term) => term.length >= 3,
249153
+ fuzzy: (term) => term.length >= 4 ? 0.2 : false,
249130
249154
  boost: BOOST,
249131
249155
  filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
249132
- });
249133
- const baseline = (hits[0]?.score ?? 0) * MIN_RELATIVE_SCORE;
249134
- 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) => {
249135
249167
  const op = operations[hit.id];
249136
249168
  return op ? [toOperationSummary(op)] : [];
249137
249169
  });
@@ -249140,6 +249172,7 @@ function searchOperations(operations, query, options = {}) {
249140
249172
  // src/core/api-spec/catalog.ts
249141
249173
  var INLINE_AREA_MAX = 2;
249142
249174
  var AREA_SAMPLE_MAX = 3;
249175
+ var AREA_OPERATIONS_MAX = 200;
249143
249176
  var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
249144
249177
  function areaOf(path) {
249145
249178
  const parts = path.split("/").filter(Boolean);
@@ -249161,7 +249194,7 @@ function groupByArea(operations) {
249161
249194
  }
249162
249195
  return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
249163
249196
  }
249164
- function readsFirst(ops) {
249197
+ function readsFirst2(ops) {
249165
249198
  const isRead = (op) => op.method === "GET" ? 0 : 1;
249166
249199
  return [...ops].sort((a, b) => isRead(a) - isRead(b));
249167
249200
  }
@@ -249169,48 +249202,17 @@ function catalogIndex(operations) {
249169
249202
  const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
249170
249203
  area,
249171
249204
  operationCount: ops.length,
249172
- 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)
249173
249206
  });
249174
249207
  return { areas, total: operations.length };
249175
249208
  }
249176
- // src/core/api-spec/grep.ts
249177
- var CONTEXT_CHARS = 40;
249178
- var MAX_SNIPPETS = 3;
249179
- var MAX_SNIPPET_CHARS = 200;
249180
- function unescapeJson(snippet) {
249181
- return snippet.replace(/\\[nrt]/g, " ").replace(/\\"/g, '"');
249182
- }
249183
- function snippets(text, pattern) {
249184
- const found = [];
249185
- for (const match of text.matchAll(pattern)) {
249186
- const start = Math.max(0, match.index - CONTEXT_CHARS);
249187
- const end = match.index + match[0].length + CONTEXT_CHARS;
249188
- found.push(unescapeJson(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS))));
249189
- if (found.length === MAX_SNIPPETS || match[0].length === 0) {
249190
- break;
249191
- }
249192
- }
249193
- return found;
249194
- }
249195
- function grepSpec(spec, operations, pattern, options = {}) {
249196
- const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249197
- const hits = [];
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);
249202
- if (matches.length > 0) {
249203
- hits.push({ ...toOperationSummary(op), matches });
249204
- }
249205
- }
249206
- const schemas = options.area === undefined && !options.readOnly ? spec.components?.schemas : {};
249207
- for (const [schema, definition] of Object.entries(schemas ?? {})) {
249208
- const matches = snippets(JSON.stringify(definition), regex);
249209
- if (matches.length > 0) {
249210
- hits.push({ schema, matches });
249211
- }
249212
- }
249213
- return hits.slice(0, options.limit ?? 20);
249209
+ function areaListing(area, operations, max = AREA_OPERATIONS_MAX) {
249210
+ return {
249211
+ area,
249212
+ operations: operations.slice(0, max).map(toOperationSummary),
249213
+ total: operations.length,
249214
+ truncated: operations.length > max
249215
+ };
249214
249216
  }
249215
249217
  // src/core/api-spec/schema.ts
249216
249218
  var HTTP_METHODS = [
@@ -249232,7 +249234,7 @@ var ParameterSchema = looseObject({
249232
249234
  example: unknown().optional()
249233
249235
  });
249234
249236
  var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
249235
- var RequestBodySchema = looseObject({
249237
+ var MediaContentSchema = looseObject({
249236
249238
  content: MediaTypesSchema.optional()
249237
249239
  });
249238
249240
  var ResponseObjectSchema = looseObject({
@@ -249249,7 +249251,10 @@ var OperationSchema = looseObject({
249249
249251
  responses: record(string2(), unknown()).optional(),
249250
249252
  security: array(SecurityRequirementSchema).optional()
249251
249253
  });
249252
- var PathItemSchema = looseObject(Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])));
249254
+ var PathItemSchema = looseObject({
249255
+ ...Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])),
249256
+ parameters: array(unknown()).optional()
249257
+ });
249253
249258
  var OpenApiSpecSchema = looseObject({
249254
249259
  openapi: string2(),
249255
249260
  paths: record(string2(), PathItemSchema),
@@ -249259,70 +249264,7 @@ var OpenApiSpecSchema = looseObject({
249259
249264
  security: array(SecurityRequirementSchema).optional()
249260
249265
  });
249261
249266
 
249262
- // src/core/api-spec/operations.ts
249263
- var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
249264
- var READ_ONLY_SCOPE = "read_only";
249265
- function isReadOnly(operation, spec) {
249266
- const security = operation.security ?? spec.security ?? [];
249267
- return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
249268
- }
249269
- function parameterText(operation) {
249270
- return (operation.parameters ?? []).flatMap((parameter) => {
249271
- const parsed = ParameterSchema.safeParse(parameter);
249272
- return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249273
- }).join(" ");
249274
- }
249275
- function listOperations(spec) {
249276
- return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249277
- const operation = item[method];
249278
- if (!operation) {
249279
- return [];
249280
- }
249281
- return [
249282
- {
249283
- endpoint: `${method.toUpperCase()} ${path}`,
249284
- method: method.toUpperCase(),
249285
- path,
249286
- summary: operation.summary ?? "",
249287
- description: operation.description ?? "",
249288
- parameterText: parameterText(operation),
249289
- readOnly: isReadOnly(operation, spec),
249290
- operation
249291
- }
249292
- ];
249293
- }));
249294
- }
249295
- function pathSegments(path) {
249296
- const pathname = path.split(/[?#]/, 1)[0] ?? "";
249297
- return pathname.split("/").filter(Boolean);
249298
- }
249299
- function segmentPattern(segment) {
249300
- const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
249301
- return new RegExp(`^${source}$`);
249302
- }
249303
- function specificity(templateSegments) {
249304
- return templateSegments.map((segment) => segment.includes("{") ? 0 : 1);
249305
- }
249306
- function compareSpecificity(a, b) {
249307
- for (let i = 0;i < a.length; i++) {
249308
- if (a[i] !== b[i]) {
249309
- return (b[i] ?? 0) - (a[i] ?? 0);
249310
- }
249311
- }
249312
- return 0;
249313
- }
249314
- function matchOperation(operations, method, concretePath) {
249315
- const upperMethod = method.toUpperCase();
249316
- const segments = pathSegments(concretePath);
249317
- const candidates = operations.filter((op) => {
249318
- if (op.method !== upperMethod) {
249319
- return false;
249320
- }
249321
- const template = pathSegments(op.path);
249322
- return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
249323
- });
249324
- return candidates.sort((a, b) => compareSpecificity(specificity(pathSegments(a.path)), specificity(pathSegments(b.path))))[0];
249325
- }
249267
+ // src/core/api-spec/contract.ts
249326
249268
  var SCHEMA_REF_PREFIX = "#/components/schemas/";
249327
249269
  var MAX_REF_DEPTH = 4;
249328
249270
  var FRAMEWORK_VALIDATION_ERROR = "Validation Error";
@@ -249350,25 +249292,87 @@ function inlineRefs(node, schemas, seen = new Set, depth = 0) {
249350
249292
  inlineRefs(value, schemas, seen, depth)
249351
249293
  ]));
249352
249294
  }
249353
- function jsonSchemaOf(value) {
249354
- const parsed = RequestBodySchema.safeParse(value);
249355
- return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
249295
+ function bodyOf(value) {
249296
+ const parsed = MediaContentSchema.safeParse(value);
249297
+ const content = parsed.success ? parsed.data.content ?? {} : {};
249298
+ const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
249299
+ return contentType ? { contentType, schema: content[contentType]?.schema } : {};
249300
+ }
249301
+ function leftoverRefs(node, schemas, found = new Map) {
249302
+ if (Array.isArray(node)) {
249303
+ for (const item of node) {
249304
+ leftoverRefs(item, schemas, found);
249305
+ }
249306
+ } else if (node !== null && typeof node === "object") {
249307
+ for (const [key, value] of Object.entries(node)) {
249308
+ if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
249309
+ const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
249310
+ found.set(value, schema);
249311
+ leftoverRefs(schema, schemas, found);
249312
+ } else {
249313
+ leftoverRefs(value, schemas, found);
249314
+ }
249315
+ }
249316
+ }
249317
+ return found;
249318
+ }
249319
+ var SCHEMA_DATA_KEYS = new Set([
249320
+ "example",
249321
+ "examples",
249322
+ "default",
249323
+ "enum",
249324
+ "const"
249325
+ ]);
249326
+ var DOCS_CALLOUT = /<(Info|Note|Tip|Check|Warning)>([\s\S]*?)<\/\1>/g;
249327
+ var RELATIVE_LINK = /\[([^\]]+)\]\(\/[^)]*\)/g;
249328
+ function cleanText(text) {
249329
+ return text.replace(DOCS_CALLOUT, (_, kind, body) => kind === "Warning" ? `Warning: ${body}` : body).replace(RELATIVE_LINK, "$1");
249330
+ }
249331
+ function slimSchema(node, isPropertyMap = false) {
249332
+ if (Array.isArray(node)) {
249333
+ return node.map((item) => slimSchema(item));
249334
+ }
249335
+ if (node === null || typeof node !== "object") {
249336
+ return node;
249337
+ }
249338
+ const entries = Object.entries(node);
249339
+ if (isPropertyMap) {
249340
+ return Object.fromEntries(entries.map(([name, value]) => [name, slimSchema(value)]));
249341
+ }
249342
+ const slim = {};
249343
+ for (const [key, value] of entries) {
249344
+ if (key === "title" && typeof value === "string") {
249345
+ continue;
249346
+ }
249347
+ slim[key] = SCHEMA_DATA_KEYS.has(key) ? value : key === "properties" ? slimSchema(value, true) : key === "description" && typeof value === "string" ? cleanText(value) : slimSchema(value);
249348
+ }
249349
+ const { anyOf, ...rest } = slim;
249350
+ const nullable = Array.isArray(anyOf) && anyOf.length === 2 ? nullableType(anyOf) : undefined;
249351
+ return nullable ? { type: [nullable, "null"], ...rest } : slim;
249352
+ }
249353
+ function nullableType(variants) {
249354
+ const types = variants.map((variant) => variant !== null && typeof variant === "object" && Object.keys(variant).length === 1 && typeof variant.type === "string" ? variant.type : undefined);
249355
+ if (types.includes(undefined) || !types.includes("null")) {
249356
+ return;
249357
+ }
249358
+ return types.find((type) => type !== "null");
249356
249359
  }
249357
249360
  function getOperationContract(spec, op) {
249358
249361
  const schemas = spec.components?.schemas ?? {};
249359
- const inline = (node) => node === undefined ? null : inlineRefs(node, schemas);
249362
+ const inline = (node) => node === undefined ? null : slimSchema(inlineRefs(node, schemas));
249360
249363
  const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
249361
249364
  const parsed = ResponseObjectSchema.safeParse(response);
249362
249365
  return parsed.success ? [[status, parsed.data]] : [];
249363
249366
  });
249364
- const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
249367
+ const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => bodyOf(response).schema).find(Boolean);
249365
249368
  const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
249366
- return {
249369
+ const requestBody = bodyOf(op.operation.requestBody);
249370
+ const contract = {
249367
249371
  endpoint: op.endpoint,
249368
249372
  method: op.method,
249369
249373
  path: op.path,
249370
249374
  summary: op.summary,
249371
- description: op.description,
249375
+ description: cleanText(op.description),
249372
249376
  parameters: (op.operation.parameters ?? []).flatMap((parameter) => {
249373
249377
  const parsed = ParameterSchema.safeParse(parameter);
249374
249378
  if (!parsed.success) {
@@ -249382,23 +249386,123 @@ function getOperationContract(spec, op) {
249382
249386
  in: location2,
249383
249387
  required: required ?? false,
249384
249388
  schema: inline(schema ?? {}),
249385
- ...description && !inSchema ? { description } : {},
249389
+ ...description && !inSchema ? { description: cleanText(description) } : {},
249386
249390
  ..."example" in parsed.data ? { example: parsed.data.example } : {}
249387
249391
  }
249388
249392
  ];
249389
249393
  }),
249390
- requestBodySchema: inline(jsonSchemaOf(op.operation.requestBody)),
249394
+ ...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
249395
+ requestBodySchema: inline(requestBody.schema),
249391
249396
  responseSchema: inline(success),
249392
- errors: Object.fromEntries(errors.map(([status, response]) => [status, response.description ?? ""]))
249397
+ errors: Object.fromEntries(errors.map(([status, response]) => [
249398
+ status,
249399
+ cleanText(response.description ?? "")
249400
+ ]))
249401
+ };
249402
+ const refs = leftoverRefs(contract, schemas);
249403
+ return {
249404
+ ...contract,
249405
+ ...refs.size > 0 ? {
249406
+ refs: Object.fromEntries([...refs].map(([ref, schema]) => [ref, slimSchema(schema)]))
249407
+ } : {}
249408
+ };
249409
+ }
249410
+ // src/core/api-spec/grep.ts
249411
+ function grepOperations(spec, operations, pattern, options = {}) {
249412
+ const regex = new RegExp(pattern, options.ignoreCase ? "i" : "");
249413
+ return operations.filter((op) => regex.test(JSON.stringify(getOperationContract(spec, op)))).slice(0, options.limit ?? 20).map(toOperationSummary);
249414
+ }
249415
+ // src/core/api-spec/operations.ts
249416
+ var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
249417
+ var READ_ONLY_SCOPE = "read_only";
249418
+ function isReadOnly(operation, spec) {
249419
+ const security = operation.security ?? spec.security ?? [];
249420
+ return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
249421
+ }
249422
+ function parameterText(operation) {
249423
+ return (operation.parameters ?? []).flatMap((parameter) => {
249424
+ const parsed = ParameterSchema.safeParse(parameter);
249425
+ return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249426
+ }).join(" ");
249427
+ }
249428
+ function mergeParameters(shared, own) {
249429
+ if (!shared?.length) {
249430
+ return own;
249431
+ }
249432
+ const key = (parameter) => {
249433
+ const parsed = ParameterSchema.safeParse(parameter);
249434
+ return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249393
249435
  };
249436
+ const ownKeys = new Set((own ?? []).map(key));
249437
+ return [
249438
+ ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249439
+ ...own ?? []
249440
+ ];
249441
+ }
249442
+ function listOperations(spec) {
249443
+ return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249444
+ const declared = item[method];
249445
+ if (!declared) {
249446
+ return [];
249447
+ }
249448
+ const operation = {
249449
+ ...declared,
249450
+ parameters: mergeParameters(item.parameters, declared.parameters)
249451
+ };
249452
+ return [
249453
+ {
249454
+ endpoint: `${method.toUpperCase()} ${path}`,
249455
+ method: method.toUpperCase(),
249456
+ path,
249457
+ summary: operation.summary ?? "",
249458
+ description: operation.description ?? "",
249459
+ parameterText: parameterText(operation),
249460
+ readOnly: isReadOnly(operation, spec),
249461
+ operation
249462
+ }
249463
+ ];
249464
+ }));
249465
+ }
249466
+ function pathSegments(path) {
249467
+ const pathname = path.split(/[?#]/, 1)[0] ?? "";
249468
+ return pathname.split("/").filter(Boolean);
249469
+ }
249470
+ function segmentPattern(segment) {
249471
+ const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
249472
+ return new RegExp(`^${source}$`);
249473
+ }
249474
+ function literalSegments(path) {
249475
+ return pathSegments(path).map((segment) => segment.includes("{") ? "0" : "1").join("");
249476
+ }
249477
+ function matchOperation(operations, method, concretePath) {
249478
+ const upperMethod = method.toUpperCase();
249479
+ const segments = pathSegments(concretePath);
249480
+ const candidates = operations.filter((op) => {
249481
+ if (op.method !== upperMethod) {
249482
+ return false;
249483
+ }
249484
+ const template = pathSegments(op.path);
249485
+ return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
249486
+ });
249487
+ return candidates.sort((a, b) => literalSegments(b.path).localeCompare(literalSegments(a.path)))[0];
249394
249488
  }
249395
249489
  // src/core/api-spec/request.ts
249490
+ var MAX_ERROR_BODY_CHARS = 4000;
249491
+ async function readBody(response) {
249492
+ try {
249493
+ const text = (await response.clone().text()).trim();
249494
+ return text.length > MAX_ERROR_BODY_CHARS ? `${text.slice(0, MAX_ERROR_BODY_CHARS)}…` : text || undefined;
249495
+ } catch {
249496
+ return;
249497
+ }
249498
+ }
249396
249499
  async function sendApiRequest(method, path, body) {
249397
249500
  try {
249398
249501
  const response = await base44Client(path.replace(/^\/+/, ""), {
249399
249502
  method,
249400
249503
  body,
249401
- headers: body === undefined ? {} : { "Content-Type": "application/json" }
249504
+ headers: body === undefined ? {} : { "Content-Type": "application/json" },
249505
+ timeout: false
249402
249506
  });
249403
249507
  return {
249404
249508
  status: response.status,
@@ -249406,11 +249510,21 @@ async function sendApiRequest(method, path, body) {
249406
249510
  body: new Uint8Array(await response.arrayBuffer())
249407
249511
  };
249408
249512
  } catch (error) {
249409
- throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249513
+ const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249514
+ const raw = error instanceof HTTPError ? await readBody(error.response) : undefined;
249515
+ const message = raw && apiError.statusCode !== undefined ? `Error calling ${method} ${path}: HTTP ${apiError.statusCode}` : apiError.message;
249516
+ throw new ApiError(message, {
249517
+ statusCode: apiError.statusCode,
249518
+ requestUrl: apiError.requestUrl,
249519
+ requestMethod: apiError.requestMethod,
249520
+ requestId: apiError.requestId,
249521
+ hints: apiError.hints,
249522
+ details: raw ? [`Response body: ${raw}`] : apiError.details
249523
+ });
249410
249524
  }
249411
249525
  }
249412
249526
  // src/core/api-spec/spec.ts
249413
- import { stat as stat3 } from "node:fs/promises";
249527
+ import { rename, stat as stat3 } from "node:fs/promises";
249414
249528
  import { join as join22 } from "node:path";
249415
249529
  var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
249416
249530
  function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
@@ -249433,17 +249547,24 @@ function parseSpec(text) {
249433
249547
  }
249434
249548
  return result.data;
249435
249549
  }
249550
+ var SPEC_DOWNLOAD_TIMEOUT_MS = 60000;
249436
249551
  async function readFreshCache(path) {
249437
249552
  try {
249438
249553
  const { mtimeMs } = await stat3(path);
249439
- return isSpecCacheFresh(mtimeMs) ? await readTextFile(path) : null;
249554
+ if (!isSpecCacheFresh(mtimeMs)) {
249555
+ return null;
249556
+ }
249557
+ const text = await readTextFile(path);
249558
+ return { text, spec: parseSpec(text) };
249440
249559
  } catch {
249441
249560
  return null;
249442
249561
  }
249443
249562
  }
249444
249563
  async function downloadSpec() {
249445
249564
  try {
249446
- const response = await base44Client.get("api/openapi.json");
249565
+ const response = await base44Client.get("api/openapi.json", {
249566
+ timeout: SPEC_DOWNLOAD_TIMEOUT_MS
249567
+ });
249447
249568
  return await response.text();
249448
249569
  } catch (error) {
249449
249570
  throw await ApiError.fromHttpError(error, "fetching the API spec");
@@ -249453,17 +249574,19 @@ async function loadSpec(options = {}) {
249453
249574
  const path = getSpecCachePath();
249454
249575
  const cached = options.refresh ? null : await readFreshCache(path);
249455
249576
  if (cached !== null) {
249456
- return { text: cached, spec: parseSpec(cached) };
249577
+ return cached;
249457
249578
  }
249458
249579
  const text = await downloadSpec();
249459
249580
  const spec = parseSpec(text);
249460
- await writeFile(path, text);
249581
+ const partial = `${path}.${process.pid}.tmp`;
249582
+ await writeFile(partial, text);
249583
+ await rename(partial, path);
249461
249584
  return { text, spec };
249462
249585
  }
249463
249586
  // src/cli/commands/api/shared.ts
249587
+ import { fstatSync } from "node:fs";
249464
249588
  function formatJson(value) {
249465
- return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
249466
- `;
249589
+ return toJsonStdout(value, { compact: !process.stdout.isTTY });
249467
249590
  }
249468
249591
  function parseLimit(value) {
249469
249592
  if (value === undefined) {
@@ -249493,38 +249616,37 @@ function operationsInArea(operations, area) {
249493
249616
  }
249494
249617
  return inArea;
249495
249618
  }
249496
- async function readRequestBody(method, flag) {
249619
+ function isPipedStdin() {
249620
+ try {
249621
+ const stats = fstatSync(0);
249622
+ return stats.isFIFO() || stats.isFile();
249623
+ } catch {
249624
+ return false;
249625
+ }
249626
+ }
249627
+ async function readRequestBody(flag, log) {
249497
249628
  if (flag === "@-") {
249498
249629
  return readStdin("--body @-", { trim: false });
249499
249630
  }
249500
249631
  if (flag?.startsWith("@")) {
249501
249632
  return readTextFile(flag.slice(1));
249502
249633
  }
249503
- if (flag !== undefined) {
249504
- return flag;
249634
+ if (flag === undefined && isPipedStdin()) {
249635
+ log.warn("stdin is ignored; pass --body @- to send it as the body.");
249505
249636
  }
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;
249637
+ return flag;
249511
249638
  }
249512
249639
 
249513
249640
  // src/cli/commands/api/catalog.ts
249514
249641
  async function catalogAction(ctx, area, options) {
249515
249642
  const { spec } = await loadSpecTask(ctx, options.refresh);
249516
- const operations = listOperations(spec).filter((op) => !options.readOnly || op.readOnly);
249643
+ const operations = listOperations(spec);
249644
+ const readOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
249517
249645
  if (area === undefined) {
249518
- return { stdout: formatJson(catalogIndex(operations)) };
249646
+ return { stdout: formatJson(catalogIndex(readOnly(operations))) };
249519
249647
  }
249520
- const inArea = operationsInArea(operations, area);
249521
- return {
249522
- stdout: formatJson({
249523
- area,
249524
- operations: inArea.map(toOperationSummary),
249525
- total: inArea.length
249526
- })
249527
- };
249648
+ const inArea = readOnly(operationsInArea(operations, area));
249649
+ return { stdout: formatJson(areaListing(area, inArea)) };
249528
249650
  }
249529
249651
  function getApiCatalogCommand() {
249530
249652
  return new Base44Command("catalog", {
@@ -249534,12 +249656,16 @@ function getApiCatalogCommand() {
249534
249656
  }
249535
249657
 
249536
249658
  // src/cli/commands/api/fetch.ts
249537
- async function findOperation(ctx, method, path, refresh) {
249659
+ async function findOperation(ctx, method, path, { refresh, flag }) {
249538
249660
  const { spec } = await loadSpecTask(ctx, refresh);
249539
249661
  const op = matchOperation(listOperations(spec), method, path);
249540
249662
  if (!op) {
249541
249663
  throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
249542
249664
  hints: [
249665
+ {
249666
+ message: "The cached spec may predate this route; fetch it again",
249667
+ command: `base44 api fetch ${method} ${path} ${flag} --refresh`
249668
+ },
249543
249669
  {
249544
249670
  message: "Find the operation and its path template",
249545
249671
  command: 'base44 api search "<what you want to do>"'
@@ -249559,7 +249685,7 @@ var TEXT_CONTENT_TYPES = [
249559
249685
  function isText(contentType) {
249560
249686
  return !contentType || TEXT_CONTENT_TYPES.some((hint) => contentType.toLowerCase().includes(hint));
249561
249687
  }
249562
- async function formatResponse({ status, contentType, body }, output) {
249688
+ async function formatResponse({ status, contentType, body }, output, jsonMode) {
249563
249689
  if (output !== undefined) {
249564
249690
  await writeFile(output, body);
249565
249691
  return formatJson({ status, contentType, bytes: body.length, output });
@@ -249568,12 +249694,20 @@ async function formatResponse({ status, contentType, body }, output) {
249568
249694
  return formatJson({ status });
249569
249695
  }
249570
249696
  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.`);
249697
+ return formatJson({
249698
+ status,
249699
+ contentType,
249700
+ bytes: body.length,
249701
+ note: "Binary body not printed; add --output <file> to save it."
249702
+ });
249572
249703
  }
249573
249704
  const text = new TextDecoder().decode(body);
249574
249705
  try {
249575
249706
  return formatJson(JSON.parse(text));
249576
249707
  } catch {
249708
+ if (jsonMode) {
249709
+ return formatJson({ status, contentType, body: text });
249710
+ }
249577
249711
  return text.endsWith(`
249578
249712
  `) ? text : `${text}
249579
249713
  `;
@@ -249582,34 +249716,50 @@ async function formatResponse({ status, contentType, body }, output) {
249582
249716
  async function fetchAction(ctx, methodArg, path, options, command) {
249583
249717
  if (!methodArg || !path) {
249584
249718
  if (options.help) {
249585
- return { stdout: command.helpInformation() };
249719
+ const usage = command.helpInformation();
249720
+ return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
249586
249721
  }
249587
249722
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249588
249723
  }
249589
249724
  const method = methodArg.toUpperCase();
249590
249725
  if (options.help) {
249591
- const { spec, op } = await findOperation(ctx, method, path, options.refresh);
249726
+ const { spec, op } = await findOperation(ctx, method, path, {
249727
+ refresh: options.refresh,
249728
+ flag: "--help"
249729
+ });
249592
249730
  return { stdout: formatJson(getOperationContract(spec, op)) };
249593
249731
  }
249594
249732
  if (options.readOnly) {
249595
- const { op } = await findOperation(ctx, method, path, options.refresh);
249733
+ const { op } = await findOperation(ctx, method, path, {
249734
+ refresh: options.refresh,
249735
+ flag: "--read-only"
249736
+ });
249596
249737
  if (!op.readOnly) {
249597
249738
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249598
249739
  }
249599
249740
  }
249741
+ ctx.errorReporter.setContext({
249742
+ command: {
249743
+ name: "api fetch",
249744
+ args: [method, path.split("?", 1)[0] ?? ""],
249745
+ options: { ...options, body: options.body && "[not reported]" }
249746
+ }
249747
+ });
249600
249748
  await ensureAuth(ctx);
249601
- const body = await readRequestBody(method, options.body);
249749
+ const body = await readRequestBody(options.body, ctx.log);
249602
249750
  const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
249603
249751
  successMessage: `Called ${method} ${path}`,
249604
249752
  errorMessage: "Request failed"
249605
249753
  });
249606
- return { stdout: await formatResponse(response, options.output) };
249754
+ return {
249755
+ stdout: await formatResponse(response, options.output, ctx.jsonMode)
249756
+ };
249607
249757
  }
249608
249758
  function getApiFetchCommand() {
249609
249759
  return new Base44Command("fetch", {
249610
249760
  requireAuth: false,
249611
249761
  requireAppContext: false
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);
249762
+ }).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").action(fetchAction);
249613
249763
  }
249614
249764
 
249615
249765
  // src/cli/commands/api/grep.ts
@@ -249624,15 +249774,16 @@ async function grepAction(ctx, pattern, options) {
249624
249774
  const limit = parseLimit(options.limit);
249625
249775
  assertValidRegex(pattern);
249626
249776
  const { spec } = await loadSpecTask(ctx, options.refresh);
249627
- const operations = listOperations(spec);
249777
+ let operations = listOperations(spec);
249628
249778
  if (options.area !== undefined) {
249629
- operationsInArea(operations, options.area);
249779
+ operations = operationsInArea(operations, options.area);
249780
+ }
249781
+ if (options.readOnly) {
249782
+ operations = operations.filter((op) => op.readOnly);
249630
249783
  }
249631
- const hits = grepSpec(spec, operations, pattern, {
249632
- area: options.area,
249784
+ const hits = grepOperations(spec, operations, pattern, {
249633
249785
  ignoreCase: options.ignoreCase,
249634
- limit,
249635
- readOnly: options.readOnly
249786
+ limit
249636
249787
  });
249637
249788
  return { stdout: formatJson(hits) };
249638
249789
  }
@@ -249640,7 +249791,7 @@ function getApiGrepCommand() {
249640
249791
  return new Base44Command("grep", {
249641
249792
  requireAuth: false,
249642
249793
  requireAppContext: false
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);
249794
+ }).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);
249644
249795
  }
249645
249796
 
249646
249797
  // src/cli/commands/api/search.ts
@@ -262200,7 +262351,7 @@ var nativeEnumType = ZodNativeEnum.create;
262200
262351
  var promiseType = ZodPromise.create;
262201
262352
  var effectsType = ZodEffects.create;
262202
262353
  var optionalType = ZodOptional2.create;
262203
- var nullableType = ZodNullable2.create;
262354
+ var nullableType2 = ZodNullable2.create;
262204
262355
  var preprocessType = ZodEffects.createWithPreprocess;
262205
262356
  var pipelineType = ZodPipeline.create;
262206
262357
  // ../functions-compiler/src/contracts.ts
@@ -273202,4 +273353,4 @@ export {
273202
273353
  runCLI
273203
273354
  };
273204
273355
 
273205
- //# debugId=C89C416C808E439E64756E2164756E21
273356
+ //# debugId=ED51B8A8CDD1B22D64756E2164756E21