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

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
@@ -249105,13 +249105,17 @@ var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
249105
249105
  var BOOST = { path: 8, summary: 5, description: 2, parameters: 0.5 };
249106
249106
  var MIN_RELATIVE_SCORE = 0.2;
249107
249107
  var TOKEN_SEPARATOR = /[\n\r\p{Z}\p{P}\p{S}]+/u;
249108
+ var STOPWORDS = new Set("a an and are at be by do does for from how i in is it its me my of on or our that the this to we what who with you your".split(" "));
249109
+ function tokenize(text) {
249110
+ return text.split(TOKEN_SEPARATOR).filter((word) => word && !STOPWORDS.has(word.toLowerCase()));
249111
+ }
249108
249112
  function toOperationSummary(op) {
249109
249113
  return { endpoint: op.endpoint, summary: op.summary };
249110
249114
  }
249111
249115
  function buildSearchIndex(operations) {
249112
249116
  const index = new MiniSearch({
249113
249117
  fields: ["path", "summary", "description", "parameters"],
249114
- tokenize: (text) => text.split(TOKEN_SEPARATOR).filter(Boolean)
249118
+ tokenize
249115
249119
  });
249116
249120
  index.addAll(operations.map((op, id) => ({
249117
249121
  id,
@@ -249122,14 +249126,25 @@ function buildSearchIndex(operations) {
249122
249126
  })));
249123
249127
  return index;
249124
249128
  }
249129
+ function summaryCoverage(query, op) {
249130
+ const terms = tokenize(query.toLowerCase());
249131
+ if (!op || terms.length === 0) {
249132
+ return 0;
249133
+ }
249134
+ const words = tokenize(op.summary.toLowerCase());
249135
+ return terms.filter((term) => words.some((word) => word.startsWith(term))).length / terms.length;
249136
+ }
249125
249137
  function searchOperations(operations, query, options = {}) {
249126
249138
  const index = buildSearchIndex(operations);
249127
249139
  const hits = index.search(query, {
249128
- prefix: true,
249129
- fuzzy: 0.2,
249140
+ prefix: (term) => term.length >= 3,
249141
+ fuzzy: (term) => term.length >= 4 ? 0.2 : false,
249130
249142
  boost: BOOST,
249131
249143
  filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
249132
- });
249144
+ }).map((hit) => ({
249145
+ ...hit,
249146
+ score: hit.score * (1 + summaryCoverage(query, operations[hit.id]))
249147
+ })).sort((a, b) => b.score - a.score);
249133
249148
  const baseline = (hits[0]?.score ?? 0) * MIN_RELATIVE_SCORE;
249134
249149
  return hits.filter((hit) => hit.score >= baseline).slice(0, options.limit ?? 5).flatMap((hit) => {
249135
249150
  const op = operations[hit.id];
@@ -249140,6 +249155,7 @@ function searchOperations(operations, query, options = {}) {
249140
249155
  // src/core/api-spec/catalog.ts
249141
249156
  var INLINE_AREA_MAX = 2;
249142
249157
  var AREA_SAMPLE_MAX = 3;
249158
+ var AREA_OPERATIONS_MAX = 200;
249143
249159
  var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
249144
249160
  function areaOf(path) {
249145
249161
  const parts = path.split("/").filter(Boolean);
@@ -249173,6 +249189,14 @@ function catalogIndex(operations) {
249173
249189
  });
249174
249190
  return { areas, total: operations.length };
249175
249191
  }
249192
+ function areaListing(area, operations, max = AREA_OPERATIONS_MAX) {
249193
+ return {
249194
+ area,
249195
+ operations: operations.slice(0, max).map(toOperationSummary),
249196
+ total: operations.length,
249197
+ truncated: operations.length > max
249198
+ };
249199
+ }
249176
249200
  // src/core/api-spec/grep.ts
249177
249201
  var CONTEXT_CHARS = 40;
249178
249202
  var MAX_SNIPPETS = 3;
@@ -249195,15 +249219,14 @@ function snippets(text, pattern) {
249195
249219
  function grepSpec(spec, operations, pattern, options = {}) {
249196
249220
  const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249197
249221
  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)) {
249222
+ for (const op of operations) {
249200
249223
  const { summary, description, parameters, requestBody, responses } = op.operation;
249201
249224
  const matches = snippets(`${op.endpoint} ${JSON.stringify({ summary, description, parameters, requestBody, responses })}`, regex);
249202
249225
  if (matches.length > 0) {
249203
249226
  hits.push({ ...toOperationSummary(op), matches });
249204
249227
  }
249205
249228
  }
249206
- const schemas = options.area === undefined && !options.readOnly ? spec.components?.schemas : {};
249229
+ const schemas = options.schemas === false ? {} : spec.components?.schemas;
249207
249230
  for (const [schema, definition] of Object.entries(schemas ?? {})) {
249208
249231
  const matches = snippets(JSON.stringify(definition), regex);
249209
249232
  if (matches.length > 0) {
@@ -249249,7 +249272,10 @@ var OperationSchema = looseObject({
249249
249272
  responses: record(string2(), unknown()).optional(),
249250
249273
  security: array(SecurityRequirementSchema).optional()
249251
249274
  });
249252
- var PathItemSchema = looseObject(Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])));
249275
+ var PathItemSchema = looseObject({
249276
+ ...Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])),
249277
+ parameters: array(unknown()).optional()
249278
+ });
249253
249279
  var OpenApiSpecSchema = looseObject({
249254
249280
  openapi: string2(),
249255
249281
  paths: record(string2(), PathItemSchema),
@@ -249272,12 +249298,30 @@ function parameterText(operation) {
249272
249298
  return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
249273
249299
  }).join(" ");
249274
249300
  }
249301
+ function mergeParameters(shared, own) {
249302
+ if (!shared?.length) {
249303
+ return own;
249304
+ }
249305
+ const key = (parameter) => {
249306
+ const parsed = ParameterSchema.safeParse(parameter);
249307
+ return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
249308
+ };
249309
+ const ownKeys = new Set((own ?? []).map(key));
249310
+ return [
249311
+ ...shared.filter((parameter) => !ownKeys.has(key(parameter))),
249312
+ ...own ?? []
249313
+ ];
249314
+ }
249275
249315
  function listOperations(spec) {
249276
249316
  return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
249277
- const operation = item[method];
249278
- if (!operation) {
249317
+ const declared = item[method];
249318
+ if (!declared) {
249279
249319
  return [];
249280
249320
  }
249321
+ const operation = {
249322
+ ...declared,
249323
+ parameters: mergeParameters(item.parameters, declared.parameters)
249324
+ };
249281
249325
  return [
249282
249326
  {
249283
249327
  endpoint: `${method.toUpperCase()} ${path}`,
@@ -249354,6 +249398,30 @@ function jsonSchemaOf(value) {
249354
249398
  const parsed = RequestBodySchema.safeParse(value);
249355
249399
  return parsed.success ? parsed.data.content?.["application/json"]?.schema : undefined;
249356
249400
  }
249401
+ function requestBodyOf(value) {
249402
+ const parsed = RequestBodySchema.safeParse(value);
249403
+ const content = parsed.success ? parsed.data.content ?? {} : {};
249404
+ const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
249405
+ return contentType ? { contentType, schema: content[contentType]?.schema } : {};
249406
+ }
249407
+ function leftoverRefs(node, schemas, found = new Map) {
249408
+ if (Array.isArray(node)) {
249409
+ for (const item of node) {
249410
+ leftoverRefs(item, schemas, found);
249411
+ }
249412
+ } else if (node !== null && typeof node === "object") {
249413
+ for (const [key, value] of Object.entries(node)) {
249414
+ if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
249415
+ const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
249416
+ found.set(value, schema);
249417
+ leftoverRefs(schema, schemas, found);
249418
+ } else {
249419
+ leftoverRefs(value, schemas, found);
249420
+ }
249421
+ }
249422
+ }
249423
+ return found;
249424
+ }
249357
249425
  function getOperationContract(spec, op) {
249358
249426
  const schemas = spec.components?.schemas ?? {};
249359
249427
  const inline = (node) => node === undefined ? null : inlineRefs(node, schemas);
@@ -249363,7 +249431,8 @@ function getOperationContract(spec, op) {
249363
249431
  });
249364
249432
  const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => jsonSchemaOf(response)).find(Boolean);
249365
249433
  const errors = responses.filter(([status, response]) => !status.startsWith("2") && response.description !== FRAMEWORK_VALIDATION_ERROR);
249366
- return {
249434
+ const requestBody = requestBodyOf(op.operation.requestBody);
249435
+ const contract = {
249367
249436
  endpoint: op.endpoint,
249368
249437
  method: op.method,
249369
249438
  path: op.path,
@@ -249387,18 +249456,34 @@ function getOperationContract(spec, op) {
249387
249456
  }
249388
249457
  ];
249389
249458
  }),
249390
- requestBodySchema: inline(jsonSchemaOf(op.operation.requestBody)),
249459
+ ...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
249460
+ requestBodySchema: inline(requestBody.schema),
249391
249461
  responseSchema: inline(success),
249392
249462
  errors: Object.fromEntries(errors.map(([status, response]) => [status, response.description ?? ""]))
249393
249463
  };
249464
+ const refs = leftoverRefs(contract, schemas);
249465
+ return {
249466
+ ...contract,
249467
+ ...refs.size > 0 ? { refs: Object.fromEntries(refs) } : {}
249468
+ };
249394
249469
  }
249395
249470
  // src/core/api-spec/request.ts
249471
+ var MAX_ERROR_BODY_CHARS = 4000;
249472
+ async function readBody(response) {
249473
+ try {
249474
+ const text = (await response.clone().text()).trim();
249475
+ return text.length > MAX_ERROR_BODY_CHARS ? `${text.slice(0, MAX_ERROR_BODY_CHARS)}…` : text || undefined;
249476
+ } catch {
249477
+ return;
249478
+ }
249479
+ }
249396
249480
  async function sendApiRequest(method, path, body) {
249397
249481
  try {
249398
249482
  const response = await base44Client(path.replace(/^\/+/, ""), {
249399
249483
  method,
249400
249484
  body,
249401
- headers: body === undefined ? {} : { "Content-Type": "application/json" }
249485
+ headers: body === undefined ? {} : { "Content-Type": "application/json" },
249486
+ timeout: false
249402
249487
  });
249403
249488
  return {
249404
249489
  status: response.status,
@@ -249406,11 +249491,20 @@ async function sendApiRequest(method, path, body) {
249406
249491
  body: new Uint8Array(await response.arrayBuffer())
249407
249492
  };
249408
249493
  } catch (error) {
249409
- throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249494
+ const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
249495
+ const raw = error instanceof HTTPError ? await readBody(error.response) : undefined;
249496
+ throw new ApiError(apiError.message, {
249497
+ statusCode: apiError.statusCode,
249498
+ requestUrl: apiError.requestUrl,
249499
+ requestMethod: apiError.requestMethod,
249500
+ requestId: apiError.requestId,
249501
+ hints: apiError.hints,
249502
+ details: raw ? [`Response body: ${raw}`] : apiError.details
249503
+ });
249410
249504
  }
249411
249505
  }
249412
249506
  // src/core/api-spec/spec.ts
249413
- import { stat as stat3 } from "node:fs/promises";
249507
+ import { rename, stat as stat3 } from "node:fs/promises";
249414
249508
  import { join as join22 } from "node:path";
249415
249509
  var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
249416
249510
  function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
@@ -249433,17 +249527,24 @@ function parseSpec(text) {
249433
249527
  }
249434
249528
  return result.data;
249435
249529
  }
249530
+ var SPEC_DOWNLOAD_TIMEOUT_MS = 60000;
249436
249531
  async function readFreshCache(path) {
249437
249532
  try {
249438
249533
  const { mtimeMs } = await stat3(path);
249439
- return isSpecCacheFresh(mtimeMs) ? await readTextFile(path) : null;
249534
+ if (!isSpecCacheFresh(mtimeMs)) {
249535
+ return null;
249536
+ }
249537
+ const text = await readTextFile(path);
249538
+ return { text, spec: parseSpec(text) };
249440
249539
  } catch {
249441
249540
  return null;
249442
249541
  }
249443
249542
  }
249444
249543
  async function downloadSpec() {
249445
249544
  try {
249446
- const response = await base44Client.get("api/openapi.json");
249545
+ const response = await base44Client.get("api/openapi.json", {
249546
+ timeout: SPEC_DOWNLOAD_TIMEOUT_MS
249547
+ });
249447
249548
  return await response.text();
249448
249549
  } catch (error) {
249449
249550
  throw await ApiError.fromHttpError(error, "fetching the API spec");
@@ -249453,17 +249554,19 @@ async function loadSpec(options = {}) {
249453
249554
  const path = getSpecCachePath();
249454
249555
  const cached = options.refresh ? null : await readFreshCache(path);
249455
249556
  if (cached !== null) {
249456
- return { text: cached, spec: parseSpec(cached) };
249557
+ return cached;
249457
249558
  }
249458
249559
  const text = await downloadSpec();
249459
249560
  const spec = parseSpec(text);
249460
- await writeFile(path, text);
249561
+ const partial = `${path}.${process.pid}.tmp`;
249562
+ await writeFile(partial, text);
249563
+ await rename(partial, path);
249461
249564
  return { text, spec };
249462
249565
  }
249463
249566
  // src/cli/commands/api/shared.ts
249567
+ import { fstatSync } from "node:fs";
249464
249568
  function formatJson(value) {
249465
- return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
249466
- `;
249569
+ return toJsonStdout(value, { compact: !process.stdout.isTTY });
249467
249570
  }
249468
249571
  function parseLimit(value) {
249469
249572
  if (value === undefined) {
@@ -249493,38 +249596,37 @@ function operationsInArea(operations, area) {
249493
249596
  }
249494
249597
  return inArea;
249495
249598
  }
249496
- async function readRequestBody(method, flag) {
249599
+ function isPipedStdin() {
249600
+ try {
249601
+ const stats = fstatSync(0);
249602
+ return stats.isFIFO() || stats.isFile();
249603
+ } catch {
249604
+ return false;
249605
+ }
249606
+ }
249607
+ async function readRequestBody(flag, log) {
249497
249608
  if (flag === "@-") {
249498
249609
  return readStdin("--body @-", { trim: false });
249499
249610
  }
249500
249611
  if (flag?.startsWith("@")) {
249501
249612
  return readTextFile(flag.slice(1));
249502
249613
  }
249503
- if (flag !== undefined) {
249504
- return flag;
249505
- }
249506
- if (method === "GET" || method === "HEAD" || process.stdin.isTTY) {
249507
- return;
249614
+ if (flag === undefined && isPipedStdin()) {
249615
+ log.warn("stdin is ignored; pass --body @- to send it as the body.");
249508
249616
  }
249509
- const piped = await readStdin("--body", { trim: false });
249510
- return piped.trim() ? piped : undefined;
249617
+ return flag;
249511
249618
  }
249512
249619
 
249513
249620
  // src/cli/commands/api/catalog.ts
249514
249621
  async function catalogAction(ctx, area, options) {
249515
249622
  const { spec } = await loadSpecTask(ctx, options.refresh);
249516
- const operations = listOperations(spec).filter((op) => !options.readOnly || op.readOnly);
249623
+ const operations = listOperations(spec);
249624
+ const readOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
249517
249625
  if (area === undefined) {
249518
- return { stdout: formatJson(catalogIndex(operations)) };
249626
+ return { stdout: formatJson(catalogIndex(readOnly(operations))) };
249519
249627
  }
249520
- const inArea = operationsInArea(operations, area);
249521
- return {
249522
- stdout: formatJson({
249523
- area,
249524
- operations: inArea.map(toOperationSummary),
249525
- total: inArea.length
249526
- })
249527
- };
249628
+ const inArea = readOnly(operationsInArea(operations, area));
249629
+ return { stdout: formatJson(areaListing(area, inArea)) };
249528
249630
  }
249529
249631
  function getApiCatalogCommand() {
249530
249632
  return new Base44Command("catalog", {
@@ -249540,6 +249642,10 @@ async function findOperation(ctx, method, path, refresh) {
249540
249642
  if (!op) {
249541
249643
  throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
249542
249644
  hints: [
249645
+ {
249646
+ message: "The cached spec may predate this route; fetch it again",
249647
+ command: "base44 api fetch <METHOD> <path> --help --refresh"
249648
+ },
249543
249649
  {
249544
249650
  message: "Find the operation and its path template",
249545
249651
  command: 'base44 api search "<what you want to do>"'
@@ -249559,7 +249665,7 @@ var TEXT_CONTENT_TYPES = [
249559
249665
  function isText(contentType) {
249560
249666
  return !contentType || TEXT_CONTENT_TYPES.some((hint) => contentType.toLowerCase().includes(hint));
249561
249667
  }
249562
- async function formatResponse({ status, contentType, body }, output) {
249668
+ async function formatResponse({ status, contentType, body }, output, jsonMode) {
249563
249669
  if (output !== undefined) {
249564
249670
  await writeFile(output, body);
249565
249671
  return formatJson({ status, contentType, bytes: body.length, output });
@@ -249568,12 +249674,20 @@ async function formatResponse({ status, contentType, body }, output) {
249568
249674
  return formatJson({ status });
249569
249675
  }
249570
249676
  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.`);
249677
+ return formatJson({
249678
+ status,
249679
+ contentType,
249680
+ bytes: body.length,
249681
+ note: "Binary body not printed; add --output <file> to save it."
249682
+ });
249572
249683
  }
249573
249684
  const text = new TextDecoder().decode(body);
249574
249685
  try {
249575
249686
  return formatJson(JSON.parse(text));
249576
249687
  } catch {
249688
+ if (jsonMode) {
249689
+ return formatJson({ status, contentType, body: text });
249690
+ }
249577
249691
  return text.endsWith(`
249578
249692
  `) ? text : `${text}
249579
249693
  `;
@@ -249582,7 +249696,8 @@ async function formatResponse({ status, contentType, body }, output) {
249582
249696
  async function fetchAction(ctx, methodArg, path, options, command) {
249583
249697
  if (!methodArg || !path) {
249584
249698
  if (options.help) {
249585
- return { stdout: command.helpInformation() };
249699
+ const usage = command.helpInformation();
249700
+ return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
249586
249701
  }
249587
249702
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249588
249703
  }
@@ -249597,19 +249712,28 @@ async function fetchAction(ctx, methodArg, path, options, command) {
249597
249712
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249598
249713
  }
249599
249714
  }
249715
+ ctx.errorReporter.setContext({
249716
+ command: {
249717
+ name: "api fetch",
249718
+ args: [method, path.split("?", 1)[0] ?? ""],
249719
+ options: { ...options, body: options.body && "[not reported]" }
249720
+ }
249721
+ });
249600
249722
  await ensureAuth(ctx);
249601
- const body = await readRequestBody(method, options.body);
249723
+ const body = await readRequestBody(options.body, ctx.log);
249602
249724
  const response = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), {
249603
249725
  successMessage: `Called ${method} ${path}`,
249604
249726
  errorMessage: "Request failed"
249605
249727
  });
249606
- return { stdout: await formatResponse(response, options.output) };
249728
+ return {
249729
+ stdout: await formatResponse(response, options.output, ctx.jsonMode)
249730
+ };
249607
249731
  }
249608
249732
  function getApiFetchCommand() {
249609
249733
  return new Base44Command("fetch", {
249610
249734
  requireAuth: false,
249611
249735
  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);
249736
+ }).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
249737
  }
249614
249738
 
249615
249739
  // src/cli/commands/api/grep.ts
@@ -249624,15 +249748,18 @@ async function grepAction(ctx, pattern, options) {
249624
249748
  const limit = parseLimit(options.limit);
249625
249749
  assertValidRegex(pattern);
249626
249750
  const { spec } = await loadSpecTask(ctx, options.refresh);
249627
- const operations = listOperations(spec);
249751
+ let operations = listOperations(spec);
249628
249752
  if (options.area !== undefined) {
249629
- operationsInArea(operations, options.area);
249753
+ operations = operationsInArea(operations, options.area);
249754
+ }
249755
+ if (options.readOnly) {
249756
+ operations = operations.filter((op) => op.readOnly);
249630
249757
  }
249758
+ const narrowed = options.area !== undefined || options.readOnly === true;
249631
249759
  const hits = grepSpec(spec, operations, pattern, {
249632
- area: options.area,
249633
249760
  ignoreCase: options.ignoreCase,
249634
249761
  limit,
249635
- readOnly: options.readOnly
249762
+ schemas: !narrowed
249636
249763
  });
249637
249764
  return { stdout: formatJson(hits) };
249638
249765
  }
@@ -249640,7 +249767,7 @@ function getApiGrepCommand() {
249640
249767
  return new Base44Command("grep", {
249641
249768
  requireAuth: false,
249642
249769
  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);
249770
+ }).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
249771
  }
249645
249772
 
249646
249773
  // src/cli/commands/api/search.ts
@@ -273202,4 +273329,4 @@ export {
273202
273329
  runCLI
273203
273330
  };
273204
273331
 
273205
- //# debugId=C89C416C808E439E64756E2164756E21
273332
+ //# debugId=FB96E058A37AEBFF64756E2164756E21