@mx-space/cli 0.15.0 → 0.15.1
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 +1 -1
- package/dist/{Lexical.dev-Cck4n26y.mjs → Lexical.dev-BSvx45_E.mjs} +127 -94
- package/dist/{Lexical.node-D6wf2D5M.mjs → Lexical.node-kAh5GM2n.mjs} +1 -1
- package/dist/{Lexical.prod-DCwS1oTq.mjs → Lexical.prod-Bqwgb3ez.mjs} +4 -2
- package/dist/{LexicalClipboard.dev-CMkPHV7O.mjs → LexicalClipboard.dev-BWU3KXIa.mjs} +18 -14
- package/dist/{LexicalClipboard.node-m4nZ7IYw.mjs → LexicalClipboard.node-BygAdNdF.mjs} +1 -1
- package/dist/{LexicalClipboard.prod-B_rN1vE1.mjs → LexicalClipboard.prod-BtMuKNyT.mjs} +10 -10
- package/dist/{LexicalCodeCore.dev-DyJw3i8V.mjs → LexicalCodeCore.dev-CD2xgvDs.mjs} +43 -25
- package/dist/{LexicalCodeCore.prod-DPXLHQLF.mjs → LexicalCodeCore.prod-Bl6FFMc7.mjs} +6 -6
- package/dist/{LexicalDragon.dev-ZkNfMwrE.mjs → LexicalDragon.dev-BwdYhm4K.mjs} +2 -2
- package/dist/{LexicalDragon.node-Ds9oLUFh.mjs → LexicalDragon.node-CpJhkCVV.mjs} +1 -1
- package/dist/{LexicalDragon.prod-B58ic2av.mjs → LexicalDragon.prod-CvXmWwo1.mjs} +2 -2
- package/dist/{LexicalExtension.dev-DvwHs1Xv.mjs → LexicalExtension.dev-LcRLXI5Z.mjs} +25 -13
- package/dist/{LexicalExtension.node-5OymZQfy.mjs → LexicalExtension.node-BwJt2LXV.mjs} +1 -1
- package/dist/{LexicalExtension.prod-Ce0T5smQ.mjs → LexicalExtension.prod-lg8_33-H.mjs} +16 -13
- package/dist/{LexicalHeadless.dev-DA0WldSR.mjs → LexicalHeadless.dev-BeUbKBes.mjs} +1 -1
- package/dist/{LexicalHeadless.prod-1kQgKB6c.mjs → LexicalHeadless.prod-4gbIA8HM.mjs} +1 -1
- package/dist/{LexicalHtml.dev-BDB7CUrx.mjs → LexicalHtml.dev-BLdZWTCJ.mjs} +20 -14
- package/dist/{LexicalHtml.node-DpVNt7It.mjs → LexicalHtml.node-BeuJMvvt.mjs} +1 -1
- package/dist/{LexicalHtml.prod-HkxM5scw.mjs → LexicalHtml.prod-CHUyCocN.mjs} +4 -4
- package/dist/{LexicalLink.dev-C5zNJlrm.mjs → LexicalLink.dev-DgsFRqw0.mjs} +28 -21
- package/dist/{LexicalLink.prod-Bkt9hQAt.mjs → LexicalLink.prod-CkXkeKY2.mjs} +6 -5
- package/dist/{LexicalList.dev-B7VgME-m.mjs → LexicalList.dev-OOms3kQi.mjs} +4 -4
- package/dist/{LexicalList.prod-B8c7TDjH.mjs → LexicalList.prod-DzMBeqHn.mjs} +4 -4
- package/dist/{LexicalMarkdown.dev-B5z9kLbV.mjs → LexicalMarkdown.dev-DJLKbZtD.mjs} +40 -29
- package/dist/{LexicalMarkdown.prod-wKzw7FFH.mjs → LexicalMarkdown.prod-Cp21kDCU.mjs} +10 -7
- package/dist/{LexicalRichText.dev-CUd6Li5F.mjs → LexicalRichText.dev-0rkAGjUf.mjs} +15 -11
- package/dist/{LexicalRichText.node-BKfaQ-CH.mjs → LexicalRichText.node-Cd-BySPE.mjs} +4 -4
- package/dist/{LexicalRichText.prod-SBewjJHx.mjs → LexicalRichText.prod-DTQiEr8C.mjs} +17 -11
- package/dist/{LexicalSelection.dev-D27JOCqj.mjs → LexicalSelection.dev-Bi0VlUEv.mjs} +28 -24
- package/dist/{LexicalSelection.node-DBEwPjBu.mjs → LexicalSelection.node-t2U46EF_.mjs} +1 -1
- package/dist/{LexicalSelection.prod-OaYhXHOL.mjs → LexicalSelection.prod-CrFG111g.mjs} +2 -2
- package/dist/{LexicalTable.dev-6IFFOAE0.mjs → LexicalTable.dev-D-sFhO-o.mjs} +33 -28
- package/dist/{LexicalTable.prod-2CaLZ7fH.mjs → LexicalTable.prod-DwYaa_dN.mjs} +10 -9
- package/dist/{LexicalUtils.dev-DJA7J_7v.mjs → LexicalUtils.dev-Q2q3-UDM.mjs} +8 -5
- package/dist/{LexicalUtils.node-Df9oPTlA.mjs → LexicalUtils.node-Dl7OvqJV.mjs} +1 -1
- package/dist/{LexicalUtils.prod-Bb7V4Ewg.mjs → LexicalUtils.prod-CBnq_iEV.mjs} +7 -6
- package/dist/bin/mxs.mjs +1 -1
- package/dist/esm-CNZ7kdTg.mjs +2 -0
- package/dist/{esm-DLzrv7gD.mjs → esm-ZXjJmLEC.mjs} +257 -260
- package/dist/index.mjs +1 -1
- package/dist/{mxs-BIRW5Axj.mjs → mxs-DC9zR3f2.mjs} +759 -539
- package/dist/{rolldown-runtime-JspESFgx.mjs → rolldown-runtime-B4iAMlE-.mjs} +1 -1
- package/dist/src/bin/mxs.d.ts +2 -0
- package/dist/src/bin/mxs.js +310 -0
- package/dist/src/cli/ai/_poll.d.ts +12 -0
- package/dist/src/cli/ai/_poll.js +38 -0
- package/dist/src/cli/ai/_resolve.d.ts +8 -0
- package/dist/src/cli/ai/_resolve.js +27 -0
- package/dist/src/cli/ai/index.d.ts +127 -0
- package/dist/src/cli/ai/index.js +46 -0
- package/dist/src/cli/ai/insights/by-article.d.ts +10 -0
- package/dist/src/cli/ai/insights/by-article.js +21 -0
- package/dist/src/cli/ai/insights/delete.d.ts +7 -0
- package/dist/src/cli/ai/insights/delete.js +18 -0
- package/dist/src/cli/ai/insights/edit.d.ts +8 -0
- package/dist/src/cli/ai/insights/edit.js +54 -0
- package/dist/src/cli/ai/insights/get.d.ts +6 -0
- package/dist/src/cli/ai/insights/get.js +11 -0
- package/dist/src/cli/ai/insights/index.d.ts +30 -0
- package/dist/src/cli/ai/insights/index.js +17 -0
- package/dist/src/cli/ai/insights/list.d.ts +10 -0
- package/dist/src/cli/ai/insights/list.js +20 -0
- package/dist/src/cli/ai/insights/refresh.d.ts +10 -0
- package/dist/src/cli/ai/insights/refresh.js +25 -0
- package/dist/src/cli/ai/insights/translate.d.ts +10 -0
- package/dist/src/cli/ai/insights/translate.js +25 -0
- package/dist/src/cli/ai/overview/by-article.d.ts +7 -0
- package/dist/src/cli/ai/overview/by-article.js +15 -0
- package/dist/src/cli/ai/overview/index.d.ts +11 -0
- package/dist/src/cli/ai/overview/index.js +4 -0
- package/dist/src/cli/ai/overview/list.d.ts +10 -0
- package/dist/src/cli/ai/overview/list.js +20 -0
- package/dist/src/cli/ai/summary/by-article.d.ts +10 -0
- package/dist/src/cli/ai/summary/by-article.js +21 -0
- package/dist/src/cli/ai/summary/delete.d.ts +7 -0
- package/dist/src/cli/ai/summary/delete.js +18 -0
- package/dist/src/cli/ai/summary/edit.d.ts +8 -0
- package/dist/src/cli/ai/summary/edit.js +54 -0
- package/dist/src/cli/ai/summary/get.d.ts +6 -0
- package/dist/src/cli/ai/summary/get.js +11 -0
- package/dist/src/cli/ai/summary/index.d.ts +30 -0
- package/dist/src/cli/ai/summary/index.js +9 -0
- package/dist/src/cli/ai/summary/list.d.ts +10 -0
- package/dist/src/cli/ai/summary/list.js +20 -0
- package/dist/src/cli/ai/summary/regen.d.ts +10 -0
- package/dist/src/cli/ai/summary/regen.js +25 -0
- package/dist/src/cli/ai/summary/translate.d.ts +10 -0
- package/dist/src/cli/ai/summary/translate.js +25 -0
- package/dist/src/cli/ai/translate/by-article.d.ts +9 -0
- package/dist/src/cli/ai/translate/by-article.js +19 -0
- package/dist/src/cli/ai/translate/delete.d.ts +7 -0
- package/dist/src/cli/ai/translate/delete.js +18 -0
- package/dist/src/cli/ai/translate/edit.d.ts +8 -0
- package/dist/src/cli/ai/translate/edit.js +97 -0
- package/dist/src/cli/ai/translate/entries/delete.d.ts +7 -0
- package/dist/src/cli/ai/translate/entries/delete.js +18 -0
- package/dist/src/cli/ai/translate/entries/edit.d.ts +8 -0
- package/dist/src/cli/ai/translate/entries/edit.js +73 -0
- package/dist/src/cli/ai/translate/entries/generate.d.ts +7 -0
- package/dist/src/cli/ai/translate/entries/generate.js +15 -0
- package/dist/src/cli/ai/translate/entries/index.d.ts +17 -0
- package/dist/src/cli/ai/translate/entries/index.js +6 -0
- package/dist/src/cli/ai/translate/entries/list.d.ts +10 -0
- package/dist/src/cli/ai/translate/entries/list.js +20 -0
- package/dist/src/cli/ai/translate/get.d.ts +6 -0
- package/dist/src/cli/ai/translate/get.js +11 -0
- package/dist/src/cli/ai/translate/index.d.ts +40 -0
- package/dist/src/cli/ai/translate/index.js +19 -0
- package/dist/src/cli/ai/translate/languages.d.ts +7 -0
- package/dist/src/cli/ai/translate/languages.js +15 -0
- package/dist/src/cli/ai/translate/list.d.ts +9 -0
- package/dist/src/cli/ai/translate/list.js +19 -0
- package/dist/src/cli/ai/translate/run.d.ts +10 -0
- package/dist/src/cli/ai/translate/run.js +31 -0
- package/dist/src/cli/ai/tts/by-article.d.ts +7 -0
- package/dist/src/cli/ai/tts/by-article.js +15 -0
- package/dist/src/cli/ai/tts/delete.d.ts +7 -0
- package/dist/src/cli/ai/tts/delete.js +18 -0
- package/dist/src/cli/ai/tts/index.d.ts +22 -0
- package/dist/src/cli/ai/tts/index.js +7 -0
- package/dist/src/cli/ai/tts/list.d.ts +10 -0
- package/dist/src/cli/ai/tts/list.js +20 -0
- package/dist/src/cli/ai/tts/run.d.ts +10 -0
- package/dist/src/cli/ai/tts/run.js +25 -0
- package/dist/src/cli/ai/tts/voices.d.ts +7 -0
- package/dist/src/cli/ai/tts/voices.js +12 -0
- package/dist/src/cli/ai/views.d.ts +3 -0
- package/dist/src/cli/ai/views.js +45 -0
- package/dist/src/cli/auth/index.d.ts +6 -0
- package/dist/src/cli/auth/index.js +22 -0
- package/dist/src/cli/auth/login.d.ts +11 -0
- package/dist/src/cli/auth/login.js +168 -0
- package/dist/src/cli/auth/logout.d.ts +6 -0
- package/dist/src/cli/auth/logout.js +21 -0
- package/dist/src/cli/auth/status.d.ts +4 -0
- package/dist/src/cli/auth/status.js +31 -0
- package/dist/src/cli/auth/view.d.ts +25 -0
- package/dist/src/cli/auth/view.js +46 -0
- package/dist/src/cli/auth/whoami.d.ts +7 -0
- package/dist/src/cli/auth/whoami.js +44 -0
- package/dist/src/cli/category/create.d.ts +10 -0
- package/dist/src/cli/category/create.js +24 -0
- package/dist/src/cli/category/delete.d.ts +8 -0
- package/dist/src/cli/category/delete.js +21 -0
- package/dist/src/cli/category/get.d.ts +6 -0
- package/dist/src/cli/category/get.js +11 -0
- package/dist/src/cli/category/index.d.ts +20 -0
- package/dist/src/cli/category/index.js +41 -0
- package/dist/src/cli/category/list.d.ts +4 -0
- package/dist/src/cli/category/list.js +10 -0
- package/dist/src/cli/category/update.d.ts +12 -0
- package/dist/src/cli/category/update.js +34 -0
- package/dist/src/cli/comment/_flags.d.ts +28 -0
- package/dist/src/cli/comment/_flags.js +48 -0
- package/dist/src/cli/comment/approve.d.ts +9 -0
- package/dist/src/cli/comment/approve.js +23 -0
- package/dist/src/cli/comment/delete.d.ts +9 -0
- package/dist/src/cli/comment/delete.js +24 -0
- package/dist/src/cli/comment/get.d.ts +6 -0
- package/dist/src/cli/comment/get.js +12 -0
- package/dist/src/cli/comment/index.d.ts +34 -0
- package/dist/src/cli/comment/index.js +53 -0
- package/dist/src/cli/comment/list.d.ts +9 -0
- package/dist/src/cli/comment/list.js +20 -0
- package/dist/src/cli/comment/reject.d.ts +9 -0
- package/dist/src/cli/comment/reject.js +23 -0
- package/dist/src/cli/comment/reply.d.ts +9 -0
- package/dist/src/cli/comment/reply.js +31 -0
- package/dist/src/cli/comment/unread.d.ts +7 -0
- package/dist/src/cli/comment/unread.js +21 -0
- package/dist/src/cli/comment/view.d.ts +3 -0
- package/dist/src/cli/comment/view.js +197 -0
- package/dist/src/cli/config/edit.d.ts +5 -0
- package/dist/src/cli/config/edit.js +36 -0
- package/dist/src/cli/config/get.d.ts +6 -0
- package/dist/src/cli/config/get.js +11 -0
- package/dist/src/cli/config/index.d.ts +10 -0
- package/dist/src/cli/config/index.js +22 -0
- package/dist/src/cli/config/list.d.ts +4 -0
- package/dist/src/cli/config/list.js +10 -0
- package/dist/src/cli/config/set.d.ts +9 -0
- package/dist/src/cli/config/set.js +48 -0
- package/dist/src/cli/draft/_shared.d.ts +27 -0
- package/dist/src/cli/draft/_shared.js +85 -0
- package/dist/src/cli/draft/create.d.ts +21 -0
- package/dist/src/cli/draft/create.js +34 -0
- package/dist/src/cli/draft/delete.d.ts +7 -0
- package/dist/src/cli/draft/delete.js +20 -0
- package/dist/src/cli/draft/get.d.ts +6 -0
- package/dist/src/cli/draft/get.js +11 -0
- package/dist/src/cli/draft/index.d.ts +54 -0
- package/dist/src/cli/draft/index.js +42 -0
- package/dist/src/cli/draft/list.d.ts +11 -0
- package/dist/src/cli/draft/list.js +23 -0
- package/dist/src/cli/draft/publish.d.ts +8 -0
- package/dist/src/cli/draft/publish.js +64 -0
- package/dist/src/cli/draft/update.d.ts +22 -0
- package/dist/src/cli/draft/update.js +29 -0
- package/dist/src/cli/file/_shared.d.ts +6 -0
- package/dist/src/cli/file/_shared.js +5 -0
- package/dist/src/cli/file/delete.d.ts +8 -0
- package/dist/src/cli/file/delete.js +21 -0
- package/dist/src/cli/file/index.d.ts +19 -0
- package/dist/src/cli/file/index.js +33 -0
- package/dist/src/cli/file/list.d.ts +6 -0
- package/dist/src/cli/file/list.js +11 -0
- package/dist/src/cli/file/rename.d.ts +8 -0
- package/dist/src/cli/file/rename.js +16 -0
- package/dist/src/cli/file/upload.d.ts +9 -0
- package/dist/src/cli/file/upload.js +32 -0
- package/dist/src/cli/help/index.d.ts +62 -0
- package/dist/src/cli/help/index.js +276 -0
- package/dist/src/cli/help/registry.d.ts +28 -0
- package/dist/src/cli/help/registry.js +29 -0
- package/dist/src/cli/note/_flags.d.ts +66 -0
- package/dist/src/cli/note/_flags.js +73 -0
- package/dist/src/cli/note/create.d.ts +23 -0
- package/dist/src/cli/note/create.js +25 -0
- package/dist/src/cli/note/delete.d.ts +8 -0
- package/dist/src/cli/note/delete.js +21 -0
- package/dist/src/cli/note/edit.d.ts +28 -0
- package/dist/src/cli/note/edit.js +114 -0
- package/dist/src/cli/note/get.d.ts +6 -0
- package/dist/src/cli/note/get.js +29 -0
- package/dist/src/cli/note/index.d.ts +77 -0
- package/dist/src/cli/note/index.js +63 -0
- package/dist/src/cli/note/list.d.ts +10 -0
- package/dist/src/cli/note/list.js +22 -0
- package/dist/src/cli/note/publish.d.ts +7 -0
- package/dist/src/cli/note/publish.js +17 -0
- package/dist/src/cli/note/unpublish.d.ts +7 -0
- package/dist/src/cli/note/unpublish.js +17 -0
- package/dist/src/cli/note/update.d.ts +25 -0
- package/dist/src/cli/note/update.js +36 -0
- package/dist/src/cli/note/view.d.ts +3 -0
- package/dist/src/cli/note/view.js +162 -0
- package/dist/src/cli/page/create.d.ts +41 -0
- package/dist/src/cli/page/create.js +56 -0
- package/dist/src/cli/page/delete.d.ts +7 -0
- package/dist/src/cli/page/delete.js +37 -0
- package/dist/src/cli/page/edit.d.ts +19 -0
- package/dist/src/cli/page/edit.js +117 -0
- package/dist/src/cli/page/get.d.ts +6 -0
- package/dist/src/cli/page/get.js +16 -0
- package/dist/src/cli/page/index.d.ts +44 -0
- package/dist/src/cli/page/index.js +38 -0
- package/dist/src/cli/page/list.d.ts +4 -0
- package/dist/src/cli/page/list.js +10 -0
- package/dist/src/cli/page/update.d.ts +16 -0
- package/dist/src/cli/page/update.js +48 -0
- package/dist/src/cli/page/view.d.ts +2 -0
- package/dist/src/cli/page/view.js +79 -0
- package/dist/src/cli/post/_flags.d.ts +66 -0
- package/dist/src/cli/post/_flags.js +96 -0
- package/dist/src/cli/post/apply.d.ts +7 -0
- package/dist/src/cli/post/apply.js +70 -0
- package/dist/src/cli/post/create.d.ts +21 -0
- package/dist/src/cli/post/create.js +24 -0
- package/dist/src/cli/post/delete.d.ts +8 -0
- package/dist/src/cli/post/delete.js +21 -0
- package/dist/src/cli/post/edit.d.ts +26 -0
- package/dist/src/cli/post/edit.js +115 -0
- package/dist/src/cli/post/get.d.ts +7 -0
- package/dist/src/cli/post/get.js +15 -0
- package/dist/src/cli/post/index.d.ts +91 -0
- package/dist/src/cli/post/index.js +73 -0
- package/dist/src/cli/post/list.d.ts +10 -0
- package/dist/src/cli/post/list.js +23 -0
- package/dist/src/cli/post/publish.d.ts +7 -0
- package/dist/src/cli/post/publish.js +17 -0
- package/dist/src/cli/post/stage.d.ts +23 -0
- package/dist/src/cli/post/stage.js +55 -0
- package/dist/src/cli/post/unpublish.d.ts +7 -0
- package/dist/src/cli/post/unpublish.js +17 -0
- package/dist/src/cli/post/update.d.ts +23 -0
- package/dist/src/cli/post/update.js +38 -0
- package/dist/src/cli/post/view.d.ts +3 -0
- package/dist/src/cli/post/view.js +150 -0
- package/dist/src/cli/preview/index.d.ts +13 -0
- package/dist/src/cli/preview/index.js +226 -0
- package/dist/src/cli/profile/index.d.ts +14 -0
- package/dist/src/cli/profile/index.js +36 -0
- package/dist/src/cli/profile/ls.d.ts +5 -0
- package/dist/src/cli/profile/ls.js +26 -0
- package/dist/src/cli/profile/mark.d.ts +9 -0
- package/dist/src/cli/profile/mark.js +23 -0
- package/dist/src/cli/profile/rm.d.ts +12 -0
- package/dist/src/cli/profile/rm.js +50 -0
- package/dist/src/cli/profile/show.d.ts +9 -0
- package/dist/src/cli/profile/show.js +40 -0
- package/dist/src/cli/profile/use.d.ts +6 -0
- package/dist/src/cli/profile/use.js +11 -0
- package/dist/src/cli/profile/view.d.ts +8 -0
- package/dist/src/cli/profile/view.js +21 -0
- package/dist/src/cli/project/_flags.d.ts +56 -0
- package/dist/src/cli/project/_flags.js +130 -0
- package/dist/src/cli/project/create.d.ts +17 -0
- package/dist/src/cli/project/create.js +25 -0
- package/dist/src/cli/project/delete.d.ts +8 -0
- package/dist/src/cli/project/delete.js +22 -0
- package/dist/src/cli/project/edit.d.ts +11 -0
- package/dist/src/cli/project/edit.js +61 -0
- package/dist/src/cli/project/get.d.ts +7 -0
- package/dist/src/cli/project/get.js +14 -0
- package/dist/src/cli/project/index.d.ts +43 -0
- package/dist/src/cli/project/index.js +52 -0
- package/dist/src/cli/project/list.d.ts +8 -0
- package/dist/src/cli/project/list.js +19 -0
- package/dist/src/cli/project/update.d.ts +18 -0
- package/dist/src/cli/project/update.js +24 -0
- package/dist/src/cli/project/view-cmd.d.ts +7 -0
- package/dist/src/cli/project/view-cmd.js +15 -0
- package/dist/src/cli/project/view.d.ts +3 -0
- package/dist/src/cli/project/view.js +102 -0
- package/dist/src/cli/render/codehighlight.d.ts +8 -0
- package/dist/src/cli/render/codehighlight.js +264 -0
- package/dist/src/cli/render/envelope.d.ts +7 -0
- package/dist/src/cli/render/envelope.js +23 -0
- package/dist/src/cli/render/frontmatter.d.ts +8 -0
- package/dist/src/cli/render/frontmatter.js +50 -0
- package/dist/src/cli/render/helpers.d.ts +2 -0
- package/dist/src/cli/render/helpers.js +11 -0
- package/dist/src/cli/render/index.d.ts +7 -0
- package/dist/src/cli/render/index.js +10 -0
- package/dist/src/cli/render/lexical/blocks.d.ts +19 -0
- package/dist/src/cli/render/lexical/blocks.js +208 -0
- package/dist/src/cli/render/lexical/code.d.ts +2 -0
- package/dist/src/cli/render/lexical/code.js +22 -0
- package/dist/src/cli/render/lexical/embeds.d.ts +6 -0
- package/dist/src/cli/render/lexical/embeds.js +51 -0
- package/dist/src/cli/render/lexical/index.d.ts +9 -0
- package/dist/src/cli/render/lexical/index.js +25 -0
- package/dist/src/cli/render/lexical/inlines.d.ts +17 -0
- package/dist/src/cli/render/lexical/inlines.js +76 -0
- package/dist/src/cli/render/lexical/parser.d.ts +10 -0
- package/dist/src/cli/render/lexical/parser.js +64 -0
- package/dist/src/cli/render/lexical/walker.d.ts +21 -0
- package/dist/src/cli/render/lexical/walker.js +51 -0
- package/dist/src/cli/render/markdown.d.ts +18 -0
- package/dist/src/cli/render/markdown.js +196 -0
- package/dist/src/cli/render/metadata-block.d.ts +14 -0
- package/dist/src/cli/render/metadata-block.js +50 -0
- package/dist/src/cli/skill/all.d.ts +4 -0
- package/dist/src/cli/skill/all.js +11 -0
- package/dist/src/cli/skill/get.d.ts +6 -0
- package/dist/src/cli/skill/get.js +12 -0
- package/dist/src/cli/skill/index.d.ts +10 -0
- package/dist/src/cli/skill/index.js +34 -0
- package/dist/src/cli/skill/list.d.ts +4 -0
- package/dist/src/cli/skill/list.js +11 -0
- package/dist/src/cli/skill/search.d.ts +6 -0
- package/dist/src/cli/skill/search.js +12 -0
- package/dist/src/cli/skill/views.d.ts +6 -0
- package/dist/src/cli/skill/views.js +90 -0
- package/dist/src/cli/snippet/_flags.d.ts +57 -0
- package/dist/src/cli/snippet/_flags.js +123 -0
- package/dist/src/cli/snippet/_resolve.d.ts +4 -0
- package/dist/src/cli/snippet/_resolve.js +32 -0
- package/dist/src/cli/snippet/_sync.d.ts +5 -0
- package/dist/src/cli/snippet/_sync.js +54 -0
- package/dist/src/cli/snippet/create.d.ts +19 -0
- package/dist/src/cli/snippet/create.js +35 -0
- package/dist/src/cli/snippet/delete.d.ts +8 -0
- package/dist/src/cli/snippet/delete.js +28 -0
- package/dist/src/cli/snippet/edit.d.ts +7 -0
- package/dist/src/cli/snippet/edit.js +29 -0
- package/dist/src/cli/snippet/get.d.ts +6 -0
- package/dist/src/cli/snippet/get.js +12 -0
- package/dist/src/cli/snippet/index.d.ts +43 -0
- package/dist/src/cli/snippet/index.js +58 -0
- package/dist/src/cli/snippet/list.d.ts +9 -0
- package/dist/src/cli/snippet/list.js +20 -0
- package/dist/src/cli/snippet/pull.d.ts +8 -0
- package/dist/src/cli/snippet/pull.js +33 -0
- package/dist/src/cli/snippet/push.d.ts +10 -0
- package/dist/src/cli/snippet/push.js +31 -0
- package/dist/src/cli/snippet/update.d.ts +8 -0
- package/dist/src/cli/snippet/update.js +16 -0
- package/dist/src/cli/topic/create.d.ts +10 -0
- package/dist/src/cli/topic/create.js +24 -0
- package/dist/src/cli/topic/delete.d.ts +7 -0
- package/dist/src/cli/topic/delete.js +37 -0
- package/dist/src/cli/topic/get.d.ts +6 -0
- package/dist/src/cli/topic/get.js +15 -0
- package/dist/src/cli/topic/index.d.ts +20 -0
- package/dist/src/cli/topic/index.js +32 -0
- package/dist/src/cli/topic/list.d.ts +4 -0
- package/dist/src/cli/topic/list.js +10 -0
- package/dist/src/cli/topic/update.d.ts +11 -0
- package/dist/src/cli/topic/update.js +51 -0
- package/dist/src/cli/ui/index.d.ts +24 -0
- package/dist/src/cli/ui/index.js +83 -0
- package/dist/src/cli/update/index.d.ts +10 -0
- package/dist/src/cli/update/index.js +142 -0
- package/dist/src/domain/admin-link.d.ts +12 -0
- package/dist/src/domain/admin-link.js +45 -0
- package/dist/src/domain/content-spec.d.ts +20 -0
- package/dist/src/domain/content-spec.js +78 -0
- package/dist/src/domain/envelope-compat.d.ts +68 -0
- package/dist/src/domain/envelope-compat.js +121 -0
- package/dist/src/domain/envelope.d.ts +34 -0
- package/dist/src/domain/envelope.js +355 -0
- package/dist/src/domain/errors.d.ts +336 -0
- package/dist/src/domain/errors.js +239 -0
- package/dist/src/domain/gate.d.ts +14 -0
- package/dist/src/domain/gate.js +18 -0
- package/dist/src/domain/payload.d.ts +64 -0
- package/dist/src/domain/payload.js +237 -0
- package/dist/src/domain/preflight-guards.d.ts +54 -0
- package/dist/src/domain/preflight-guards.js +130 -0
- package/dist/src/domain/runtime-flags.d.ts +33 -0
- package/dist/src/domain/runtime-flags.js +166 -0
- package/dist/src/domain/schema/api-envelope.d.ts +67 -0
- package/dist/src/domain/schema/api-envelope.js +65 -0
- package/dist/src/domain/schema/category.d.ts +23 -0
- package/dist/src/domain/schema/category.js +19 -0
- package/dist/src/domain/schema/config.d.ts +13 -0
- package/dist/src/domain/schema/config.js +18 -0
- package/dist/src/domain/schema/note.d.ts +76 -0
- package/dist/src/domain/schema/note.js +35 -0
- package/dist/src/domain/schema/page.d.ts +40 -0
- package/dist/src/domain/schema/page.js +22 -0
- package/dist/src/domain/schema/post.d.ts +68 -0
- package/dist/src/domain/schema/post.js +35 -0
- package/dist/src/domain/schema/profile.d.ts +14 -0
- package/dist/src/domain/schema/profile.js +22 -0
- package/dist/src/domain/schema/topic.d.ts +24 -0
- package/dist/src/domain/schema/topic.js +16 -0
- package/dist/src/domain/version.d.ts +15 -0
- package/dist/src/domain/version.js +43 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +8 -0
- package/dist/src/layers/App.d.ts +30 -0
- package/dist/src/layers/App.js +39 -0
- package/dist/src/services/Ai/index.d.ts +13 -0
- package/dist/src/services/Ai/index.js +127 -0
- package/dist/src/services/Ai/overview.d.ts +7 -0
- package/dist/src/services/Ai/overview.js +11 -0
- package/dist/src/services/Ai/resources.d.ts +7 -0
- package/dist/src/services/Ai/resources.js +59 -0
- package/dist/src/services/Ai/shared.d.ts +2 -0
- package/dist/src/services/Ai/shared.js +11 -0
- package/dist/src/services/Ai/tasks.d.ts +8 -0
- package/dist/src/services/Ai/tasks.js +144 -0
- package/dist/src/services/Ai/types.d.ts +130 -0
- package/dist/src/services/Ai/types.js +1 -0
- package/dist/src/services/Api.d.ts +67 -0
- package/dist/src/services/Api.js +348 -0
- package/dist/src/services/Auth.d.ts +101 -0
- package/dist/src/services/Auth.js +402 -0
- package/dist/src/services/Backup.d.ts +8 -0
- package/dist/src/services/Backup.js +4 -0
- package/dist/src/services/Cache.d.ts +8 -0
- package/dist/src/services/Cache.js +4 -0
- package/dist/src/services/Comment.d.ts +48 -0
- package/dist/src/services/Comment.js +102 -0
- package/dist/src/services/Config.d.ts +95 -0
- package/dist/src/services/Config.js +359 -0
- package/dist/src/services/Editor.d.ts +28 -0
- package/dist/src/services/Editor.js +95 -0
- package/dist/src/services/Lexical.d.ts +27 -0
- package/dist/src/services/Lexical.js +56 -0
- package/dist/src/services/Migration.d.ts +31 -0
- package/dist/src/services/Migration.js +177 -0
- package/dist/src/services/Profile.d.ts +29 -0
- package/dist/src/services/Profile.js +115 -0
- package/dist/src/services/Renderer/content.d.ts +16 -0
- package/dist/src/services/Renderer/content.js +110 -0
- package/dist/src/services/Renderer/datetime.d.ts +38 -0
- package/dist/src/services/Renderer/datetime.js +147 -0
- package/dist/src/services/Renderer/errors.d.ts +3 -0
- package/dist/src/services/Renderer/errors.js +59 -0
- package/dist/src/services/Renderer/index.d.ts +13 -0
- package/dist/src/services/Renderer/index.js +11 -0
- package/dist/src/services/Renderer/lists.d.ts +1 -0
- package/dist/src/services/Renderer/lists.js +101 -0
- package/dist/src/services/Renderer/options.d.ts +10 -0
- package/dist/src/services/Renderer/options.js +13 -0
- package/dist/src/services/Renderer/primitives.d.ts +4 -0
- package/dist/src/services/Renderer/primitives.js +12 -0
- package/dist/src/services/Renderer/service.d.ts +35 -0
- package/dist/src/services/Renderer/service.js +123 -0
- package/dist/src/services/Renderer/view.d.ts +16 -0
- package/dist/src/services/Renderer/view.js +1 -0
- package/dist/src/services/Resolver.d.ts +47 -0
- package/dist/src/services/Resolver.js +269 -0
- package/dist/src/services/Skill.d.ts +29 -0
- package/dist/src/services/Skill.js +421 -0
- package/dist/src/services/UpdateNotifier.d.ts +162 -0
- package/dist/src/services/UpdateNotifier.js +572 -0
- package/dist/test/cli/ai/ai.test.d.ts +1 -0
- package/dist/test/cli/ai/ai.test.js +507 -0
- package/dist/test/cli/ai/verbs.test.d.ts +1 -0
- package/dist/test/cli/ai/verbs.test.js +235 -0
- package/dist/test/cli/auth/login.test.d.ts +1 -0
- package/dist/test/cli/auth/login.test.js +236 -0
- package/dist/test/cli/auth/logout-whoami.test.d.ts +1 -0
- package/dist/test/cli/auth/logout-whoami.test.js +124 -0
- package/dist/test/cli/auth/status.test.d.ts +1 -0
- package/dist/test/cli/auth/status.test.js +90 -0
- package/dist/test/cli/category/category.test.d.ts +1 -0
- package/dist/test/cli/category/category.test.js +175 -0
- package/dist/test/cli/comment/comment.test.d.ts +1 -0
- package/dist/test/cli/comment/comment.test.js +445 -0
- package/dist/test/cli/config/config.test.d.ts +1 -0
- package/dist/test/cli/config/config.test.js +281 -0
- package/dist/test/cli/edit-roundtrip.test.d.ts +1 -0
- package/dist/test/cli/edit-roundtrip.test.js +259 -0
- package/dist/test/cli/file/file.test.d.ts +1 -0
- package/dist/test/cli/file/file.test.js +185 -0
- package/dist/test/cli/help.test.d.ts +1 -0
- package/dist/test/cli/help.test.js +289 -0
- package/dist/test/cli/note/create.test.d.ts +1 -0
- package/dist/test/cli/note/create.test.js +155 -0
- package/dist/test/cli/note/list.test.d.ts +1 -0
- package/dist/test/cli/note/list.test.js +115 -0
- package/dist/test/cli/note/publish.test.d.ts +1 -0
- package/dist/test/cli/note/publish.test.js +123 -0
- package/dist/test/cli/page/page.test.d.ts +1 -0
- package/dist/test/cli/page/page.test.js +185 -0
- package/dist/test/cli/post/create.test.d.ts +1 -0
- package/dist/test/cli/post/create.test.js +172 -0
- package/dist/test/cli/post/list.test.d.ts +1 -0
- package/dist/test/cli/post/list.test.js +133 -0
- package/dist/test/cli/post/publish.test.d.ts +1 -0
- package/dist/test/cli/post/publish.test.js +139 -0
- package/dist/test/cli/post/stage-apply.test.d.ts +1 -0
- package/dist/test/cli/post/stage-apply.test.js +215 -0
- package/dist/test/cli/post/update.test.d.ts +1 -0
- package/dist/test/cli/post/update.test.js +160 -0
- package/dist/test/cli/post-note-crud.test.d.ts +1 -0
- package/dist/test/cli/post-note-crud.test.js +362 -0
- package/dist/test/cli/profile/ls.test.d.ts +1 -0
- package/dist/test/cli/profile/ls.test.js +93 -0
- package/dist/test/cli/profile/mark-use.test.d.ts +1 -0
- package/dist/test/cli/profile/mark-use.test.js +216 -0
- package/dist/test/cli/project-crud.test.d.ts +1 -0
- package/dist/test/cli/project-crud.test.js +315 -0
- package/dist/test/cli/render/lexical.test.d.ts +1 -0
- package/dist/test/cli/render/lexical.test.js +216 -0
- package/dist/test/cli/render/markdown.test.d.ts +1 -0
- package/dist/test/cli/render/markdown.test.js +39 -0
- package/dist/test/cli/snippet-crud.test.d.ts +1 -0
- package/dist/test/cli/snippet-crud.test.js +293 -0
- package/dist/test/cli/topic/topic.test.d.ts +1 -0
- package/dist/test/cli/topic/topic.test.js +181 -0
- package/dist/test/cli/update.test.d.ts +1 -0
- package/dist/test/cli/update.test.js +395 -0
- package/dist/test/domain/content-spec.test.d.ts +1 -0
- package/dist/test/domain/content-spec.test.js +126 -0
- package/dist/test/domain/envelope-compat.test.d.ts +1 -0
- package/dist/test/domain/envelope-compat.test.js +126 -0
- package/dist/test/domain/envelope.test.d.ts +1 -0
- package/dist/test/domain/envelope.test.js +149 -0
- package/dist/test/domain/errors.test.d.ts +1 -0
- package/dist/test/domain/errors.test.js +127 -0
- package/dist/test/domain/gate.test.d.ts +1 -0
- package/dist/test/domain/gate.test.js +128 -0
- package/dist/test/domain/payload.test.d.ts +1 -0
- package/dist/test/domain/payload.test.js +259 -0
- package/dist/test/helper/test-fs.d.ts +24 -0
- package/dist/test/helper/test-fs.js +161 -0
- package/dist/test/helper/test-http.d.ts +31 -0
- package/dist/test/helper/test-http.js +66 -0
- package/dist/test/integration/_helpers.d.ts +5 -0
- package/dist/test/integration/_helpers.js +24 -0
- package/dist/test/integration/cli-error-envelope.test.d.ts +1 -0
- package/dist/test/integration/cli-error-envelope.test.js +137 -0
- package/dist/test/integration/cli-help-render.test.d.ts +1 -0
- package/dist/test/integration/cli-help-render.test.js +149 -0
- package/dist/test/integration/cli-help.test.d.ts +1 -0
- package/dist/test/integration/cli-help.test.js +67 -0
- package/dist/test/integration/cli-post-list.test.d.ts +1 -0
- package/dist/test/integration/cli-post-list.test.js +140 -0
- package/dist/test/integration/cli-skill.test.d.ts +1 -0
- package/dist/test/integration/cli-skill.test.js +74 -0
- package/dist/test/integration/cli-version.test.d.ts +1 -0
- package/dist/test/integration/cli-version.test.js +37 -0
- package/dist/test/services/Api.test.d.ts +1 -0
- package/dist/test/services/Api.test.js +553 -0
- package/dist/test/services/Auth.test.d.ts +1 -0
- package/dist/test/services/Auth.test.js +650 -0
- package/dist/test/services/Config.test.d.ts +1 -0
- package/dist/test/services/Config.test.js +510 -0
- package/dist/test/services/Datetime.test.d.ts +1 -0
- package/dist/test/services/Datetime.test.js +113 -0
- package/dist/test/services/Editor.test.d.ts +1 -0
- package/dist/test/services/Editor.test.js +205 -0
- package/dist/test/services/Lexical.errors.test.d.ts +1 -0
- package/dist/test/services/Lexical.errors.test.js +60 -0
- package/dist/test/services/Lexical.test.d.ts +1 -0
- package/dist/test/services/Lexical.test.js +68 -0
- package/dist/test/services/Migration.test.d.ts +1 -0
- package/dist/test/services/Migration.test.js +376 -0
- package/dist/test/services/Profile.test.d.ts +1 -0
- package/dist/test/services/Profile.test.js +277 -0
- package/dist/test/services/Renderer.test.d.ts +1 -0
- package/dist/test/services/Renderer.test.js +538 -0
- package/dist/test/services/Resolver.test.d.ts +1 -0
- package/dist/test/services/Resolver.test.js +320 -0
- package/dist/test/services/Skill.test.d.ts +1 -0
- package/dist/test/services/Skill.test.js +261 -0
- package/dist/test/services/UpdateNotifier.spawn.test.d.ts +1 -0
- package/dist/test/services/UpdateNotifier.spawn.test.js +73 -0
- package/dist/test/services/UpdateNotifier.test.d.ts +1 -0
- package/dist/test/services/UpdateNotifier.test.js +912 -0
- package/dist/vendor/litexml/cli.mjs +19 -4
- package/dist/vendor/litexml/litexml-html-preview-client.css +98 -13
- package/dist/vendor/litexml/litexml-html-preview-client.js +5794 -4976
- package/dist/vendor/litexml/style.css +5 -5
- package/package.json +29 -26
- package/skills/safety.md +1 -1
- package/LICENSE +0 -33
- package/dist/esm-CDcJmHkG.mjs +0 -2
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { HttpClient, HttpClientRequest } from '@effect/platform';
|
|
2
|
+
import { Context, Effect, Layer } from 'effect';
|
|
3
|
+
import { AuthDenied, AuthExpired, AuthMissing, AuthProbe, Generic, NetworkDns, NetworkRefused, NetworkTimeout, } from '../domain/errors';
|
|
4
|
+
import { Config } from './Config';
|
|
5
|
+
export const SUPPORTED_API_VERSIONS = [3, 2];
|
|
6
|
+
export class Auth extends Context.Tag('Auth')() {
|
|
7
|
+
/** Build the Auth Layer; depends on `Config` and `HttpClient`. */
|
|
8
|
+
static Default = Layer.effect(Auth, Effect.gen(function* () {
|
|
9
|
+
const http = yield* HttpClient.HttpClient;
|
|
10
|
+
const config = yield* Config;
|
|
11
|
+
return makeAuthService(http, config);
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Implementation
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const TOKEN_EXPIRY_BUFFER_MS = 60_000;
|
|
18
|
+
export const isExpiringSoon = (cred, bufferMs = TOKEN_EXPIRY_BUFFER_MS) => cred.expires_at < Date.now() + bufferMs;
|
|
19
|
+
export const toCredentials = (resp) => ({
|
|
20
|
+
access_token: resp.access_token,
|
|
21
|
+
refresh_token: resp.refresh_token,
|
|
22
|
+
expires_at: Date.now() + resp.expires_in * 1000,
|
|
23
|
+
user: resp.user,
|
|
24
|
+
});
|
|
25
|
+
function mapTransportError(err, url) {
|
|
26
|
+
const cause = err;
|
|
27
|
+
const code = cause?.code ?? cause?.cause?.code;
|
|
28
|
+
if (cause?.name === 'AbortError' || code === 'ABORT_ERR') {
|
|
29
|
+
return new Generic({ message: 'request aborted', details: { url } });
|
|
30
|
+
}
|
|
31
|
+
if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {
|
|
32
|
+
let host = url;
|
|
33
|
+
try {
|
|
34
|
+
host = new URL(url).host;
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
return new NetworkDns({
|
|
38
|
+
host,
|
|
39
|
+
message: 'dns lookup failed',
|
|
40
|
+
details: { url },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (code === 'ECONNREFUSED') {
|
|
44
|
+
return new NetworkRefused({ url, message: 'connection refused' });
|
|
45
|
+
}
|
|
46
|
+
if (code === 'ETIMEDOUT' || code === 'UND_ERR_CONNECT_TIMEOUT') {
|
|
47
|
+
return new NetworkTimeout({ url, message: 'network request timed out' });
|
|
48
|
+
}
|
|
49
|
+
return new Generic({
|
|
50
|
+
message: cause?.message ?? `request failed: ${url}`,
|
|
51
|
+
details: { url, cause: code },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function jsonResponseBody(res) {
|
|
55
|
+
return res.json.pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
56
|
+
}
|
|
57
|
+
function makeAuthService(http, config) {
|
|
58
|
+
const sendJson = (url, method, body, headers) => Effect.gen(function* () {
|
|
59
|
+
let req = HttpClientRequest.make(method)(url, { headers });
|
|
60
|
+
if (body !== undefined && method !== 'GET') {
|
|
61
|
+
req = yield* HttpClientRequest.bodyJson(req, body).pipe(Effect.mapError((err) => new Generic({ message: 'failed to encode body', cause: err })));
|
|
62
|
+
}
|
|
63
|
+
return yield* http.execute(req).pipe(
|
|
64
|
+
// ResponseError is just a status filter — we don't apply filterStatusOk,
|
|
65
|
+
// so transport-level failures (RequestError) are what we map here.
|
|
66
|
+
Effect.catchTag('RequestError', (rerr) => Effect.fail(mapTransportError(rerr.cause ?? rerr, url))), Effect.catchTag('ResponseError', (rerr) => Effect.succeed(rerr.response)));
|
|
67
|
+
});
|
|
68
|
+
const probe = (apiUrl) => Effect.gen(function* () {
|
|
69
|
+
const candidates = [
|
|
70
|
+
...SUPPORTED_API_VERSIONS.map((v) => ({
|
|
71
|
+
prefix: `/api/v${v}/auth`,
|
|
72
|
+
version: v,
|
|
73
|
+
})),
|
|
74
|
+
{ prefix: '/auth', version: null },
|
|
75
|
+
];
|
|
76
|
+
let lastTransport = null;
|
|
77
|
+
const attempted = [];
|
|
78
|
+
for (const cand of candidates) {
|
|
79
|
+
const probeUrl = `${apiUrl}${cand.prefix}/ok`;
|
|
80
|
+
const result = yield* sendJson(probeUrl, 'GET', undefined, {
|
|
81
|
+
accept: 'application/json',
|
|
82
|
+
}).pipe(Effect.either);
|
|
83
|
+
if (result._tag === 'Left') {
|
|
84
|
+
lastTransport = result.left;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const res = result.right;
|
|
88
|
+
attempted.push({ url: probeUrl, status: res.status });
|
|
89
|
+
if (res.status >= 200 && res.status < 300) {
|
|
90
|
+
const apiVersion = cand.version ?? SUPPORTED_API_VERSIONS[0];
|
|
91
|
+
const apiBase = cand.prefix === '/auth' ? apiUrl : `${apiUrl}/api/v${apiVersion}`;
|
|
92
|
+
const authBase = `${apiUrl}${cand.prefix}`;
|
|
93
|
+
return { apiUrl, apiBase, authBase, apiVersion };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (lastTransport && lastTransport._tag !== 'Generic') {
|
|
97
|
+
return yield* Effect.fail(lastTransport);
|
|
98
|
+
}
|
|
99
|
+
const tried = attempted.length > 0
|
|
100
|
+
? attempted.map((a) => `${a.url} → ${a.status}`).join(', ')
|
|
101
|
+
: 'no responses';
|
|
102
|
+
return yield* Effect.fail(new AuthProbe({
|
|
103
|
+
message: 'cannot detect auth endpoint',
|
|
104
|
+
hint: `tried: ${tried}. supply the site root (e.g. https://blog.example.com), not the API path. verify the server is reachable and runs a supported API version (${SUPPORTED_API_VERSIONS.join(', ')}).`,
|
|
105
|
+
}));
|
|
106
|
+
});
|
|
107
|
+
const requestDeviceCode = (authBase, clientId, scope = 'openid profile email') => Effect.gen(function* () {
|
|
108
|
+
const url = `${authBase}/device/code`;
|
|
109
|
+
const res = yield* sendJson(url, 'POST', { client_id: clientId, scope }, { 'content-type': 'application/json', accept: 'application/json' }).pipe(Effect.mapError((err) => {
|
|
110
|
+
if (err._tag === 'Generic')
|
|
111
|
+
return err;
|
|
112
|
+
// transport errors collapse into AuthDenied — matches legacy where
|
|
113
|
+
// network failure during device-code request surfaces as auth.denied.
|
|
114
|
+
return new AuthDenied({
|
|
115
|
+
message: 'device code request failed',
|
|
116
|
+
details: err,
|
|
117
|
+
});
|
|
118
|
+
}));
|
|
119
|
+
const body = yield* jsonResponseBody(res);
|
|
120
|
+
if (res.status >= 200 && res.status < 300) {
|
|
121
|
+
return body;
|
|
122
|
+
}
|
|
123
|
+
return yield* Effect.fail(new AuthDenied({
|
|
124
|
+
message: `device code request failed (${res.status})`,
|
|
125
|
+
details: body,
|
|
126
|
+
}));
|
|
127
|
+
});
|
|
128
|
+
const pollDeviceToken = (authBase, clientId, deviceCode, opts) => Effect.tryPromise({
|
|
129
|
+
try: async () => {
|
|
130
|
+
const url = `${authBase}/device/token`;
|
|
131
|
+
const deadline = Date.now() + opts.expiresInSec * 1000;
|
|
132
|
+
let intervalMs = Math.max(1, opts.intervalSec) * 1000;
|
|
133
|
+
while (Date.now() < deadline) {
|
|
134
|
+
if (opts.signal?.aborted) {
|
|
135
|
+
throw new AuthDenied({ message: 'aborted by user' });
|
|
136
|
+
}
|
|
137
|
+
await sleep(intervalMs, opts.signal);
|
|
138
|
+
const res = await fetchJson(url, {
|
|
139
|
+
method: 'POST',
|
|
140
|
+
headers: {
|
|
141
|
+
'content-type': 'application/json',
|
|
142
|
+
accept: 'application/json',
|
|
143
|
+
},
|
|
144
|
+
body: JSON.stringify({
|
|
145
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
146
|
+
device_code: deviceCode,
|
|
147
|
+
client_id: clientId,
|
|
148
|
+
}),
|
|
149
|
+
signal: opts.signal,
|
|
150
|
+
});
|
|
151
|
+
const body = res.body;
|
|
152
|
+
if (res.ok && body?.access_token) {
|
|
153
|
+
return body;
|
|
154
|
+
}
|
|
155
|
+
const err = body?.error;
|
|
156
|
+
if (err === 'authorization_pending') {
|
|
157
|
+
opts.onTick?.('pending');
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (err === 'slow_down') {
|
|
161
|
+
intervalMs += 5000;
|
|
162
|
+
opts.onTick?.('slow_down');
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (err === 'access_denied') {
|
|
166
|
+
throw new AuthDenied({
|
|
167
|
+
message: 'user denied the authorization request',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (err === 'expired_token') {
|
|
171
|
+
throw new AuthExpired({
|
|
172
|
+
message: 'device code expired before authorization completed',
|
|
173
|
+
hint: 'run `mxs auth login` again',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
throw new AuthDenied({
|
|
177
|
+
message: `device token request failed (${res.status})`,
|
|
178
|
+
details: body,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
throw new AuthExpired({
|
|
182
|
+
message: 'device authorization timed out',
|
|
183
|
+
hint: 'run `mxs auth login` again',
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
catch: (err) => {
|
|
187
|
+
if (err instanceof AuthDenied)
|
|
188
|
+
return err;
|
|
189
|
+
if (err instanceof AuthExpired)
|
|
190
|
+
return err;
|
|
191
|
+
return new Generic({
|
|
192
|
+
message: 'device token polling failed',
|
|
193
|
+
cause: err,
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
const refresh = (authBase, clientId, cred) => Effect.tryPromise({
|
|
198
|
+
try: async () => {
|
|
199
|
+
if (!cred.refresh_token) {
|
|
200
|
+
return refreshSessionToken(authBase, cred);
|
|
201
|
+
}
|
|
202
|
+
const res = await fetchJson(`${authBase}/token`, {
|
|
203
|
+
method: 'POST',
|
|
204
|
+
headers: {
|
|
205
|
+
'content-type': 'application/json',
|
|
206
|
+
accept: 'application/json',
|
|
207
|
+
},
|
|
208
|
+
body: JSON.stringify({
|
|
209
|
+
grant_type: 'refresh_token',
|
|
210
|
+
refresh_token: cred.refresh_token,
|
|
211
|
+
client_id: clientId,
|
|
212
|
+
}),
|
|
213
|
+
});
|
|
214
|
+
if (!res.ok)
|
|
215
|
+
return null;
|
|
216
|
+
const body = res.body;
|
|
217
|
+
if (!body?.access_token)
|
|
218
|
+
return null;
|
|
219
|
+
return {
|
|
220
|
+
access_token: body.access_token,
|
|
221
|
+
refresh_token: body.refresh_token ?? cred.refresh_token,
|
|
222
|
+
expires_at: Date.now() + body.expires_in * 1000,
|
|
223
|
+
user: body.user ?? cred.user,
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
catch: (err) => new Generic({ message: 'refresh failed', cause: err }),
|
|
227
|
+
});
|
|
228
|
+
const ensureFresh = (resolved) => Effect.gen(function* () {
|
|
229
|
+
if (!resolved.profileName) {
|
|
230
|
+
return yield* Effect.fail(new AuthMissing({
|
|
231
|
+
message: 'not authenticated',
|
|
232
|
+
hint: 'run `mxs auth login`',
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
235
|
+
const cred = yield* config.readProfileCredentials(resolved.profileName);
|
|
236
|
+
if (!cred) {
|
|
237
|
+
return yield* Effect.fail(new AuthMissing({
|
|
238
|
+
message: 'not authenticated',
|
|
239
|
+
hint: 'run `mxs auth login`',
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
if (!isExpiringSoon(cred))
|
|
243
|
+
return cred;
|
|
244
|
+
const refreshed = yield* refresh(resolved.authBase, resolved.clientId, cred);
|
|
245
|
+
if (!refreshed)
|
|
246
|
+
return cred;
|
|
247
|
+
yield* config.writeProfileCredentials(resolved.profileName, refreshed);
|
|
248
|
+
return refreshed;
|
|
249
|
+
});
|
|
250
|
+
const login = () => Effect.fail(new Generic({
|
|
251
|
+
message: 'Auth.login is a Wave 2 surface; compose probe + requestDeviceCode + pollDeviceToken explicitly',
|
|
252
|
+
}));
|
|
253
|
+
const logout = (name) => Effect.gen(function* () {
|
|
254
|
+
const target = name ??
|
|
255
|
+
(yield* config.resolve().pipe(Effect.map((r) => r.profileName), Effect.catchAll(() => Effect.succeed(null))));
|
|
256
|
+
if (!target)
|
|
257
|
+
return;
|
|
258
|
+
yield* config.deleteProfileCredentials(target);
|
|
259
|
+
});
|
|
260
|
+
const whoami = Effect.gen(function* () {
|
|
261
|
+
const resolved = yield* config.resolve().pipe(Effect.mapError((err) => new Generic({
|
|
262
|
+
message: 'failed to resolve config',
|
|
263
|
+
cause: err,
|
|
264
|
+
})));
|
|
265
|
+
const fresh = yield* ensureFresh(resolved);
|
|
266
|
+
return {
|
|
267
|
+
id: fresh.user?.id,
|
|
268
|
+
email: fresh.user?.email,
|
|
269
|
+
name: fresh.user?.name,
|
|
270
|
+
expiresAt: fresh.expires_at,
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
const status = Effect.gen(function* () {
|
|
274
|
+
const resolved = yield* config.resolve().pipe(Effect.mapError((err) => new Generic({
|
|
275
|
+
message: 'failed to resolve config',
|
|
276
|
+
cause: err,
|
|
277
|
+
})));
|
|
278
|
+
if (!resolved.profileName) {
|
|
279
|
+
return {
|
|
280
|
+
authenticated: false,
|
|
281
|
+
apiUrl: resolved.apiUrl,
|
|
282
|
+
profile: null,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
const cred = yield* config.readProfileCredentials(resolved.profileName);
|
|
286
|
+
if (!cred) {
|
|
287
|
+
return {
|
|
288
|
+
authenticated: false,
|
|
289
|
+
apiUrl: resolved.apiUrl,
|
|
290
|
+
profile: resolved.profileName,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
authenticated: true,
|
|
295
|
+
apiUrl: resolved.apiUrl,
|
|
296
|
+
profile: resolved.profileName,
|
|
297
|
+
expiresAt: cred.expires_at,
|
|
298
|
+
user: {
|
|
299
|
+
id: cred.user?.id,
|
|
300
|
+
email: cred.user?.email,
|
|
301
|
+
name: cred.user?.name,
|
|
302
|
+
expiresAt: cred.expires_at,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
});
|
|
306
|
+
const enrichUser = (profileName, authBase, cred) => Effect.gen(function* () {
|
|
307
|
+
if (cred.user?.id || cred.user?.email || cred.user?.name)
|
|
308
|
+
return cred;
|
|
309
|
+
const fetched = yield* Effect.tryPromise({
|
|
310
|
+
try: () => fetchSessionUser(authBase, cred),
|
|
311
|
+
catch: () => null,
|
|
312
|
+
}).pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
313
|
+
if (!fetched)
|
|
314
|
+
return cred;
|
|
315
|
+
const updated = { ...cred, user: fetched };
|
|
316
|
+
yield* config.writeProfileCredentials(profileName, updated);
|
|
317
|
+
return updated;
|
|
318
|
+
});
|
|
319
|
+
return {
|
|
320
|
+
probe,
|
|
321
|
+
requestDeviceCode,
|
|
322
|
+
pollDeviceToken,
|
|
323
|
+
refresh,
|
|
324
|
+
login,
|
|
325
|
+
logout,
|
|
326
|
+
whoami,
|
|
327
|
+
status,
|
|
328
|
+
ensureFresh,
|
|
329
|
+
enrichUser,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
async function fetchJson(url, init) {
|
|
333
|
+
const res = await globalThis.fetch(url, init);
|
|
334
|
+
let body;
|
|
335
|
+
try {
|
|
336
|
+
body = await res.json();
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
body = null;
|
|
340
|
+
}
|
|
341
|
+
return { ok: res.ok, status: res.status, headers: res.headers, body };
|
|
342
|
+
}
|
|
343
|
+
function sleep(ms, signal) {
|
|
344
|
+
return new Promise((resolve, reject) => {
|
|
345
|
+
if (signal?.aborted)
|
|
346
|
+
return reject(new Error('aborted'));
|
|
347
|
+
const timer = setTimeout(() => {
|
|
348
|
+
if (signal)
|
|
349
|
+
signal.removeEventListener('abort', onAbort);
|
|
350
|
+
resolve();
|
|
351
|
+
}, ms);
|
|
352
|
+
const onAbort = () => {
|
|
353
|
+
clearTimeout(timer);
|
|
354
|
+
reject(new Error('aborted'));
|
|
355
|
+
};
|
|
356
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
async function fetchSessionUser(authBase, cred) {
|
|
360
|
+
const res = await globalThis.fetch(`${authBase}/get-session`, {
|
|
361
|
+
method: 'GET',
|
|
362
|
+
headers: {
|
|
363
|
+
accept: 'application/json',
|
|
364
|
+
authorization: `Bearer ${cred.access_token}`,
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
if (!res.ok)
|
|
368
|
+
return null;
|
|
369
|
+
const body = (await res.json().catch(() => null));
|
|
370
|
+
return body?.user ?? null;
|
|
371
|
+
}
|
|
372
|
+
async function refreshSessionToken(authBase, cred) {
|
|
373
|
+
const res = await globalThis.fetch(`${authBase}/get-session`, {
|
|
374
|
+
method: 'GET',
|
|
375
|
+
headers: {
|
|
376
|
+
accept: 'application/json',
|
|
377
|
+
authorization: `Bearer ${cred.access_token}`,
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
if (!res.ok)
|
|
381
|
+
return null;
|
|
382
|
+
const body = (await res.json().catch(() => null));
|
|
383
|
+
const expiresAt = normalizeExpiresAt(body?.session?.expiresAt);
|
|
384
|
+
if (!expiresAt || expiresAt <= cred.expires_at)
|
|
385
|
+
return null;
|
|
386
|
+
return {
|
|
387
|
+
access_token: res.headers.get('set-auth-token') ?? cred.access_token,
|
|
388
|
+
refresh_token: cred.refresh_token,
|
|
389
|
+
expires_at: expiresAt,
|
|
390
|
+
user: body?.user ?? cred.user,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function normalizeExpiresAt(value) {
|
|
394
|
+
if (value === undefined)
|
|
395
|
+
return null;
|
|
396
|
+
const time = value instanceof Date
|
|
397
|
+
? value.getTime()
|
|
398
|
+
: typeof value === 'number'
|
|
399
|
+
? value
|
|
400
|
+
: new Date(value).getTime();
|
|
401
|
+
return Number.isFinite(time) ? time : null;
|
|
402
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Context, Layer } from 'effect';
|
|
2
|
+
export interface BackupService {
|
|
3
|
+
}
|
|
4
|
+
declare const Backup_base: Context.TagClass<Backup, "Backup", BackupService>;
|
|
5
|
+
export declare class Backup extends Backup_base {
|
|
6
|
+
static Default: Layer.Layer<Backup>;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from 'effect';
|
|
2
|
+
import type { ApiError } from './Api';
|
|
3
|
+
import { Api } from './Api';
|
|
4
|
+
export type CommentStateName = 'unread' | 'read' | 'junk';
|
|
5
|
+
export declare const COMMENT_STATE_NAMES: readonly CommentStateName[];
|
|
6
|
+
export declare const stateNameToCode: (s: CommentStateName) => number;
|
|
7
|
+
export declare const stateCodeToName: (n: number) => CommentStateName | undefined;
|
|
8
|
+
export interface CommentListOptions {
|
|
9
|
+
readonly page?: number;
|
|
10
|
+
readonly size?: number;
|
|
11
|
+
readonly state?: CommentStateName;
|
|
12
|
+
readonly all?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface CommentListResponse {
|
|
15
|
+
readonly data: ReadonlyArray<unknown>;
|
|
16
|
+
readonly pagination?: Record<string, unknown>;
|
|
17
|
+
readonly readers?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface CommentBatchFilter {
|
|
20
|
+
readonly currentState?: CommentStateName;
|
|
21
|
+
}
|
|
22
|
+
export interface CommentReplyInput {
|
|
23
|
+
readonly text: string;
|
|
24
|
+
readonly isWhispers?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface CommentService {
|
|
27
|
+
readonly list: (opts: CommentListOptions) => Effect.Effect<CommentListResponse, ApiError>;
|
|
28
|
+
readonly get: (id: string) => Effect.Effect<unknown, ApiError>;
|
|
29
|
+
/** Reply to a comment as the owner. Routes through `/comments/owner-reply/:id`. */
|
|
30
|
+
readonly reply: (parentId: string, body: CommentReplyInput) => Effect.Effect<unknown, ApiError>;
|
|
31
|
+
/** Mark one or more comments as read (state=1). Routes through batch endpoint. */
|
|
32
|
+
readonly approve: (ids: ReadonlyArray<string>) => Effect.Effect<void, ApiError>;
|
|
33
|
+
/** Mark one or more comments as junk (state=2). Routes through batch endpoint. */
|
|
34
|
+
readonly reject: (ids: ReadonlyArray<string>) => Effect.Effect<void, ApiError>;
|
|
35
|
+
/** Soft-delete one or more comments. Routes through batch endpoint. */
|
|
36
|
+
readonly delete: (ids: ReadonlyArray<string>) => Effect.Effect<void, ApiError>;
|
|
37
|
+
/** Approve all comments matching `filter` (optional currentState). */
|
|
38
|
+
readonly approveAll: (filter: CommentBatchFilter) => Effect.Effect<void, ApiError>;
|
|
39
|
+
/** Reject all comments matching `filter` (optional currentState). */
|
|
40
|
+
readonly rejectAll: (filter: CommentBatchFilter) => Effect.Effect<void, ApiError>;
|
|
41
|
+
/** Soft-delete all comments matching `filter` (optional currentState). */
|
|
42
|
+
readonly deleteAll: (filter: CommentBatchFilter) => Effect.Effect<void, ApiError>;
|
|
43
|
+
}
|
|
44
|
+
declare const Comment_base: Context.TagClass<Comment, "Comment", CommentService>;
|
|
45
|
+
export declare class Comment extends Comment_base {
|
|
46
|
+
static Default: Layer.Layer<Comment, never, Api>;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from 'effect';
|
|
2
|
+
import { Api } from './Api';
|
|
3
|
+
export const COMMENT_STATE_NAMES = [
|
|
4
|
+
'unread',
|
|
5
|
+
'read',
|
|
6
|
+
'junk',
|
|
7
|
+
];
|
|
8
|
+
const stateToCode = {
|
|
9
|
+
unread: 0,
|
|
10
|
+
read: 1,
|
|
11
|
+
junk: 2,
|
|
12
|
+
};
|
|
13
|
+
const codeToState = {
|
|
14
|
+
0: 'unread',
|
|
15
|
+
1: 'read',
|
|
16
|
+
2: 'junk',
|
|
17
|
+
};
|
|
18
|
+
export const stateNameToCode = (s) => stateToCode[s];
|
|
19
|
+
export const stateCodeToName = (n) => codeToState[n];
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Implementation
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const mergeListResponses = (responses) => {
|
|
24
|
+
const data = [];
|
|
25
|
+
const readers = {};
|
|
26
|
+
let total = 0;
|
|
27
|
+
for (const r of responses) {
|
|
28
|
+
if (Array.isArray(r.data))
|
|
29
|
+
data.push(...r.data);
|
|
30
|
+
if (r.readers)
|
|
31
|
+
Object.assign(readers, r.readers);
|
|
32
|
+
const t = r.pagination && typeof r.pagination.total === 'number'
|
|
33
|
+
? r.pagination.total
|
|
34
|
+
: 0;
|
|
35
|
+
total += t;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
data,
|
|
39
|
+
pagination: { total, size: data.length, page: 1, totalPages: 1 },
|
|
40
|
+
readers,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const makeService = (api) => {
|
|
44
|
+
const requestList = (state, page, size) => api.request('/comments', {
|
|
45
|
+
query: { page, size, state: stateNameToCode(state) },
|
|
46
|
+
});
|
|
47
|
+
const patchBatchState = (body) => Effect.asVoid(api.request('/comments/batch/state', {
|
|
48
|
+
method: 'PATCH',
|
|
49
|
+
body,
|
|
50
|
+
}));
|
|
51
|
+
const deleteBatch = (body) => Effect.asVoid(api.request('/comments/batch', {
|
|
52
|
+
method: 'DELETE',
|
|
53
|
+
body,
|
|
54
|
+
}));
|
|
55
|
+
return {
|
|
56
|
+
list: (opts) => {
|
|
57
|
+
if (opts.all) {
|
|
58
|
+
return Effect.all(COMMENT_STATE_NAMES.map((s) => requestList(s, opts.page, opts.size)), { concurrency: 3 }).pipe(Effect.map(mergeListResponses));
|
|
59
|
+
}
|
|
60
|
+
return requestList(opts.state ?? 'unread', opts.page, opts.size);
|
|
61
|
+
},
|
|
62
|
+
get: (id) => api.request(`/comments/${id}`),
|
|
63
|
+
reply: (parentId, body) => api.request(`/comments/owner-reply/${parentId}`, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
body: {
|
|
66
|
+
text: body.text,
|
|
67
|
+
...(body.isWhispers !== undefined
|
|
68
|
+
? { isWhispers: body.isWhispers }
|
|
69
|
+
: {}),
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
approve: (ids) => patchBatchState({ ids: [...ids], state: stateToCode.read }),
|
|
73
|
+
reject: (ids) => patchBatchState({ ids: [...ids], state: stateToCode.junk }),
|
|
74
|
+
delete: (ids) => deleteBatch({ ids: [...ids] }),
|
|
75
|
+
approveAll: (filter) => patchBatchState({
|
|
76
|
+
all: true,
|
|
77
|
+
state: stateToCode.read,
|
|
78
|
+
currentState: filter.currentState !== undefined
|
|
79
|
+
? stateNameToCode(filter.currentState)
|
|
80
|
+
: undefined,
|
|
81
|
+
}),
|
|
82
|
+
rejectAll: (filter) => patchBatchState({
|
|
83
|
+
all: true,
|
|
84
|
+
state: stateToCode.junk,
|
|
85
|
+
currentState: filter.currentState !== undefined
|
|
86
|
+
? stateNameToCode(filter.currentState)
|
|
87
|
+
: undefined,
|
|
88
|
+
}),
|
|
89
|
+
deleteAll: (filter) => deleteBatch({
|
|
90
|
+
all: true,
|
|
91
|
+
state: filter.currentState !== undefined
|
|
92
|
+
? stateNameToCode(filter.currentState)
|
|
93
|
+
: undefined,
|
|
94
|
+
}),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
export class Comment extends Context.Tag('Comment')() {
|
|
98
|
+
static Default = Layer.effect(Comment, Effect.gen(function* () {
|
|
99
|
+
const api = yield* Api;
|
|
100
|
+
return makeService(api);
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { FileSystem, Path } from '@effect/platform';
|
|
2
|
+
import { Context, Effect, Layer } from 'effect';
|
|
3
|
+
import type { ConfigMigrationFailed } from '../domain/errors';
|
|
4
|
+
import { ConfigMissingApiUrl, Generic, ProfileNotFound } from '../domain/errors';
|
|
5
|
+
export interface ConfigShape {
|
|
6
|
+
readonly api_url?: string;
|
|
7
|
+
readonly api_version?: number;
|
|
8
|
+
readonly production?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface CredentialsShape {
|
|
11
|
+
readonly access_token: string;
|
|
12
|
+
readonly refresh_token?: string;
|
|
13
|
+
readonly expires_at: number;
|
|
14
|
+
readonly user?: {
|
|
15
|
+
readonly id?: string;
|
|
16
|
+
readonly email?: string;
|
|
17
|
+
readonly name?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface ResolvedConfig {
|
|
21
|
+
readonly apiUrl: string;
|
|
22
|
+
readonly apiBase: string;
|
|
23
|
+
readonly authBase: string;
|
|
24
|
+
readonly apiVersion: number;
|
|
25
|
+
readonly clientId: string;
|
|
26
|
+
readonly token?: string;
|
|
27
|
+
readonly apiKey?: string;
|
|
28
|
+
readonly configPath: string;
|
|
29
|
+
readonly credentialsPath: string;
|
|
30
|
+
readonly profileName: string | null;
|
|
31
|
+
readonly isProduction: boolean;
|
|
32
|
+
readonly profileExplicit: boolean;
|
|
33
|
+
readonly urlOverridden: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface StoreOverrides {
|
|
36
|
+
readonly apiUrl?: string;
|
|
37
|
+
readonly token?: string;
|
|
38
|
+
readonly apiKey?: string;
|
|
39
|
+
readonly profile?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare const DEFAULT_CLIENT_ID = "mxs-cli";
|
|
42
|
+
export declare const LEGACY_CONFIG_FIELDS: readonly ["api_base", "auth_base", "client_id"];
|
|
43
|
+
export declare const LOCAL_DEV_ENV = "MXS_CLI_LOCAL_DEV";
|
|
44
|
+
export declare const LOCAL_DEV_API_URL_ENV = "MXS_CLI_LOCAL_DEV_API_URL";
|
|
45
|
+
export declare const LOCAL_DEV_PROFILE_NAME = "local-dev";
|
|
46
|
+
export declare const LOCAL_DEV_API_URL_DEFAULT = "http://localhost:2333";
|
|
47
|
+
export interface LocalDevProfileInput {
|
|
48
|
+
readonly profileOverride?: string;
|
|
49
|
+
readonly envProfile?: string;
|
|
50
|
+
readonly apiUrlOverride?: string;
|
|
51
|
+
readonly envApiUrl?: string;
|
|
52
|
+
readonly currentProfile?: string | null;
|
|
53
|
+
}
|
|
54
|
+
export declare const isLocalDevEnabled: () => boolean;
|
|
55
|
+
export declare const getLocalDevApiUrl: () => string;
|
|
56
|
+
export declare const shouldUseLocalDev: (input: LocalDevProfileInput) => boolean;
|
|
57
|
+
export declare const stripLegacyConfigFields: (cfg: Record<string, unknown>) => ConfigShape;
|
|
58
|
+
export interface ParsedApiUrl {
|
|
59
|
+
readonly baseUrl: string;
|
|
60
|
+
readonly apiVersion?: number;
|
|
61
|
+
}
|
|
62
|
+
export declare const parseApiUrl: (input: string) => Effect.Effect<ParsedApiUrl, ConfigMissingApiUrl>;
|
|
63
|
+
export declare const normalizeApiUrl: (input: string) => Effect.Effect<string, ConfigMissingApiUrl>;
|
|
64
|
+
export interface ConfigService {
|
|
65
|
+
readonly getConfigDir: Effect.Effect<string>;
|
|
66
|
+
readonly getProfilesDir: Effect.Effect<string>;
|
|
67
|
+
readonly getProfileDir: (name: string) => Effect.Effect<string>;
|
|
68
|
+
readonly getProfileConfigPath: (name: string) => Effect.Effect<string>;
|
|
69
|
+
readonly getProfileCredentialsPath: (name: string) => Effect.Effect<string>;
|
|
70
|
+
readonly getCurrentPath: Effect.Effect<string>;
|
|
71
|
+
readonly getLegacyConfigPath: Effect.Effect<string>;
|
|
72
|
+
readonly getLegacyCredentialsPath: Effect.Effect<string>;
|
|
73
|
+
readonly readProfileConfig: (name: string) => Effect.Effect<ConfigShape, ProfileNotFound | Generic>;
|
|
74
|
+
readonly writeProfileConfig: (name: string, cfg: ConfigShape) => Effect.Effect<void, Generic>;
|
|
75
|
+
readonly updateProfileConfig: (name: string, update: (prev: ConfigShape) => ConfigShape) => Effect.Effect<ConfigShape, ProfileNotFound | Generic>;
|
|
76
|
+
readonly readProfileCredentials: (name: string) => Effect.Effect<CredentialsShape | null, Generic>;
|
|
77
|
+
readonly writeProfileCredentials: (name: string, creds: CredentialsShape) => Effect.Effect<void, Generic>;
|
|
78
|
+
readonly deleteProfileCredentials: (name: string) => Effect.Effect<void, Generic>;
|
|
79
|
+
readonly readLegacyConfig: Effect.Effect<ConfigShape, Generic>;
|
|
80
|
+
readonly readLegacyConfigRaw: Effect.Effect<Record<string, unknown> | null, Generic>;
|
|
81
|
+
readonly readLegacyCredentialsRaw: Effect.Effect<Record<string, unknown> | null, Generic>;
|
|
82
|
+
readonly deleteLegacyConfig: Effect.Effect<void, Generic>;
|
|
83
|
+
readonly deleteLegacyCredentials: Effect.Effect<void, Generic>;
|
|
84
|
+
readonly readCurrent: Effect.Effect<string | null, Generic>;
|
|
85
|
+
readonly writeCurrent: (name: string) => Effect.Effect<void, Generic>;
|
|
86
|
+
readonly listProfileDirs: Effect.Effect<readonly string[], Generic>;
|
|
87
|
+
readonly profileExists: (name: string) => Effect.Effect<boolean, Generic>;
|
|
88
|
+
readonly removeProfileDir: (name: string) => Effect.Effect<void, Generic>;
|
|
89
|
+
readonly resolve: (overrides?: StoreOverrides) => Effect.Effect<ResolvedConfig, ConfigMissingApiUrl | ProfileNotFound | ConfigMigrationFailed | Generic>;
|
|
90
|
+
}
|
|
91
|
+
declare const Config_base: Context.TagClass<Config, "Config", ConfigService>;
|
|
92
|
+
export declare class Config extends Config_base {
|
|
93
|
+
static Default: Layer.Layer<Config, never, FileSystem.FileSystem | Path.Path>;
|
|
94
|
+
}
|
|
95
|
+
export {};
|