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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,8 +45,8 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
45
45
  | ------- | ----------- |
46
46
  | `api catalog [area]` | List the API's areas, or every operation in one area |
47
47
  | `api search <text>` | Search every public Base44 API operation by what it does |
48
- | `api grep <pattern>` | Search the raw API spec with a regular expression; `--area` narrows it to one area |
49
- | `api fetch <METHOD> <path>` | Call any public Base44 API operation, like curl; `--help` after a path prints its contract |
48
+ | `api grep <pattern>` | Search the API spec with a regular expression, for when search misses |
49
+ | `api fetch <METHOD> <path>` | Call any public Base44 API operation; `--help` after a path prints its contract |
50
50
  | [`create`](https://docs.base44.com/developers/references/cli/commands/create) | Create a new Base44 project from a template |
51
51
  | [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy all project resources and site to Base44 |
52
52
  | [`eject`](https://docs.base44.com/developers/references/cli/commands/eject) | Download the code for an existing Base44 project |
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,10 +249202,18 @@ 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
  }
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
+ };
249216
+ }
249176
249217
  // src/core/api-spec/grep.ts
249177
249218
  var CONTEXT_CHARS = 40;
249178
249219
  var MAX_SNIPPETS = 3;
@@ -249195,15 +249236,14 @@ function snippets(text, pattern) {
249195
249236
  function grepSpec(spec, operations, pattern, options = {}) {
249196
249237
  const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249197
249238
  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)) {
249239
+ for (const op of operations) {
249200
249240
  const { summary, description, parameters, requestBody, responses } = op.operation;
249201
249241
  const matches = snippets(`${op.endpoint} ${JSON.stringify({ summary, description, parameters, requestBody, responses })}`, regex);
249202
249242
  if (matches.length > 0) {
249203
249243
  hits.push({ ...toOperationSummary(op), matches });
249204
249244
  }
249205
249245
  }
249206
- const schemas = options.area === undefined && !options.readOnly ? spec.components?.schemas : {};
249246
+ const schemas = options.schemas === false ? {} : spec.components?.schemas;
249207
249247
  for (const [schema, definition] of Object.entries(schemas ?? {})) {
249208
249248
  const matches = snippets(JSON.stringify(definition), regex);
249209
249249
  if (matches.length > 0) {
@@ -249249,7 +249289,10 @@ var OperationSchema = looseObject({
249249
249289
  responses: record(string2(), unknown()).optional(),
249250
249290
  security: array(SecurityRequirementSchema).optional()
249251
249291
  });
249252
- var PathItemSchema = looseObject(Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])));
249292
+ var PathItemSchema = looseObject({
249293
+ ...Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])),
249294
+ parameters: array(unknown()).optional()
249295
+ });
249253
249296
  var OpenApiSpecSchema = looseObject({
249254
249297
  openapi: string2(),
249255
249298
  paths: record(string2(), PathItemSchema),
@@ -249272,12 +249315,30 @@ function parameterText(operation) {
249272
249315
  return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249273
249316
  }).join(" ");
249274
249317
  }
249318
+ function mergeParameters(shared, own) {
249319
+ if (!shared?.length) {
249320
+ return own;
249321
+ }
249322
+ const key = (parameter) => {
249323
+ const parsed = ParameterSchema.safeParse(parameter);
249324
+ return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249325
+ };
249326
+ const ownKeys = new Set((own ?? []).map(key));
249327
+ return [
249328
+ ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249329
+ ...own ?? []
249330
+ ];
249331
+ }
249275
249332
  function listOperations(spec) {
249276
249333
  return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249277
- const operation = item[method];
249278
- if (!operation) {
249334
+ const declared = item[method];
249335
+ if (!declared) {
249279
249336
  return [];
249280
249337
  }
249338
+ const operation = {
249339
+ ...declared,
249340
+ parameters: mergeParameters(item.parameters, declared.parameters)
249341
+ };
249281
249342
  return [
249282
249343
  {
249283
249344
  endpoint: `${method.toUpperCase()} ${path}`,
@@ -249354,6 +249415,30 @@ function jsonSchemaOf(value) {
249354
249415
  const parsed = RequestBodySchema.safeParse(value);
249355
249416
  return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
249356
249417
  }
249418
+ function requestBodyOf(value) {
249419
+ const parsed = RequestBodySchema.safeParse(value);
249420
+ const content = parsed.success ? parsed.data.content ?? {} : {};
249421
+ const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
249422
+ return contentType ? { contentType, schema: content[contentType]?.schema } : {};
249423
+ }
249424
+ function leftoverRefs(node, schemas, found = new Map) {
249425
+ if (Array.isArray(node)) {
249426
+ for (const item of node) {
249427
+ leftoverRefs(item, schemas, found);
249428
+ }
249429
+ } else if (node !== null && typeof node === "object") {
249430
+ for (const [key, value] of Object.entries(node)) {
249431
+ if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
249432
+ const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
249433
+ found.set(value, schema);
249434
+ leftoverRefs(schema, schemas, found);
249435
+ } else {
249436
+ leftoverRefs(value, schemas, found);
249437
+ }
249438
+ }
249439
+ }
249440
+ return found;
249441
+ }
249357
249442
  function getOperationContract(spec, op) {
249358
249443
  const schemas = spec.components?.schemas ?? {};
249359
249444
  const inline = (node) => node === undefined ? null : inlineRefs(node, schemas);
@@ -249363,7 +249448,8 @@ function getOperationContract(spec, op) {
249363
249448
  });
249364
249449
  const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
249365
249450
  const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
249366
- return {
249451
+ const requestBody = requestBodyOf(op.operation.requestBody);
249452
+ const contract = {
249367
249453
  endpoint: op.endpoint,
249368
249454
  method: op.method,
249369
249455
  path: op.path,
@@ -249387,18 +249473,34 @@ function getOperationContract(spec, op) {
249387
249473
  }
249388
249474
  ];
249389
249475
  }),
249390
- requestBodySchema: inline(jsonSchemaOf(op.operation.requestBody)),
249476
+ ...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
249477
+ requestBodySchema: inline(requestBody.schema),
249391
249478
  responseSchema: inline(success),
249392
249479
  errors: Object.fromEntries(errors.map(([status, response]) => [status, response.description ?? ""]))
249393
249480
  };
249481
+ const refs = leftoverRefs(contract, schemas);
249482
+ return {
249483
+ ...contract,
249484
+ ...refs.size > 0 ? { refs: Object.fromEntries(refs) } : {}
249485
+ };
249394
249486
  }
249395
249487
  // src/core/api-spec/request.ts
249488
+ var MAX_ERROR_BODY_CHARS = 4000;
249489
+ async function readBody(response) {
249490
+ try {
249491
+ const text = (await response.clone().text()).trim();
249492
+ return text.length > MAX_ERROR_BODY_CHARS ? `${text.slice(0, MAX_ERROR_BODY_CHARS)}…` : text || undefined;
249493
+ } catch {
249494
+ return;
249495
+ }
249496
+ }
249396
249497
  async function sendApiRequest(method, path, body) {
249397
249498
  try {
249398
249499
  const response = await base44Client(path.replace(/^\/+/, ""), {
249399
249500
  method,
249400
249501
  body,
249401
- headers: body === undefined ? {} : { "Content-Type": "application/json" }
249502
+ headers: body === undefined ? {} : { "Content-Type": "application/json" },
249503
+ timeout: false
249402
249504
  });
249403
249505
  return {
249404
249506
  status: response.status,
@@ -249406,11 +249508,20 @@ async function sendApiRequest(method, path, body) {
249406
249508
  body: new Uint8Array(await response.arrayBuffer())
249407
249509
  };
249408
249510
  } catch (error) {
249409
- throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249511
+ const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249512
+ const raw = error instanceof HTTPError ? await readBody(error.response) : undefined;
249513
+ throw new ApiError(apiError.message, {
249514
+ statusCode: apiError.statusCode,
249515
+ requestUrl: apiError.requestUrl,
249516
+ requestMethod: apiError.requestMethod,
249517
+ requestId: apiError.requestId,
249518
+ hints: apiError.hints,
249519
+ details: raw ? [`Response body: ${raw}`] : apiError.details
249520
+ });
249410
249521
  }
249411
249522
  }
249412
249523
  // src/core/api-spec/spec.ts
249413
- import { stat as stat3 } from "node:fs/promises";
249524
+ import { rename, stat as stat3 } from "node:fs/promises";
249414
249525
  import { join as join22 } from "node:path";
249415
249526
  var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
249416
249527
  function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
@@ -249433,17 +249544,24 @@ function parseSpec(text) {
249433
249544
  }
249434
249545
  return result.data;
249435
249546
  }
249547
+ var SPEC_DOWNLOAD_TIMEOUT_MS = 60000;
249436
249548
  async function readFreshCache(path) {
249437
249549
  try {
249438
249550
  const { mtimeMs } = await stat3(path);
249439
- return isSpecCacheFresh(mtimeMs) ? await readTextFile(path) : null;
249551
+ if (!isSpecCacheFresh(mtimeMs)) {
249552
+ return null;
249553
+ }
249554
+ const text = await readTextFile(path);
249555
+ return { text, spec: parseSpec(text) };
249440
249556
  } catch {
249441
249557
  return null;
249442
249558
  }
249443
249559
  }
249444
249560
  async function downloadSpec() {
249445
249561
  try {
249446
- const response = await base44Client.get("api/openapi.json");
249562
+ const response = await base44Client.get("api/openapi.json", {
249563
+ timeout: SPEC_DOWNLOAD_TIMEOUT_MS
249564
+ });
249447
249565
  return await response.text();
249448
249566
  } catch (error) {
249449
249567
  throw await ApiError.fromHttpError(error, "fetching the API spec");
@@ -249453,17 +249571,19 @@ async function loadSpec(options = {}) {
249453
249571
  const path = getSpecCachePath();
249454
249572
  const cached = options.refresh ? null : await readFreshCache(path);
249455
249573
  if (cached !== null) {
249456
- return { text: cached, spec: parseSpec(cached) };
249574
+ return cached;
249457
249575
  }
249458
249576
  const text = await downloadSpec();
249459
249577
  const spec = parseSpec(text);
249460
- await writeFile(path, text);
249578
+ const partial = `${path}.${process.pid}.tmp`;
249579
+ await writeFile(partial, text);
249580
+ await rename(partial, path);
249461
249581
  return { text, spec };
249462
249582
  }
249463
249583
  // src/cli/commands/api/shared.ts
249584
+ import { fstatSync } from "node:fs";
249464
249585
  function formatJson(value) {
249465
- return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
249466
- `;
249586
+ return toJsonStdout(value, { compact: !process.stdout.isTTY });
249467
249587
  }
249468
249588
  function parseLimit(value) {
249469
249589
  if (value === undefined) {
@@ -249493,38 +249613,37 @@ function operationsInArea(operations, area) {
249493
249613
  }
249494
249614
  return inArea;
249495
249615
  }
249496
- async function readRequestBody(method, flag) {
249616
+ function isPipedStdin() {
249617
+ try {
249618
+ const stats = fstatSync(0);
249619
+ return stats.isFIFO() || stats.isFile();
249620
+ } catch {
249621
+ return false;
249622
+ }
249623
+ }
249624
+ async function readRequestBody(flag, log) {
249497
249625
  if (flag === "@-") {
249498
249626
  return readStdin("--body @-", { trim: false });
249499
249627
  }
249500
249628
  if (flag?.startsWith("@")) {
249501
249629
  return readTextFile(flag.slice(1));
249502
249630
  }
249503
- if (flag !== undefined) {
249504
- return flag;
249505
- }
249506
- if (method === "GET" || method === "HEAD" || process.stdin.isTTY) {
249507
- return;
249631
+ if (flag === undefined && isPipedStdin()) {
249632
+ log.warn("stdin is ignored; pass --body @- to send it as the body.");
249508
249633
  }
249509
- const piped = await readStdin("--body", { trim: false });
249510
- return piped.trim() ? piped : undefined;
249634
+ return flag;
249511
249635
  }
249512
249636
 
249513
249637
  // src/cli/commands/api/catalog.ts
249514
249638
  async function catalogAction(ctx, area, options) {
249515
249639
  const { spec } = await loadSpecTask(ctx, options.refresh);
249516
- const operations = listOperations(spec).filter((op) => !options.readOnly || op.readOnly);
249640
+ const operations = listOperations(spec);
249641
+ const readOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
249517
249642
  if (area === undefined) {
249518
- return { stdout: formatJson(catalogIndex(operations)) };
249643
+ return { stdout: formatJson(catalogIndex(readOnly(operations))) };
249519
249644
  }
249520
- const inArea = operationsInArea(operations, area);
249521
- return {
249522
- stdout: formatJson({
249523
- area,
249524
- operations: inArea.map(toOperationSummary),
249525
- total: inArea.length
249526
- })
249527
- };
249645
+ const inArea = readOnly(operationsInArea(operations, area));
249646
+ return { stdout: formatJson(areaListing(area, inArea)) };
249528
249647
  }
249529
249648
  function getApiCatalogCommand() {
249530
249649
  return new Base44Command("catalog", {
@@ -249534,12 +249653,16 @@ function getApiCatalogCommand() {
249534
249653
  }
249535
249654
 
249536
249655
  // src/cli/commands/api/fetch.ts
249537
- async function findOperation(ctx, method, path, refresh) {
249656
+ async function findOperation(ctx, method, path, { refresh, flag }) {
249538
249657
  const { spec } = await loadSpecTask(ctx, refresh);
249539
249658
  const op = matchOperation(listOperations(spec), method, path);
249540
249659
  if (!op) {
249541
249660
  throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
249542
249661
  hints: [
249662
+ {
249663
+ message: "The cached spec may predate this route; fetch it again",
249664
+ command: `base44 api fetch ${method} ${path} ${flag} --refresh`
249665
+ },
249543
249666
  {
249544
249667
  message: "Find the operation and its path template",
249545
249668
  command: 'base44 api search "<what you want to do>"'
@@ -249559,7 +249682,7 @@ var TEXT_CONTENT_TYPES = [
249559
249682
  function isText(contentType) {
249560
249683
  return !contentType || TEXT_CONTENT_TYPES.some((hint) => contentType.toLowerCase().includes(hint));
249561
249684
  }
249562
- async function formatResponse({ status, contentType, body }, output) {
249685
+ async function formatResponse({ status, contentType, body }, output, jsonMode) {
249563
249686
  if (output !== undefined) {
249564
249687
  await writeFile(output, body);
249565
249688
  return formatJson({ status, contentType, bytes: body.length, output });
@@ -249568,12 +249691,20 @@ async function formatResponse({ status, contentType, body }, output) {
249568
249691
  return formatJson({ status });
249569
249692
  }
249570
249693
  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.`);
249694
+ return formatJson({
249695
+ status,
249696
+ contentType,
249697
+ bytes: body.length,
249698
+ note: "Binary body not printed; add --output <file> to save it."
249699
+ });
249572
249700
  }
249573
249701
  const text = new TextDecoder().decode(body);
249574
249702
  try {
249575
249703
  return formatJson(JSON.parse(text));
249576
249704
  } catch {
249705
+ if (jsonMode) {
249706
+ return formatJson({ status, contentType, body: text });
249707
+ }
249577
249708
  return text.endsWith(`
249578
249709
  `) ? text : `${text}
249579
249710
  `;
@@ -249582,34 +249713,50 @@ async function formatResponse({ status, contentType, body }, output) {
249582
249713
  async function fetchAction(ctx, methodArg, path, options, command) {
249583
249714
  if (!methodArg || !path) {
249584
249715
  if (options.help) {
249585
- return { stdout: command.helpInformation() };
249716
+ const usage = command.helpInformation();
249717
+ return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
249586
249718
  }
249587
249719
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249588
249720
  }
249589
249721
  const method = methodArg.toUpperCase();
249590
249722
  if (options.help) {
249591
- const { spec, op } = await findOperation(ctx, method, path, options.refresh);
249723
+ const { spec, op } = await findOperation(ctx, method, path, {
249724
+ refresh: options.refresh,
249725
+ flag: "--help"
249726
+ });
249592
249727
  return { stdout: formatJson(getOperationContract(spec, op)) };
249593
249728
  }
249594
249729
  if (options.readOnly) {
249595
- const { op } = await findOperation(ctx, method, path, options.refresh);
249730
+ const { op } = await findOperation(ctx, method, path, {
249731
+ refresh: options.refresh,
249732
+ flag: "--read-only"
249733
+ });
249596
249734
  if (!op.readOnly) {
249597
249735
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249598
249736
  }
249599
249737
  }
249738
+ ctx.errorReporter.setContext({
249739
+ command: {
249740
+ name: "api fetch",
249741
+ args: [method, path.split("?", 1)[0] ?? ""],
249742
+ options: { ...options, body: options.body && "[not reported]" }
249743
+ }
249744
+ });
249600
249745
  await ensureAuth(ctx);
249601
- const body = await readRequestBody(method, options.body);
249746
+ const body = await readRequestBody(options.body, ctx.log);
249602
249747
  const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
249603
249748
  successMessage: `Called ${method} ${path}`,
249604
249749
  errorMessage: "Request failed"
249605
249750
  });
249606
- return { stdout: await formatResponse(response, options.output) };
249751
+ return {
249752
+ stdout: await formatResponse(response, options.output, ctx.jsonMode)
249753
+ };
249607
249754
  }
249608
249755
  function getApiFetchCommand() {
249609
249756
  return new Base44Command("fetch", {
249610
249757
  requireAuth: false,
249611
249758
  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);
249759
+ }).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
249760
  }
249614
249761
 
249615
249762
  // src/cli/commands/api/grep.ts
@@ -249624,15 +249771,18 @@ async function grepAction(ctx, pattern, options) {
249624
249771
  const limit = parseLimit(options.limit);
249625
249772
  assertValidRegex(pattern);
249626
249773
  const { spec } = await loadSpecTask(ctx, options.refresh);
249627
- const operations = listOperations(spec);
249774
+ let operations = listOperations(spec);
249628
249775
  if (options.area !== undefined) {
249629
- operationsInArea(operations, options.area);
249776
+ operations = operationsInArea(operations, options.area);
249777
+ }
249778
+ if (options.readOnly) {
249779
+ operations = operations.filter((op) => op.readOnly);
249630
249780
  }
249781
+ const narrowed = options.area !== undefined || options.readOnly === true;
249631
249782
  const hits = grepSpec(spec, operations, pattern, {
249632
- area: options.area,
249633
249783
  ignoreCase: options.ignoreCase,
249634
249784
  limit,
249635
- readOnly: options.readOnly
249785
+ schemas: !narrowed
249636
249786
  });
249637
249787
  return { stdout: formatJson(hits) };
249638
249788
  }
@@ -249640,7 +249790,7 @@ function getApiGrepCommand() {
249640
249790
  return new Base44Command("grep", {
249641
249791
  requireAuth: false,
249642
249792
  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);
249793
+ }).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 or schemas to return (default 20)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
249644
249794
  }
249645
249795
 
249646
249796
  // src/cli/commands/api/search.ts
@@ -273202,4 +273352,4 @@ export {
273202
273352
  runCLI
273203
273353
  };
273204
273354
 
273205
- //# debugId=C89C416C808E439E64756E2164756E21
273355
+ //# debugId=47D4434C61AEF7C764756E2164756E21