@base44-preview/cli 0.1.32-pr.663.57b7b28 → 0.1.32-pr.663.60cadbf

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
@@ -248042,28 +248042,6 @@ function getAgentsCommand() {
248042
248042
  return new Command2("agents").description("Manage project agents").addCommand(getAgentsPushCommand()).addCommand(getAgentsPullCommand());
248043
248043
  }
248044
248044
 
248045
- // src/core/api-spec/body.ts
248046
- var METHODS_WITHOUT_BODY = new Set(["GET", "HEAD"]);
248047
- async function resolveRequestBody(method, flag, source) {
248048
- const takesBody = !METHODS_WITHOUT_BODY.has(method.toUpperCase());
248049
- if (flag !== undefined && !takesBody) {
248050
- throw new InvalidInputError(`${method.toUpperCase()} requests cannot have a body.`);
248051
- }
248052
- if (flag === "@-") {
248053
- return source.readStdin();
248054
- }
248055
- if (flag?.startsWith("@")) {
248056
- return readTextFile(flag.slice(1));
248057
- }
248058
- if (flag !== undefined) {
248059
- return flag;
248060
- }
248061
- if (!takesBody || source.stdinIsTTY) {
248062
- return;
248063
- }
248064
- const piped = await source.readStdin();
248065
- return piped.trim() ? piped : undefined;
248066
- }
248067
248045
  // ../../node_modules/minisearch/dist/es/index.js
248068
248046
  var ENTRIES = "ENTRIES";
248069
248047
  var KEYS = "KEYS";
@@ -249124,24 +249102,30 @@ var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
249124
249102
  var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
249125
249103
 
249126
249104
  // src/core/api-spec/search.ts
249127
- 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
+ };
249128
249112
  var MIN_RELATIVE_SCORE = 0.2;
249129
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
+ }
249130
249118
  function toOperationSummary(op) {
249131
- return {
249132
- method: op.method,
249133
- path: op.path,
249134
- summary: op.summary,
249135
- readOnly: op.readOnly
249136
- };
249119
+ return { endpoint: op.endpoint, summary: op.summary };
249137
249120
  }
249138
249121
  function buildSearchIndex(operations) {
249139
249122
  const index = new MiniSearch({
249140
- fields: ["path", "summary", "description", "parameters"],
249141
- tokenize: (text) => text.split(TOKEN_SEPARATOR).filter(Boolean)
249123
+ fields: ["method", "path", "summary", "description", "parameters"],
249124
+ tokenize
249142
249125
  });
249143
249126
  index.addAll(operations.map((op, id) => ({
249144
249127
  id,
249128
+ method: op.method,
249145
249129
  path: op.path.replace(/\{[^}]*\}/g, ""),
249146
249130
  summary: op.summary,
249147
249131
  description: op.description,
@@ -249149,53 +249133,86 @@ function buildSearchIndex(operations) {
249149
249133
  })));
249150
249134
  return index;
249151
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;
249152
249145
  function searchOperations(operations, query, options = {}) {
249146
+ const terms = tokenize(query.toLowerCase());
249147
+ if (terms.length === 0) {
249148
+ return [];
249149
+ }
249153
249150
  const index = buildSearchIndex(operations);
249154
249151
  const hits = index.search(query, {
249155
- prefix: true,
249156
- fuzzy: 0.2,
249152
+ prefix: (term) => term.length >= 3,
249153
+ fuzzy: (term) => term.length >= 4 ? 0.2 : false,
249157
249154
  boost: BOOST,
249158
249155
  filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
249159
- });
249160
- const baseline = (hits[0]?.score ?? 0) * MIN_RELATIVE_SCORE;
249161
- 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) => {
249162
249167
  const op = operations[hit.id];
249163
249168
  return op ? [toOperationSummary(op)] : [];
249164
249169
  });
249165
249170
  }
249166
249171
 
249167
- // src/core/api-spec/grep.ts
249168
- var CONTEXT_CHARS = 40;
249169
- var MAX_SNIPPETS = 3;
249170
- var MAX_SNIPPET_CHARS = 200;
249171
- function snippets(text, pattern) {
249172
- const found = [];
249173
- for (const match of text.matchAll(pattern)) {
249174
- const start = Math.max(0, match.index - CONTEXT_CHARS);
249175
- const end = match.index + match[0].length + CONTEXT_CHARS;
249176
- found.push(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS)));
249177
- if (found.length === MAX_SNIPPETS || match[0].length === 0) {
249178
- break;
249179
- }
249172
+ // src/core/api-spec/catalog.ts
249173
+ var INLINE_AREA_MAX = 2;
249174
+ var AREA_SAMPLE_MAX = 3;
249175
+ var AREA_OPERATIONS_MAX = 200;
249176
+ var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
249177
+ function areaOf(path) {
249178
+ const parts = path.split("/").filter(Boolean);
249179
+ const appIdIndex = parts.indexOf("{app_id}");
249180
+ if (appIdIndex !== -1 && appIdIndex + 1 < parts.length) {
249181
+ return parts[appIdIndex + 1] ?? "other";
249180
249182
  }
249181
- return found;
249182
- }
249183
- function grepSpec(spec, operations, pattern, options = {}) {
249184
- const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249185
- const hits = [];
249186
- for (const op of operations) {
249187
- const matches = snippets(`${op.method} ${op.path} ${JSON.stringify(op.operation)}`, regex);
249188
- if (matches.length > 0) {
249189
- hits.push({ ...toOperationSummary(op), matches });
249190
- }
249183
+ if (parts[0] === "api" && parts.length > 1) {
249184
+ return parts[1] ?? "other";
249191
249185
  }
249192
- for (const [schema, definition] of Object.entries(spec.components?.schemas ?? {})) {
249193
- const matches = snippets(JSON.stringify(definition), regex);
249194
- if (matches.length > 0) {
249195
- hits.push({ schema, matches });
249196
- }
249186
+ return parts[0] ?? "other";
249187
+ }
249188
+ function groupByArea(operations) {
249189
+ const sorted = [...operations].sort((a, b) => byCodePoint(`${a.method} ${a.path}`, `${b.method} ${b.path}`));
249190
+ const areas = new Map;
249191
+ for (const op of sorted) {
249192
+ const area = areaOf(op.path);
249193
+ areas.set(area, [...areas.get(area) ?? [], op]);
249197
249194
  }
249198
- return hits.slice(0, options.limit ?? 20);
249195
+ return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
249196
+ }
249197
+ function readsFirst2(ops) {
249198
+ const isRead = (op) => op.method === "GET" ? 0 : 1;
249199
+ return [...ops].sort((a, b) => isRead(a) - isRead(b));
249200
+ }
249201
+ function catalogIndex(operations) {
249202
+ const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
249203
+ area,
249204
+ operationCount: ops.length,
249205
+ sample: readsFirst2(ops).slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
249206
+ });
249207
+ return { areas, total: operations.length };
249208
+ }
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
+ };
249199
249216
  }
249200
249217
  // src/core/api-spec/schema.ts
249201
249218
  var HTTP_METHODS = [
@@ -249213,7 +249230,16 @@ var ParameterSchema = looseObject({
249213
249230
  in: string2(),
249214
249231
  required: boolean2().optional(),
249215
249232
  description: string2().optional(),
249216
- schema: unknown().optional()
249233
+ schema: unknown().optional(),
249234
+ example: unknown().optional()
249235
+ });
249236
+ var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
249237
+ var RequestBodySchema = looseObject({
249238
+ content: MediaTypesSchema.optional()
249239
+ });
249240
+ var ResponseObjectSchema = looseObject({
249241
+ description: string2().optional(),
249242
+ content: MediaTypesSchema.optional()
249217
249243
  });
249218
249244
  var SecurityRequirementSchema = record(string2(), array(string2()));
249219
249245
  var OperationSchema = looseObject({
@@ -249225,7 +249251,10 @@ var OperationSchema = looseObject({
249225
249251
  responses: record(string2(), unknown()).optional(),
249226
249252
  security: array(SecurityRequirementSchema).optional()
249227
249253
  });
249228
- 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
+ });
249229
249258
  var OpenApiSpecSchema = looseObject({
249230
249259
  openapi: string2(),
249231
249260
  paths: record(string2(), PathItemSchema),
@@ -249248,14 +249277,33 @@ function parameterText(operation) {
249248
249277
  return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249249
249278
  }).join(" ");
249250
249279
  }
249280
+ function mergeParameters(shared, own) {
249281
+ if (!shared?.length) {
249282
+ return own;
249283
+ }
249284
+ const key = (parameter) => {
249285
+ const parsed = ParameterSchema.safeParse(parameter);
249286
+ return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249287
+ };
249288
+ const ownKeys = new Set((own ?? []).map(key));
249289
+ return [
249290
+ ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249291
+ ...own ?? []
249292
+ ];
249293
+ }
249251
249294
  function listOperations(spec) {
249252
249295
  return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249253
- const operation = item[method];
249254
- if (!operation) {
249296
+ const declared = item[method];
249297
+ if (!declared) {
249255
249298
  return [];
249256
249299
  }
249300
+ const operation = {
249301
+ ...declared,
249302
+ parameters: mergeParameters(item.parameters, declared.parameters)
249303
+ };
249257
249304
  return [
249258
249305
  {
249306
+ endpoint: `${method.toUpperCase()} ${path}`,
249259
249307
  method: method.toUpperCase(),
249260
249308
  path,
249261
249309
  summary: operation.summary ?? "",
@@ -249298,63 +249346,197 @@ function matchOperation(operations, method, concretePath) {
249298
249346
  });
249299
249347
  return candidates.sort((a, b) => compareSpecificity(specificity(pathSegments(a.path)), specificity(pathSegments(b.path))))[0];
249300
249348
  }
249301
- function collectRefs(value, spec, found) {
249302
- if (Array.isArray(value)) {
249303
- for (const item of value) {
249304
- collectRefs(item, spec, found);
249349
+ var SCHEMA_REF_PREFIX = "#/components/schemas/";
249350
+ var MAX_REF_DEPTH = 4;
249351
+ var FRAMEWORK_VALIDATION_ERROR = "Validation Error";
249352
+ function inlineRefs(node, schemas, seen = new Set, depth = 0) {
249353
+ if (depth > MAX_REF_DEPTH) {
249354
+ return node;
249355
+ }
249356
+ if (Array.isArray(node)) {
249357
+ return node.map((item) => inlineRefs(item, schemas, seen, depth));
249358
+ }
249359
+ if (node === null || typeof node !== "object") {
249360
+ return node;
249361
+ }
249362
+ const { $ref, ...siblings } = node;
249363
+ if (typeof $ref === "string" && $ref.startsWith(SCHEMA_REF_PREFIX)) {
249364
+ const name = $ref.slice(SCHEMA_REF_PREFIX.length);
249365
+ if (seen.has(name) || !(name in schemas)) {
249366
+ return node;
249305
249367
  }
249306
- return;
249368
+ const resolved = inlineRefs(schemas[name], schemas, new Set([...seen, name]), depth + 1);
249369
+ return resolved !== null && typeof resolved === "object" ? { ...resolved, ...siblings } : resolved;
249307
249370
  }
249308
- if (value === null || typeof value !== "object") {
249309
- return;
249371
+ return Object.fromEntries(Object.entries(node).map(([key, value]) => [
249372
+ key,
249373
+ inlineRefs(value, schemas, seen, depth)
249374
+ ]));
249375
+ }
249376
+ function jsonSchemaOf(value) {
249377
+ const parsed = RequestBodySchema.safeParse(value);
249378
+ return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
249379
+ }
249380
+ function requestBodyOf(value) {
249381
+ const parsed = RequestBodySchema.safeParse(value);
249382
+ const content = parsed.success ? parsed.data.content ?? {} : {};
249383
+ const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
249384
+ return contentType ? { contentType, schema: content[contentType]?.schema } : {};
249385
+ }
249386
+ function leftoverRefs(node, schemas, found = new Map) {
249387
+ if (Array.isArray(node)) {
249388
+ for (const item of node) {
249389
+ leftoverRefs(item, schemas, found);
249390
+ }
249391
+ } else if (node !== null && typeof node === "object") {
249392
+ for (const [key, value] of Object.entries(node)) {
249393
+ if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
249394
+ const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
249395
+ found.set(value, schema);
249396
+ leftoverRefs(schema, schemas, found);
249397
+ } else {
249398
+ leftoverRefs(value, schemas, found);
249399
+ }
249400
+ }
249310
249401
  }
249311
- for (const [key, child] of Object.entries(value)) {
249312
- if (key === "$ref" && typeof child === "string" && !found.has(child)) {
249313
- const target = resolvePointer(spec, child);
249314
- found.set(child, target);
249315
- collectRefs(target, spec, found);
249316
- } else {
249317
- collectRefs(child, spec, found);
249402
+ return found;
249403
+ }
249404
+ var SCHEMA_DATA_KEYS = new Set([
249405
+ "example",
249406
+ "examples",
249407
+ "default",
249408
+ "enum",
249409
+ "const"
249410
+ ]);
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
+ function slimSchema(node, isPropertyMap = false) {
249417
+ if (Array.isArray(node)) {
249418
+ return node.map((item) => slimSchema(item));
249419
+ }
249420
+ if (node === null || typeof node !== "object") {
249421
+ return node;
249422
+ }
249423
+ const entries = Object.entries(node);
249424
+ if (isPropertyMap) {
249425
+ return Object.fromEntries(entries.map(([name, value]) => [name, slimSchema(value)]));
249426
+ }
249427
+ const slim = {};
249428
+ for (const [key, value] of entries) {
249429
+ if (key === "title" && typeof value === "string") {
249430
+ continue;
249318
249431
  }
249432
+ slim[key] = SCHEMA_DATA_KEYS.has(key) ? value : key === "properties" ? slimSchema(value, true) : key === "description" && typeof value === "string" ? cleanText(value) : slimSchema(value);
249319
249433
  }
249434
+ const { anyOf, ...rest } = slim;
249435
+ const nullable = Array.isArray(anyOf) && anyOf.length === 2 ? nullableType(anyOf) : undefined;
249436
+ return nullable ? { type: [nullable, "null"], ...rest } : slim;
249320
249437
  }
249321
- function resolvePointer(spec, ref) {
249322
- if (!ref.startsWith("#/")) {
249438
+ function nullableType(variants) {
249439
+ const types = variants.map((variant) => variant !== null && typeof variant === "object" && Object.keys(variant).length === 1 && typeof variant.type === "string" ? variant.type : undefined);
249440
+ if (types.includes(undefined) || !types.includes("null")) {
249323
249441
  return;
249324
249442
  }
249325
- return ref.slice(2).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~")).reduce((node, part) => node !== null && typeof node === "object" ? node[part] : undefined, spec);
249443
+ return types.find((type) => type !== "null");
249326
249444
  }
249327
249445
  function getOperationContract(spec, op) {
249328
- const { parameters, requestBody, responses } = op.operation;
249329
- const refs = new Map;
249330
- collectRefs({ parameters, requestBody, responses }, spec, refs);
249331
- return {
249446
+ const schemas = spec.components?.schemas ?? {};
249447
+ const inline = (node) => node === undefined ? null : slimSchema(inlineRefs(node, schemas));
249448
+ const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
249449
+ const parsed = ResponseObjectSchema.safeParse(response);
249450
+ return parsed.success ? [[status, parsed.data]] : [];
249451
+ });
249452
+ const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
249453
+ const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
249454
+ const requestBody = requestBodyOf(op.operation.requestBody);
249455
+ const contract = {
249456
+ endpoint: op.endpoint,
249332
249457
  method: op.method,
249333
249458
  path: op.path,
249334
249459
  summary: op.summary,
249335
- description: op.description,
249336
- readOnly: op.readOnly,
249337
- parameters: parameters ?? [],
249338
- requestBody: requestBody ?? null,
249339
- responses: responses ?? {},
249340
- refs: Object.fromEntries(refs)
249460
+ description: cleanText(op.description),
249461
+ parameters: (op.operation.parameters ?? []).flatMap((parameter) => {
249462
+ const parsed = ParameterSchema.safeParse(parameter);
249463
+ if (!parsed.success) {
249464
+ return [];
249465
+ }
249466
+ const { name, in: location2, required, schema, description } = parsed.data;
249467
+ const inSchema = schema !== null && typeof schema === "object" && "description" in schema;
249468
+ return [
249469
+ {
249470
+ name,
249471
+ in: location2,
249472
+ required: required ?? false,
249473
+ schema: inline(schema ?? {}),
249474
+ ...description && !inSchema ? { description: cleanText(description) } : {},
249475
+ ..."example" in parsed.data ? { example: parsed.data.example } : {}
249476
+ }
249477
+ ];
249478
+ }),
249479
+ ...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
249480
+ requestBodySchema: inline(requestBody.schema),
249481
+ responseSchema: inline(success),
249482
+ errors: Object.fromEntries(errors.map(([status, response]) => [
249483
+ status,
249484
+ cleanText(response.description ?? "")
249485
+ ]))
249486
+ };
249487
+ const refs = leftoverRefs(contract, schemas);
249488
+ return {
249489
+ ...contract,
249490
+ ...refs.size > 0 ? {
249491
+ refs: Object.fromEntries([...refs].map(([ref, schema]) => [ref, slimSchema(schema)]))
249492
+ } : {}
249341
249493
  };
249342
249494
  }
249495
+
249496
+ // src/core/api-spec/grep.ts
249497
+ function grepOperations(spec, operations, pattern, options = {}) {
249498
+ const regex = new RegExp(pattern, options.ignoreCase ? "i" : "");
249499
+ return operations.filter((op) => regex.test(JSON.stringify(getOperationContract(spec, op)))).slice(0, options.limit ?? 20).map(toOperationSummary);
249500
+ }
249343
249501
  // src/core/api-spec/request.ts
249502
+ var MAX_ERROR_BODY_CHARS = 4000;
249503
+ async function readBody(response) {
249504
+ try {
249505
+ const text = (await response.clone().text()).trim();
249506
+ return text.length > MAX_ERROR_BODY_CHARS ? `${text.slice(0, MAX_ERROR_BODY_CHARS)}…` : text || undefined;
249507
+ } catch {
249508
+ return;
249509
+ }
249510
+ }
249344
249511
  async function sendApiRequest(method, path, body) {
249345
249512
  try {
249346
249513
  const response = await base44Client(path.replace(/^\/+/, ""), {
249347
249514
  method,
249348
249515
  body,
249349
- headers: body === undefined ? {} : { "Content-Type": "application/json" }
249516
+ headers: body === undefined ? {} : { "Content-Type": "application/json" },
249517
+ timeout: false
249350
249518
  });
249351
- return await response.text();
249519
+ return {
249520
+ status: response.status,
249521
+ contentType: response.headers.get("content-type") ?? "",
249522
+ body: new Uint8Array(await response.arrayBuffer())
249523
+ };
249352
249524
  } catch (error) {
249353
- throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249525
+ const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249526
+ const raw = error instanceof HTTPError ? await readBody(error.response) : undefined;
249527
+ const message = raw && apiError.statusCode !== undefined ? `Error calling ${method} ${path}: HTTP ${apiError.statusCode}` : apiError.message;
249528
+ throw new ApiError(message, {
249529
+ statusCode: apiError.statusCode,
249530
+ requestUrl: apiError.requestUrl,
249531
+ requestMethod: apiError.requestMethod,
249532
+ requestId: apiError.requestId,
249533
+ hints: apiError.hints,
249534
+ details: raw ? [`Response body: ${raw}`] : apiError.details
249535
+ });
249354
249536
  }
249355
249537
  }
249356
249538
  // src/core/api-spec/spec.ts
249357
- import { stat as stat3 } from "node:fs/promises";
249539
+ import { rename, stat as stat3 } from "node:fs/promises";
249358
249540
  import { join as join22 } from "node:path";
249359
249541
  var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
249360
249542
  function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
@@ -249377,17 +249559,24 @@ function parseSpec(text) {
249377
249559
  }
249378
249560
  return result.data;
249379
249561
  }
249562
+ var SPEC_DOWNLOAD_TIMEOUT_MS = 60000;
249380
249563
  async function readFreshCache(path) {
249381
249564
  try {
249382
249565
  const { mtimeMs } = await stat3(path);
249383
- return isSpecCacheFresh(mtimeMs) ? await readTextFile(path) : null;
249566
+ if (!isSpecCacheFresh(mtimeMs)) {
249567
+ return null;
249568
+ }
249569
+ const text = await readTextFile(path);
249570
+ return { text, spec: parseSpec(text) };
249384
249571
  } catch {
249385
249572
  return null;
249386
249573
  }
249387
249574
  }
249388
249575
  async function downloadSpec() {
249389
249576
  try {
249390
- const response = await base44Client.get("api/openapi.json");
249577
+ const response = await base44Client.get("api/openapi.json", {
249578
+ timeout: SPEC_DOWNLOAD_TIMEOUT_MS
249579
+ });
249391
249580
  return await response.text();
249392
249581
  } catch (error) {
249393
249582
  throw await ApiError.fromHttpError(error, "fetching the API spec");
@@ -249397,29 +249586,19 @@ async function loadSpec(options = {}) {
249397
249586
  const path = getSpecCachePath();
249398
249587
  const cached = options.refresh ? null : await readFreshCache(path);
249399
249588
  if (cached !== null) {
249400
- return { text: cached, spec: parseSpec(cached) };
249589
+ return cached;
249401
249590
  }
249402
249591
  const text = await downloadSpec();
249403
249592
  const spec = parseSpec(text);
249404
- await writeFile(path, text);
249593
+ const partial = `${path}.${process.pid}.tmp`;
249594
+ await writeFile(partial, text);
249595
+ await rename(partial, path);
249405
249596
  return { text, spec };
249406
249597
  }
249407
249598
  // src/cli/commands/api/shared.ts
249599
+ import { fstatSync } from "node:fs";
249408
249600
  function formatJson(value) {
249409
- return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
249410
- `;
249411
- }
249412
- function formatResponseBody(text) {
249413
- if (!text) {
249414
- return "";
249415
- }
249416
- try {
249417
- return formatJson(JSON.parse(text));
249418
- } catch {
249419
- return text.endsWith(`
249420
- `) ? text : `${text}
249421
- `;
249422
- }
249601
+ return toJsonStdout(value, { compact: !process.stdout.isTTY });
249423
249602
  }
249424
249603
  function parseLimit(value) {
249425
249604
  if (value === undefined) {
@@ -249431,20 +249610,74 @@ function parseLimit(value) {
249431
249610
  }
249432
249611
  return n;
249433
249612
  }
249613
+ var READ_ONLY_FILTER_HELP = "Only read-only operations";
249434
249614
  var REFRESH_OPTION_HELP = "Fetch the API spec again instead of using the cached copy (kept 1 hour)";
249435
249615
  function loadSpecTask({ runTask }, refresh) {
249436
249616
  return runTask("Loading the API spec", () => loadSpec({ refresh }), {
249437
249617
  successMessage: "Loaded the API spec"
249438
249618
  });
249439
249619
  }
249620
+ function operationsInArea(operations, area) {
249621
+ const areas = groupByArea(operations);
249622
+ const inArea = areas.get(area);
249623
+ if (!inArea) {
249624
+ throw new InvalidInputError(`Unknown API area: ${area}`, {
249625
+ details: [`Areas: ${[...areas.keys()].join(", ")}`],
249626
+ hints: [{ message: "List the areas", command: "base44 api catalog" }]
249627
+ });
249628
+ }
249629
+ return inArea;
249630
+ }
249631
+ function isPipedStdin() {
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) {
249640
+ if (flag === "@-") {
249641
+ return readStdin("--body @-", { trim: false });
249642
+ }
249643
+ if (flag?.startsWith("@")) {
249644
+ return readTextFile(flag.slice(1));
249645
+ }
249646
+ if (flag === undefined && isPipedStdin()) {
249647
+ log.warn("stdin is ignored; pass --body @- to send it as the body.");
249648
+ }
249649
+ return flag;
249650
+ }
249651
+
249652
+ // src/cli/commands/api/catalog.ts
249653
+ async function catalogAction(ctx, area, options) {
249654
+ const { spec } = await loadSpecTask(ctx, options.refresh);
249655
+ const operations = listOperations(spec);
249656
+ const readOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
249657
+ if (area === undefined) {
249658
+ return { stdout: formatJson(catalogIndex(readOnly(operations))) };
249659
+ }
249660
+ const inArea = readOnly(operationsInArea(operations, area));
249661
+ return { stdout: formatJson(areaListing(area, inArea)) };
249662
+ }
249663
+ function getApiCatalogCommand() {
249664
+ return new Base44Command("catalog", {
249665
+ requireAuth: false,
249666
+ requireAppContext: false
249667
+ }).description("List the API's areas, or every operation in one area").argument("[area]", 'An area from the list, e.g. "workflows"').option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(catalogAction);
249668
+ }
249440
249669
 
249441
249670
  // src/cli/commands/api/fetch.ts
249442
- async function findOperation(ctx, method, path, refresh) {
249671
+ async function findOperation(ctx, method, path, { refresh, flag }) {
249443
249672
  const { spec } = await loadSpecTask(ctx, refresh);
249444
249673
  const op = matchOperation(listOperations(spec), method, path);
249445
249674
  if (!op) {
249446
249675
  throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
249447
249676
  hints: [
249677
+ {
249678
+ message: "The cached spec may predate this route; fetch it again",
249679
+ command: `base44 api fetch ${method} ${path} ${flag} --refresh`
249680
+ },
249448
249681
  {
249449
249682
  message: "Find the operation and its path template",
249450
249683
  command: 'base44 api search "<what you want to do>"'
@@ -249454,43 +249687,91 @@ async function findOperation(ctx, method, path, refresh) {
249454
249687
  }
249455
249688
  return { spec, op };
249456
249689
  }
249690
+ var TEXT_CONTENT_TYPES = [
249691
+ "json",
249692
+ "text/",
249693
+ "xml",
249694
+ "javascript",
249695
+ "x-www-form-urlencoded"
249696
+ ];
249697
+ function isText(contentType) {
249698
+ return !contentType || TEXT_CONTENT_TYPES.some((hint) => contentType.toLowerCase().includes(hint));
249699
+ }
249700
+ async function formatResponse({ status, contentType, body }, output, jsonMode) {
249701
+ if (output !== undefined) {
249702
+ await writeFile(output, body);
249703
+ return formatJson({ status, contentType, bytes: body.length, output });
249704
+ }
249705
+ if (body.length === 0) {
249706
+ return formatJson({ status });
249707
+ }
249708
+ if (!isText(contentType)) {
249709
+ return formatJson({
249710
+ status,
249711
+ contentType,
249712
+ bytes: body.length,
249713
+ note: "Binary body not printed; add --output <file> to save it."
249714
+ });
249715
+ }
249716
+ const text = new TextDecoder().decode(body);
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(`
249724
+ `) ? text : `${text}
249725
+ `;
249726
+ }
249727
+ }
249457
249728
  async function fetchAction(ctx, methodArg, path, options, command) {
249458
249729
  if (!methodArg || !path) {
249459
249730
  if (options.help) {
249460
- return { stdout: command.helpInformation() };
249731
+ const usage = command.helpInformation();
249732
+ return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
249461
249733
  }
249462
249734
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249463
249735
  }
249464
249736
  const method = methodArg.toUpperCase();
249465
- if (!HTTP_METHODS.some((m) => m.toUpperCase() === method)) {
249466
- throw new InvalidInputError(`Unknown HTTP method: ${methodArg}`);
249467
- }
249468
- if (!path.startsWith("/")) {
249469
- throw new InvalidInputError(`The path must start with "/", got ${path}.`);
249470
- }
249471
249737
  if (options.help) {
249472
- const { spec, op } = await findOperation(ctx, method, path, options.refresh);
249738
+ const { spec, op } = await findOperation(ctx, method, path, {
249739
+ refresh: options.refresh,
249740
+ flag: "--help"
249741
+ });
249473
249742
  return { stdout: formatJson(getOperationContract(spec, op)) };
249474
249743
  }
249475
249744
  if (options.readOnly) {
249476
- const { op } = await findOperation(ctx, method, path, options.refresh);
249745
+ const { op } = await findOperation(ctx, method, path, {
249746
+ refresh: options.refresh,
249747
+ flag: "--read-only"
249748
+ });
249477
249749
  if (!op.readOnly) {
249478
249750
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249479
249751
  }
249480
249752
  }
249481
- const body = await resolveRequestBody(method, options.body, {
249482
- stdinIsTTY: Boolean(process.stdin.isTTY),
249483
- readStdin: () => readStdin("--body @-", { trim: false })
249753
+ ctx.errorReporter.setContext({
249754
+ command: {
249755
+ name: "api fetch",
249756
+ args: [method, path.split("?", 1)[0] ?? ""],
249757
+ options: { ...options, body: options.body && "[not reported]" }
249758
+ }
249484
249759
  });
249485
249760
  await ensureAuth(ctx);
249486
- const text = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), { successMessage: `Called ${method} ${path}` });
249487
- return { stdout: formatResponseBody(text) };
249761
+ const body = await readRequestBody(options.body, ctx.log);
249762
+ const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
249763
+ successMessage: `Called ${method} ${path}`,
249764
+ errorMessage: "Request failed"
249765
+ });
249766
+ return {
249767
+ stdout: await formatResponse(response, options.output, ctx.jsonMode)
249768
+ };
249488
249769
  }
249489
249770
  function getApiFetchCommand() {
249490
249771
  return new Base44Command("fetch", {
249491
249772
  requireAuth: false,
249492
249773
  requireAppContext: false
249493
- }).description("Call a Base44 API operation, like curl; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Concrete path with any query string, e.g. "/api/apps/<app-id>/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- for stdin (piped stdin is read too)").option("--read-only", "Refuse, before sending, any operation the spec does not mark read-only").option("--refresh", REFRESH_OPTION_HELP).option("-h, --help", "With a method and path, print that operation's contract; otherwise this help").action(fetchAction);
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]", '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);
249494
249775
  }
249495
249776
 
249496
249777
  // src/cli/commands/api/grep.ts
@@ -249505,7 +249786,14 @@ async function grepAction(ctx, pattern, options) {
249505
249786
  const limit = parseLimit(options.limit);
249506
249787
  assertValidRegex(pattern);
249507
249788
  const { spec } = await loadSpecTask(ctx, options.refresh);
249508
- const hits = grepSpec(spec, listOperations(spec), pattern, {
249789
+ let operations = listOperations(spec);
249790
+ if (options.area !== undefined) {
249791
+ operations = operationsInArea(operations, options.area);
249792
+ }
249793
+ if (options.readOnly) {
249794
+ operations = operations.filter((op) => op.readOnly);
249795
+ }
249796
+ const hits = grepOperations(spec, operations, pattern, {
249509
249797
  ignoreCase: options.ignoreCase,
249510
249798
  limit
249511
249799
  });
@@ -249515,7 +249803,7 @@ function getApiGrepCommand() {
249515
249803
  return new Base44Command("grep", {
249516
249804
  requireAuth: false,
249517
249805
  requireAppContext: false
249518
- }).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
249806
+ }).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);
249519
249807
  }
249520
249808
 
249521
249809
  // src/cli/commands/api/search.ts
@@ -249532,12 +249820,12 @@ function getApiSearchCommand() {
249532
249820
  return new Base44Command("search", {
249533
249821
  requireAuth: false,
249534
249822
  requireAppContext: false
249535
- }).description("Search every Base44 API operation by what it does").argument("<text...>", 'What you are looking for, e.g. "failed workflow runs"').option("--limit <n>", "Most results to return (default 5)").option("--read-only", "Return only read-only operations").option("--refresh", REFRESH_OPTION_HELP).action(searchAction);
249823
+ }).description("Search every Base44 API operation by what it does").argument("<text...>", 'What you are looking for, e.g. "failed workflow runs"').option("--limit <n>", "Most results to return (default 5)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(searchAction);
249536
249824
  }
249537
249825
 
249538
249826
  // src/cli/commands/api/index.ts
249539
249827
  function getApiCommand() {
249540
- return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
249828
+ return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiCatalogCommand()).addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
249541
249829
  }
249542
249830
 
249543
249831
  // src/cli/commands/auth/password-login.ts
@@ -254901,6 +255189,12 @@ var deno2 = Object.freeze({
254901
255189
  });
254902
255190
  globalThis.Deno = deno2;
254903
255191
  globalThis.Buffer = Buffer2;
255192
+ try {
255193
+ new AsyncLocalStorage().enterWith(void 0);
255194
+ } catch {
255195
+ AsyncLocalStorage.prototype.enterWith = () => {
255196
+ };
255197
+ }
254904
255198
  function getRegisteredHandler() {
254905
255199
  return registeredHandler;
254906
255200
  }
@@ -257866,7 +258160,7 @@ var TELEMETRY_PATCH = [
257866
258160
  var TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
257867
258161
 
257868
258162
  // ../functions-compiler/src/version.ts
257869
- var COMPILER_VERSION = "0.1.7";
258163
+ var COMPILER_VERSION = "0.1.8";
257870
258164
 
257871
258165
  // ../functions-compiler/src/worker-entry.ts
257872
258166
  function denoShimSource() {
@@ -262069,7 +262363,7 @@ var nativeEnumType = ZodNativeEnum.create;
262069
262363
  var promiseType = ZodPromise.create;
262070
262364
  var effectsType = ZodEffects.create;
262071
262365
  var optionalType = ZodOptional2.create;
262072
- var nullableType = ZodNullable2.create;
262366
+ var nullableType2 = ZodNullable2.create;
262073
262367
  var preprocessType = ZodEffects.createWithPreprocess;
262074
262368
  var pipelineType = ZodPipeline.create;
262075
262369
  // ../functions-compiler/src/contracts.ts
@@ -262490,6 +262784,174 @@ function runtimeVirtualPlugin() {
262490
262784
  };
262491
262785
  }
262492
262786
 
262787
+ // ../functions-compiler/src/esbuild/ws-native-virtual.ts
262788
+ var NAMESPACE4 = "base44-ws-native";
262789
+ var WS_SPECIFIER = /^(npm:)?ws(@[^/]+)?$/;
262790
+ var ADAPTER = `"use strict";
262791
+ const toBuffer = (value) => (globalThis.Buffer ? globalThis.Buffer.from(value) : value);
262792
+ const READY_STATES = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
262793
+ const later = (fn, ...args) => queueMicrotask(() => fn(...args));
262794
+ const upgradeHeaders = (options) => {
262795
+ const headers = new Headers(options?.headers);
262796
+ for (const name of headers.keys()) if (name !== "user-agent") return headers;
262797
+ return null;
262798
+ };
262799
+ class WebSocket {
262800
+ static CONNECTING = 0;
262801
+ static OPEN = 1;
262802
+ static CLOSING = 2;
262803
+ static CLOSED = 3;
262804
+ #socket = null;
262805
+ #state = 0;
262806
+ #url;
262807
+ #closeRequested = null;
262808
+ #terminated = false;
262809
+ #listeners = new Map();
262810
+ constructor(address, protocols, options) {
262811
+ if (protocols && typeof protocols === "object" && !Array.isArray(protocols)) {
262812
+ options = protocols;
262813
+ protocols = undefined;
262814
+ }
262815
+ this.#url = String(address);
262816
+ const headers = upgradeHeaders(options);
262817
+ if (headers) {
262818
+ this.#upgrade(headers, protocols);
262819
+ } else {
262820
+ this.#attach(new globalThis.WebSocket(this.#url, protocols));
262821
+ }
262822
+ }
262823
+ get readyState() {
262824
+ if (this.#terminated) return 3;
262825
+ return this.#socket ? this.#socket.readyState : this.#state;
262826
+ }
262827
+ get url() { return this.#url; }
262828
+ get protocol() { return this.#socket ? this.#socket.protocol ?? "" : ""; }
262829
+ on(name, listener) { return this.#add(name, listener, false); }
262830
+ addListener(name, listener) { return this.#add(name, listener, false); }
262831
+ once(name, listener) { return this.#add(name, listener, true); }
262832
+ off(name, listener) { return this.removeListener(name, listener); }
262833
+ removeListener(name, listener) {
262834
+ const listeners = this.#listeners.get(name);
262835
+ if (listeners) this.#listeners.set(name, listeners.filter((entry) => entry.listener !== listener));
262836
+ return this;
262837
+ }
262838
+ removeAllListeners(name) {
262839
+ if (name === undefined) this.#listeners.clear();
262840
+ else this.#listeners.delete(name);
262841
+ return this;
262842
+ }
262843
+ emit(name, ...args) {
262844
+ const listeners = this.#listeners.get(name) ?? [];
262845
+ this.#listeners.set(name, listeners.filter((entry) => !entry.once));
262846
+ for (const entry of listeners) entry.listener.apply(this, args);
262847
+ return listeners.length > 0;
262848
+ }
262849
+ send(data, options, callback) {
262850
+ const done = typeof options === "function" ? options : callback;
262851
+ try {
262852
+ if (!this.#socket) {
262853
+ throw new Error("WebSocket is not open: readyState " + this.#state + " (" + READY_STATES[this.#state] + ")");
262854
+ }
262855
+ this.#socket.send(data);
262856
+ done?.();
262857
+ } catch (error) {
262858
+ if (!done) throw error;
262859
+ done(error);
262860
+ }
262861
+ }
262862
+ close(code, reason) {
262863
+ if (this.#socket) this.#socket.close(code, reason);
262864
+ else if (this.#state === 0) {
262865
+ // Upgrade still in flight: close as soon as it lands.
262866
+ this.#closeRequested = [code, reason];
262867
+ this.#state = 2;
262868
+ }
262869
+ }
262870
+ // \`ws\` tears the connection down at once. workerd has no abrupt close, so the
262871
+ // socket is closed normally and "close" is reported now, not on the reply.
262872
+ terminate() {
262873
+ if (this.#terminated || this.readyState === 3) return;
262874
+ this.#terminated = true;
262875
+ if (this.#socket) {
262876
+ try { this.#socket.close(); } catch {}
262877
+ } else {
262878
+ // Upgrade still in flight: close it on arrival, without an "open".
262879
+ this.#closeRequested = [];
262880
+ this.#state = 3;
262881
+ }
262882
+ later(() => this.emit("close", 1006, toBuffer("")));
262883
+ }
262884
+ #attach(socket) {
262885
+ this.#socket = socket;
262886
+ try { socket.binaryType = "arraybuffer"; } catch {}
262887
+ socket.addEventListener("open", () => this.emit("open"));
262888
+ socket.addEventListener("message", (event) => {
262889
+ const isBinary = typeof event.data !== "string";
262890
+ this.emit("message", toBuffer(isBinary ? new Uint8Array(event.data) : event.data), isBinary);
262891
+ });
262892
+ socket.addEventListener("error", (event) => this.emit("error", event.error ?? new Error(event.message || "WebSocket error")));
262893
+ socket.addEventListener("close", (event) => {
262894
+ if (!this.#terminated) this.emit("close", event.code, toBuffer(event.reason ?? ""));
262895
+ });
262896
+ }
262897
+ #upgrade(headers, protocols) {
262898
+ headers.set("Upgrade", "websocket");
262899
+ if (protocols) headers.set("Sec-WebSocket-Protocol", [].concat(protocols).join(", "));
262900
+ const httpUrl = this.#url.replace(/^ws(s?):/i, "http$1:");
262901
+ const fail = (error) => {
262902
+ this.#state = 3;
262903
+ if (this.#terminated) return;
262904
+ this.emit("error", error);
262905
+ this.emit("close", 1006, toBuffer(""));
262906
+ };
262907
+ // Two-argument then(): an exception from an "open" listener must not be
262908
+ // reported as a failed upgrade.
262909
+ fetch(httpUrl, { headers }).then((response) => {
262910
+ const socket = response.webSocket;
262911
+ if (!socket) {
262912
+ response.body?.cancel();
262913
+ return fail(new Error("Unexpected server response: " + response.status));
262914
+ }
262915
+ socket.accept();
262916
+ this.#attach(socket);
262917
+ if (this.#closeRequested) return socket.close(...this.#closeRequested);
262918
+ // accept() opens the socket without dispatching an "open" event.
262919
+ this.emit("open");
262920
+ }, fail);
262921
+ }
262922
+ #add(name, listener, once) {
262923
+ const listeners = this.#listeners.get(name) ?? [];
262924
+ listeners.push({ listener, once });
262925
+ this.#listeners.set(name, listeners);
262926
+ return this;
262927
+ }
262928
+ }
262929
+ class WebSocketServer {
262930
+ constructor() {
262931
+ throw new Error("ws WebSocketServer is not available in Base44 functions: a function can open WebSocket connections but cannot listen for them.");
262932
+ }
262933
+ }
262934
+ module.exports = WebSocket;
262935
+ module.exports.WebSocket = WebSocket;
262936
+ module.exports.WebSocketServer = WebSocketServer;
262937
+ module.exports.default = WebSocket;
262938
+ `;
262939
+ function wsNativeVirtualPlugin() {
262940
+ return {
262941
+ name: "base44-ws-native",
262942
+ setup(build) {
262943
+ build.onResolve({ filter: WS_SPECIFIER }, () => ({
262944
+ path: "ws",
262945
+ namespace: NAMESPACE4
262946
+ }));
262947
+ build.onLoad({ filter: /.*/, namespace: NAMESPACE4 }, () => ({
262948
+ contents: ADAPTER,
262949
+ loader: "js"
262950
+ }));
262951
+ }
262952
+ };
262953
+ }
262954
+
262493
262955
  // ../functions-compiler/src/deno-bundle.ts
262494
262956
  async function bundleToModule(prepared, nodeModulesDir = "none") {
262495
262957
  const dir = await mkdtemp(path21.join(tmpdir2(), "b44-bundle-"));
@@ -262513,6 +262975,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
262513
262975
  sourcemap: false,
262514
262976
  logLevel: "silent",
262515
262977
  plugins: [
262978
+ wsNativeVirtualPlugin(),
262516
262979
  nodeBuiltinRequirePlugin(),
262517
262980
  userFilesPlugin(prepared.files, prepared.entry),
262518
262981
  privateDataSourcesVirtualPlugin(),
@@ -272902,4 +273365,4 @@ export {
272902
273365
  runCLI
272903
273366
  };
272904
273367
 
272905
- //# debugId=FA1E97B3DE15B20C64756E2164756E21
273368
+ //# debugId=34B2FE9173AAC44664756E2164756E21