@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 +2 -2
- package/dist/cli/index.js +217 -67
- package/dist/cli/index.js.map +14 -14
- package/package.json +1 -1
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
|
|
49
|
-
| `api fetch <METHOD> <path>` | Call any public Base44 API operation
|
|
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
|
|
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
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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 = {
|
|
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
|
|
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:
|
|
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
|
-
|
|
249134
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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
|
|
249278
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
249574
|
+
return cached;
|
|
249457
249575
|
}
|
|
249458
249576
|
const text = await downloadSpec();
|
|
249459
249577
|
const spec = parseSpec(text);
|
|
249460
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
249504
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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(
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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=
|
|
273355
|
+
//# debugId=47D4434C61AEF7C764756E2164756E21
|