@mx-space/cli 0.2.2 → 0.3.0

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.
Files changed (210) hide show
  1. package/README.md +14 -0
  2. package/ROADMAP.md +6 -0
  3. package/bin/mxs.cjs +5 -5
  4. package/dist/{Lexical.dev-CMevU1DO.mjs → Lexical.dev-rcxzwpir.mjs} +0 -2
  5. package/dist/{Lexical.node-BR9e7Cyk.mjs → Lexical.node-BUsI9gWr.mjs} +1 -3
  6. package/dist/{Lexical.prod-PUD-z9fY.mjs → Lexical.prod-C8HtkSD6.mjs} +0 -2
  7. package/dist/{LexicalClipboard.dev-DZC2zppG.mjs → LexicalClipboard.dev-BpqRwTLP.mjs} +5 -7
  8. package/dist/{LexicalClipboard.node-e5G1wVGb.mjs → LexicalClipboard.node-CO-MCKx5.mjs} +1 -3
  9. package/dist/{LexicalClipboard.prod-DE2azzIb.mjs → LexicalClipboard.prod-B_xdeiAC.mjs} +5 -7
  10. package/dist/{LexicalCodeCore.dev-gs--x55I.mjs → LexicalCodeCore.dev-7_cexm39.mjs} +2 -4
  11. package/dist/{LexicalCodeCore.prod-DPHOnyEj.mjs → LexicalCodeCore.prod-Bd6WFHcO.mjs} +2 -4
  12. package/dist/{LexicalDragon.dev-CVe8bzVN.mjs → LexicalDragon.dev-gBP8WSRS.mjs} +2 -4
  13. package/dist/{LexicalDragon.node-c7EHvcnK.mjs → LexicalDragon.node-OG6G55nl.mjs} +1 -3
  14. package/dist/{LexicalDragon.prod-D6KvqyLD.mjs → LexicalDragon.prod-DP-_Q8cv.mjs} +2 -4
  15. package/dist/{LexicalExtension.dev-PDo8HyEw.mjs → LexicalExtension.dev-DVbjljrm.mjs} +2 -4
  16. package/dist/{LexicalExtension.node-BKzjRb-0.mjs → LexicalExtension.node-CF3EAPN7.mjs} +1 -3
  17. package/dist/{LexicalExtension.prod-D0x_lX7q.mjs → LexicalExtension.prod-DklHHErZ.mjs} +2 -4
  18. package/dist/{LexicalHeadless.dev-DBKcW82j.mjs → LexicalHeadless.dev-DdWLM7Nl.mjs} +1 -3
  19. package/dist/{LexicalHeadless.prod-D4nEh7cR.mjs → LexicalHeadless.prod-CoiiTDzR.mjs} +1 -3
  20. package/dist/{LexicalHtml.dev-vsWW05es.mjs → LexicalHtml.dev-C3ZSWBFZ.mjs} +3 -5
  21. package/dist/{LexicalHtml.node-CpibAfba.mjs → LexicalHtml.node-D0TD152E.mjs} +1 -3
  22. package/dist/{LexicalHtml.prod-Bqz-3WAp.mjs → LexicalHtml.prod-CX47X0zl.mjs} +3 -5
  23. package/dist/{LexicalLink.dev-BO0J0B1E.mjs → LexicalLink.dev-BS1Bf-yD.mjs} +3 -5
  24. package/dist/{LexicalLink.prod-D66AhUCZ.mjs → LexicalLink.prod-B_crkoHP.mjs} +3 -5
  25. package/dist/{LexicalList.dev-DVGTWRk0.mjs → LexicalList.dev-OMqmcnQ-.mjs} +3 -5
  26. package/dist/{LexicalList.prod-Bao7NGl7.mjs → LexicalList.prod-CpL1s8vS.mjs} +3 -5
  27. package/dist/{LexicalMarkdown.dev-CRWkZwlp.mjs → LexicalMarkdown.dev-BHSdx_Gr.mjs} +3 -5
  28. package/dist/{LexicalMarkdown.prod-tGG6js4r.mjs → LexicalMarkdown.prod-C-S7Ii6-.mjs} +3 -5
  29. package/dist/{LexicalRichText.dev-DPXfQePC.mjs → LexicalRichText.dev-Bz9A_WbM.mjs} +5 -7
  30. package/dist/{LexicalRichText.node-BEkm_YwY.mjs → LexicalRichText.node-DDpwfE-P.mjs} +4 -6
  31. package/dist/{LexicalRichText.prod-DlfudC5w.mjs → LexicalRichText.prod-C8qXACDL.mjs} +5 -7
  32. package/dist/{LexicalSelection.dev-BVTArZ-b.mjs → LexicalSelection.dev-CQ380fnD.mjs} +1 -3
  33. package/dist/{LexicalSelection.node-CQ8iTYsz.mjs → LexicalSelection.node-DesBMjIE.mjs} +1 -3
  34. package/dist/{LexicalSelection.prod-BZKGGs-G.mjs → LexicalSelection.prod-D2jivCDB.mjs} +1 -3
  35. package/dist/{LexicalTable.dev-C-AOEpJn.mjs → LexicalTable.dev-Ca7mQ7Jk.mjs} +4 -6
  36. package/dist/{LexicalTable.prod-Cyn0qWxZ.mjs → LexicalTable.prod-DyPAcC7y.mjs} +4 -6
  37. package/dist/{LexicalUtils.dev-DRRDyAlS.mjs → LexicalUtils.dev-HxM8F0g6.mjs} +2 -4
  38. package/dist/{LexicalUtils.node-Dz-HANi6.mjs → LexicalUtils.node-lCWjRjoG.mjs} +1 -3
  39. package/dist/{LexicalUtils.prod-CmeHwh8W.mjs → LexicalUtils.prod-Bti5w4ki.mjs} +2 -4
  40. package/dist/bin/mxs.d.mts +2 -929
  41. package/dist/bin/mxs.mjs +2 -3595
  42. package/dist/esm-BKxzBG1f.mjs +2 -0
  43. package/dist/esm-DO9hVR8S.mjs +37652 -0
  44. package/dist/index.d.mts +1492 -374
  45. package/dist/index.mjs +2 -11
  46. package/dist/mxs-BUOk42XP.mjs +30444 -0
  47. package/dist/mxs-CM8-6uAr.d.mts +4 -0
  48. package/package.json +7 -2
  49. package/dist/Lexical.dev-CMevU1DO.mjs.map +0 -1
  50. package/dist/Lexical.node-BR9e7Cyk.mjs.map +0 -1
  51. package/dist/Lexical.prod-PUD-z9fY.mjs.map +0 -1
  52. package/dist/LexicalClipboard.dev-DZC2zppG.mjs.map +0 -1
  53. package/dist/LexicalClipboard.node-e5G1wVGb.mjs.map +0 -1
  54. package/dist/LexicalClipboard.prod-DE2azzIb.mjs.map +0 -1
  55. package/dist/LexicalCodeCore.dev-gs--x55I.mjs.map +0 -1
  56. package/dist/LexicalCodeCore.prod-DPHOnyEj.mjs.map +0 -1
  57. package/dist/LexicalDragon.dev-CVe8bzVN.mjs.map +0 -1
  58. package/dist/LexicalDragon.node-c7EHvcnK.mjs.map +0 -1
  59. package/dist/LexicalDragon.prod-D6KvqyLD.mjs.map +0 -1
  60. package/dist/LexicalExtension.dev-PDo8HyEw.mjs.map +0 -1
  61. package/dist/LexicalExtension.node-BKzjRb-0.mjs.map +0 -1
  62. package/dist/LexicalExtension.prod-D0x_lX7q.mjs.map +0 -1
  63. package/dist/LexicalHeadless.dev-DBKcW82j.mjs.map +0 -1
  64. package/dist/LexicalHeadless.prod-D4nEh7cR.mjs.map +0 -1
  65. package/dist/LexicalHtml.dev-vsWW05es.mjs.map +0 -1
  66. package/dist/LexicalHtml.node-CpibAfba.mjs.map +0 -1
  67. package/dist/LexicalHtml.prod-Bqz-3WAp.mjs.map +0 -1
  68. package/dist/LexicalLink.dev-BO0J0B1E.mjs.map +0 -1
  69. package/dist/LexicalLink.prod-D66AhUCZ.mjs.map +0 -1
  70. package/dist/LexicalList.dev-DVGTWRk0.mjs.map +0 -1
  71. package/dist/LexicalList.prod-Bao7NGl7.mjs.map +0 -1
  72. package/dist/LexicalMarkdown.dev-CRWkZwlp.mjs.map +0 -1
  73. package/dist/LexicalMarkdown.prod-tGG6js4r.mjs.map +0 -1
  74. package/dist/LexicalRichText.dev-DPXfQePC.mjs.map +0 -1
  75. package/dist/LexicalRichText.node-BEkm_YwY.mjs.map +0 -1
  76. package/dist/LexicalRichText.prod-DlfudC5w.mjs.map +0 -1
  77. package/dist/LexicalSelection.dev-BVTArZ-b.mjs.map +0 -1
  78. package/dist/LexicalSelection.node-CQ8iTYsz.mjs.map +0 -1
  79. package/dist/LexicalSelection.prod-BZKGGs-G.mjs.map +0 -1
  80. package/dist/LexicalTable.dev-C-AOEpJn.mjs.map +0 -1
  81. package/dist/LexicalTable.prod-Cyn0qWxZ.mjs.map +0 -1
  82. package/dist/LexicalUtils.dev-DRRDyAlS.mjs.map +0 -1
  83. package/dist/LexicalUtils.node-Dz-HANi6.mjs.map +0 -1
  84. package/dist/LexicalUtils.prod-CmeHwh8W.mjs.map +0 -1
  85. package/dist/auth-CAKmTDpF.mjs +0 -211
  86. package/dist/auth-CAKmTDpF.mjs.map +0 -1
  87. package/dist/bin/mxs.mjs.map +0 -1
  88. package/dist/config-store-B8_9iStL.mjs +0 -166
  89. package/dist/config-store-B8_9iStL.mjs.map +0 -1
  90. package/dist/create-5wbU7IQh.mjs +0 -23
  91. package/dist/create-5wbU7IQh.mjs.map +0 -1
  92. package/dist/create-Bs6K7AyQ.mjs +0 -23
  93. package/dist/create-Bs6K7AyQ.mjs.map +0 -1
  94. package/dist/create-DBReocgJ.mjs +0 -24
  95. package/dist/create-DBReocgJ.mjs.map +0 -1
  96. package/dist/create-DGVaE0_S.mjs +0 -19
  97. package/dist/create-DGVaE0_S.mjs.map +0 -1
  98. package/dist/create-lLFZuMsz.mjs +0 -23
  99. package/dist/create-lLFZuMsz.mjs.map +0 -1
  100. package/dist/delete-6tkhHQDp.mjs +0 -22
  101. package/dist/delete-6tkhHQDp.mjs.map +0 -1
  102. package/dist/delete-CRFxitDN.mjs +0 -31
  103. package/dist/delete-CRFxitDN.mjs.map +0 -1
  104. package/dist/delete-DU2Hvsy8.mjs +0 -22
  105. package/dist/delete-DU2Hvsy8.mjs.map +0 -1
  106. package/dist/delete-nJmHtvfq.mjs +0 -31
  107. package/dist/delete-nJmHtvfq.mjs.map +0 -1
  108. package/dist/delete-tJhXI8s4.mjs +0 -22
  109. package/dist/delete-tJhXI8s4.mjs.map +0 -1
  110. package/dist/dist-DJF1Ntdn.mjs +0 -810
  111. package/dist/dist-DJF1Ntdn.mjs.map +0 -1
  112. package/dist/document-output-BFJdwPV0.mjs +0 -200
  113. package/dist/document-output-BFJdwPV0.mjs.map +0 -1
  114. package/dist/edit-BMjTbPQO.mjs +0 -40
  115. package/dist/edit-BMjTbPQO.mjs.map +0 -1
  116. package/dist/edit-BnEmMmv6.mjs +0 -80
  117. package/dist/edit-BnEmMmv6.mjs.map +0 -1
  118. package/dist/edit-C4vRSmRy.mjs +0 -79
  119. package/dist/edit-C4vRSmRy.mjs.map +0 -1
  120. package/dist/edit-CQsW5gnk.mjs +0 -86
  121. package/dist/edit-CQsW5gnk.mjs.map +0 -1
  122. package/dist/editor-BIw1ALTF.mjs +0 -42
  123. package/dist/editor-BIw1ALTF.mjs.map +0 -1
  124. package/dist/envelope-overlays-DXXygxdF.mjs +0 -26
  125. package/dist/envelope-overlays-DXXygxdF.mjs.map +0 -1
  126. package/dist/get-B3Y5hAAO.mjs +0 -10
  127. package/dist/get-B3Y5hAAO.mjs.map +0 -1
  128. package/dist/get-C5fmd5Vf.mjs +0 -14
  129. package/dist/get-C5fmd5Vf.mjs.map +0 -1
  130. package/dist/get-Cdp2tmwz.mjs +0 -28
  131. package/dist/get-Cdp2tmwz.mjs.map +0 -1
  132. package/dist/get-D18ChSKU.mjs +0 -10
  133. package/dist/get-D18ChSKU.mjs.map +0 -1
  134. package/dist/get-NSHTGu4Y.mjs +0 -13
  135. package/dist/get-NSHTGu4Y.mjs.map +0 -1
  136. package/dist/get-XBPJr95m.mjs +0 -14
  137. package/dist/get-XBPJr95m.mjs.map +0 -1
  138. package/dist/list-B6703n9X.mjs +0 -10
  139. package/dist/list-B6703n9X.mjs.map +0 -1
  140. package/dist/list-BtNocJhc.mjs +0 -14
  141. package/dist/list-BtNocJhc.mjs.map +0 -1
  142. package/dist/list-C9dXrU9H.mjs +0 -10
  143. package/dist/list-C9dXrU9H.mjs.map +0 -1
  144. package/dist/list-CcwcYZgN.mjs +0 -10
  145. package/dist/list-CcwcYZgN.mjs.map +0 -1
  146. package/dist/list-Ctc8b5gT.mjs +0 -10
  147. package/dist/list-Ctc8b5gT.mjs.map +0 -1
  148. package/dist/list-b60JzCTw.mjs +0 -15
  149. package/dist/list-b60JzCTw.mjs.map +0 -1
  150. package/dist/litexml-codec-CfIxcPG0.mjs +0 -13451
  151. package/dist/litexml-codec-CfIxcPG0.mjs.map +0 -1
  152. package/dist/login-bZx4HaVs.mjs +0 -591
  153. package/dist/login-bZx4HaVs.mjs.map +0 -1
  154. package/dist/logout-C0Dzitsu.mjs +0 -18
  155. package/dist/logout-C0Dzitsu.mjs.map +0 -1
  156. package/dist/ls-wMiTXZPQ.mjs +0 -33
  157. package/dist/ls-wMiTXZPQ.mjs.map +0 -1
  158. package/dist/mark-Dh9BErsf.mjs +0 -29
  159. package/dist/mark-Dh9BErsf.mjs.map +0 -1
  160. package/dist/onboarding-Bw_I8qpf.mjs +0 -214
  161. package/dist/onboarding-Bw_I8qpf.mjs.map +0 -1
  162. package/dist/output-D2dDlyV2.d.mts +0 -16
  163. package/dist/output-vzequvhd.mjs +0 -163
  164. package/dist/output-vzequvhd.mjs.map +0 -1
  165. package/dist/payload-CO4zbNr8.mjs +0 -547
  166. package/dist/payload-CO4zbNr8.mjs.map +0 -1
  167. package/dist/profile-CNe2uWJi.mjs +0 -172
  168. package/dist/profile-CNe2uWJi.mjs.map +0 -1
  169. package/dist/publish-CzzucXQq.mjs +0 -23
  170. package/dist/publish-CzzucXQq.mjs.map +0 -1
  171. package/dist/publish-DRQkpxsz.mjs +0 -23
  172. package/dist/publish-DRQkpxsz.mjs.map +0 -1
  173. package/dist/resolve-BYg5Gees.mjs +0 -23
  174. package/dist/resolve-BYg5Gees.mjs.map +0 -1
  175. package/dist/resolve-BlpMdnaM.mjs +0 -16
  176. package/dist/resolve-BlpMdnaM.mjs.map +0 -1
  177. package/dist/resolve-CUsHGcb-.mjs +0 -119
  178. package/dist/resolve-CUsHGcb-.mjs.map +0 -1
  179. package/dist/resolve-helpers-CoHYa2uk.mjs +0 -30
  180. package/dist/resolve-helpers-CoHYa2uk.mjs.map +0 -1
  181. package/dist/resolve-jdb1VqAG.mjs +0 -26
  182. package/dist/resolve-jdb1VqAG.mjs.map +0 -1
  183. package/dist/rm-D-2iW1Cr.mjs +0 -33
  184. package/dist/rm-D-2iW1Cr.mjs.map +0 -1
  185. package/dist/run-Dnax6uhZ.mjs +0 -130
  186. package/dist/run-Dnax6uhZ.mjs.map +0 -1
  187. package/dist/self-update-CZywTwGd.mjs +0 -1610
  188. package/dist/self-update-CZywTwGd.mjs.map +0 -1
  189. package/dist/set-Dk28LAy5.mjs +0 -43
  190. package/dist/set-Dk28LAy5.mjs.map +0 -1
  191. package/dist/shared-d0_6ZPn_.mjs +0 -50
  192. package/dist/shared-d0_6ZPn_.mjs.map +0 -1
  193. package/dist/show-DScu6mXz.mjs +0 -39
  194. package/dist/show-DScu6mXz.mjs.map +0 -1
  195. package/dist/status-8F6tgphP.mjs +0 -23
  196. package/dist/status-8F6tgphP.mjs.map +0 -1
  197. package/dist/update-B1LGxV0n.mjs +0 -30
  198. package/dist/update-B1LGxV0n.mjs.map +0 -1
  199. package/dist/update-CXetpFT3.mjs +0 -28
  200. package/dist/update-CXetpFT3.mjs.map +0 -1
  201. package/dist/update-Dr4BW8U-.mjs +0 -30
  202. package/dist/update-Dr4BW8U-.mjs.map +0 -1
  203. package/dist/update-bqcHRJPC.mjs +0 -36
  204. package/dist/update-bqcHRJPC.mjs.map +0 -1
  205. package/dist/update-dBtzzmkN.mjs +0 -37
  206. package/dist/update-dBtzzmkN.mjs.map +0 -1
  207. package/dist/use-D7eKESSW.mjs +0 -29
  208. package/dist/use-D7eKESSW.mjs.map +0 -1
  209. package/dist/whoami-CKSNd6zL.mjs +0 -22
  210. package/dist/whoami-CKSNd6zL.mjs.map +0 -1
@@ -1,211 +0,0 @@
1
- import { c as MxsErrorCode, s as MxsError } from "./output-vzequvhd.mjs";
2
- import { f as writeCredentials, l as readCredentials } from "./config-store-B8_9iStL.mjs";
3
- //#region src/core/auth.ts
4
- const SUPPORTED_API_VERSIONS = [2];
5
- function defaultHttp() {
6
- return { fetch: globalThis.fetch.bind(globalThis) };
7
- }
8
- async function probeAuthEndpoint(apiUrl, http = defaultHttp()) {
9
- const candidates = [...SUPPORTED_API_VERSIONS.map((v) => ({
10
- prefix: `/api/v${v}/auth`,
11
- version: v
12
- })), {
13
- prefix: "/auth",
14
- version: null
15
- }];
16
- for (const cand of candidates) {
17
- const probeUrl = `${apiUrl}${cand.prefix}/ok`;
18
- let res;
19
- try {
20
- res = await http.fetch(probeUrl, { method: "GET" });
21
- } catch {
22
- continue;
23
- }
24
- if (res.ok) {
25
- const apiVersion = cand.version ?? SUPPORTED_API_VERSIONS[0];
26
- return {
27
- apiUrl,
28
- apiBase: cand.prefix === "/auth" ? apiUrl : `${apiUrl}/api/v${apiVersion}`,
29
- authBase: `${apiUrl}${cand.prefix}`,
30
- apiVersion
31
- };
32
- }
33
- }
34
- throw new MxsError({
35
- code: MxsErrorCode.AuthProbe,
36
- message: "cannot detect auth endpoint",
37
- hint: "verify the URL points at a running mx-core server"
38
- });
39
- }
40
- async function requestDeviceCode(authBase, clientId, scope = "openid profile email", http = defaultHttp()) {
41
- const res = await http.fetch(`${authBase}/device/code`, {
42
- method: "POST",
43
- headers: { "content-type": "application/json" },
44
- body: JSON.stringify({
45
- client_id: clientId,
46
- scope
47
- })
48
- });
49
- if (!res.ok) {
50
- let body;
51
- try {
52
- body = await res.json();
53
- } catch {
54
- body = await res.text();
55
- }
56
- throw new MxsError({
57
- code: MxsErrorCode.AuthDenied,
58
- message: `device code request failed (${res.status})`,
59
- details: body
60
- });
61
- }
62
- return await res.json();
63
- }
64
- async function pollDeviceToken(authBase, clientId, deviceCode, opts) {
65
- const http = opts.http ?? defaultHttp();
66
- const deadline = Date.now() + opts.expiresInSec * 1e3;
67
- let intervalMs = Math.max(1, opts.intervalSec) * 1e3;
68
- while (Date.now() < deadline) {
69
- if (opts.signal?.aborted) throw new MxsError({
70
- code: MxsErrorCode.AuthDenied,
71
- message: "aborted by user"
72
- });
73
- await sleep(intervalMs, opts.signal);
74
- const res = await http.fetch(`${authBase}/device/token`, {
75
- method: "POST",
76
- headers: { "content-type": "application/json" },
77
- body: JSON.stringify({
78
- grant_type: "urn:ietf:params:oauth:grant-type:device_code",
79
- device_code: deviceCode,
80
- client_id: clientId
81
- })
82
- });
83
- let body;
84
- try {
85
- body = await res.json();
86
- } catch {
87
- body = null;
88
- }
89
- if (res.ok && body?.access_token) return body;
90
- const err = body?.error;
91
- if (err === "authorization_pending") {
92
- opts.onTick?.("pending");
93
- continue;
94
- }
95
- if (err === "slow_down") {
96
- intervalMs += 5e3;
97
- opts.onTick?.("slow_down");
98
- continue;
99
- }
100
- if (err === "access_denied") throw new MxsError({
101
- code: MxsErrorCode.AuthDenied,
102
- message: "user denied the authorization request"
103
- });
104
- if (err === "expired_token") throw new MxsError({
105
- code: MxsErrorCode.AuthExpired,
106
- message: "device code expired before authorization completed",
107
- hint: "run `mxs auth login` again"
108
- });
109
- throw new MxsError({
110
- code: MxsErrorCode.AuthDenied,
111
- message: `device token request failed (${res.status})`,
112
- details: body
113
- });
114
- }
115
- throw new MxsError({
116
- code: MxsErrorCode.AuthExpired,
117
- message: "device authorization timed out",
118
- hint: "run `mxs auth login` again"
119
- });
120
- }
121
- function sleep(ms, signal) {
122
- return new Promise((resolve, reject) => {
123
- if (signal?.aborted) return reject(/* @__PURE__ */ new Error("aborted"));
124
- const timer = setTimeout(() => {
125
- if (signal) signal.removeEventListener("abort", onAbort);
126
- resolve();
127
- }, ms);
128
- const onAbort = () => {
129
- clearTimeout(timer);
130
- reject(/* @__PURE__ */ new Error("aborted"));
131
- };
132
- signal?.addEventListener("abort", onAbort, { once: true });
133
- });
134
- }
135
- function toCredentials(resp) {
136
- return {
137
- access_token: resp.access_token,
138
- refresh_token: resp.refresh_token,
139
- expires_at: Date.now() + resp.expires_in * 1e3,
140
- user: resp.user
141
- };
142
- }
143
- function isExpiringSoon(cred, bufferMs = 6e4) {
144
- return cred.expires_at < Date.now() + bufferMs;
145
- }
146
- async function refreshAccessToken(authBase, clientId, cred, http = defaultHttp()) {
147
- if (!cred.refresh_token) return refreshSessionToken(authBase, cred, http);
148
- const res = await http.fetch(`${authBase}/token`, {
149
- method: "POST",
150
- headers: { "content-type": "application/json" },
151
- body: JSON.stringify({
152
- grant_type: "refresh_token",
153
- refresh_token: cred.refresh_token,
154
- client_id: clientId
155
- })
156
- });
157
- if (!res.ok) return null;
158
- const body = await res.json();
159
- if (!body?.access_token) return null;
160
- return {
161
- access_token: body.access_token,
162
- refresh_token: body.refresh_token ?? cred.refresh_token,
163
- expires_at: Date.now() + body.expires_in * 1e3,
164
- user: body.user ?? cred.user
165
- };
166
- }
167
- async function refreshSessionToken(authBase, cred, http) {
168
- const res = await http.fetch(`${authBase}/get-session`, {
169
- method: "GET",
170
- headers: {
171
- accept: "application/json",
172
- authorization: `Bearer ${cred.access_token}`
173
- }
174
- });
175
- if (!res.ok) return null;
176
- const body = await res.json().catch(() => null);
177
- const expiresAt = normalizeExpiresAt(body?.session?.expiresAt);
178
- if (!expiresAt || expiresAt <= cred.expires_at) return null;
179
- return {
180
- access_token: res.headers.get("set-auth-token") ?? cred.access_token,
181
- refresh_token: cred.refresh_token,
182
- expires_at: expiresAt,
183
- user: body?.user ?? cred.user
184
- };
185
- }
186
- function normalizeExpiresAt(value) {
187
- if (value === void 0) return null;
188
- const time = value instanceof Date ? value.getTime() : typeof value === "number" ? value : new Date(value).getTime();
189
- return Number.isFinite(time) ? time : null;
190
- }
191
- async function loadCredentialsOrThrow() {
192
- const cred = await readCredentials();
193
- if (!cred) throw new MxsError({
194
- code: MxsErrorCode.AuthMissing,
195
- message: "not authenticated",
196
- hint: "run `mxs auth login`"
197
- });
198
- return cred;
199
- }
200
- async function ensureFreshToken(authBase, clientId, http = defaultHttp()) {
201
- const cred = await loadCredentialsOrThrow();
202
- if (!isExpiringSoon(cred)) return cred;
203
- const refreshed = await refreshAccessToken(authBase, clientId, cred, http);
204
- if (!refreshed) return cred;
205
- await writeCredentials(refreshed);
206
- return refreshed;
207
- }
208
- //#endregion
209
- export { loadCredentialsOrThrow as a, refreshAccessToken as c, isExpiringSoon as i, requestDeviceCode as l, defaultHttp as n, pollDeviceToken as o, ensureFreshToken as r, probeAuthEndpoint as s, SUPPORTED_API_VERSIONS as t, toCredentials as u };
210
-
211
- //# sourceMappingURL=auth-CAKmTDpF.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-CAKmTDpF.mjs","names":[],"sources":["../src/core/auth.ts"],"sourcesContent":["import {\n type CredentialsShape,\n readCredentials,\n writeCredentials,\n} from './config-store'\nimport { MxsError, MxsErrorCode } from './errors'\n\nexport const SUPPORTED_API_VERSIONS = [2] as const\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n verification_uri_complete?: string\n expires_in: number\n interval: number\n}\n\nexport interface DeviceTokenResponse {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token?: string\n scope?: string\n user?: {\n id?: string\n email?: string\n name?: string\n }\n}\n\nexport interface ProbeResult {\n apiUrl: string\n apiBase: string\n authBase: string\n apiVersion: number\n}\n\nexport interface AuthHttp {\n fetch: typeof fetch\n}\n\nexport function defaultHttp(): AuthHttp {\n return { fetch: globalThis.fetch.bind(globalThis) }\n}\n\nexport async function probeAuthEndpoint(\n apiUrl: string,\n http: AuthHttp = defaultHttp(),\n): Promise<ProbeResult> {\n const candidates: { prefix: string; version: number | null }[] = [\n ...SUPPORTED_API_VERSIONS.map((v) => ({\n prefix: `/api/v${v}/auth`,\n version: v,\n })),\n { prefix: '/auth', version: null },\n ]\n for (const cand of candidates) {\n const probeUrl = `${apiUrl}${cand.prefix}/ok`\n let res: Response\n try {\n res = await http.fetch(probeUrl, { method: 'GET' })\n } catch {\n continue\n }\n if (res.ok) {\n const apiVersion = cand.version ?? SUPPORTED_API_VERSIONS[0]\n const apiBase =\n cand.prefix === '/auth' ? apiUrl : `${apiUrl}/api/v${apiVersion}`\n const authBase = `${apiUrl}${cand.prefix}`\n return { apiUrl, apiBase, authBase, apiVersion }\n }\n }\n throw new MxsError({\n code: MxsErrorCode.AuthProbe,\n message: 'cannot detect auth endpoint',\n hint: 'verify the URL points at a running mx-core server',\n })\n}\n\nexport async function requestDeviceCode(\n authBase: string,\n clientId: string,\n scope = 'openid profile email',\n http: AuthHttp = defaultHttp(),\n): Promise<DeviceCodeResponse> {\n const res = await http.fetch(`${authBase}/device/code`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ client_id: clientId, scope }),\n })\n if (!res.ok) {\n let body: unknown\n try {\n body = await res.json()\n } catch {\n body = await res.text()\n }\n throw new MxsError({\n code: MxsErrorCode.AuthDenied,\n message: `device code request failed (${res.status})`,\n details: body,\n })\n }\n return (await res.json()) as DeviceCodeResponse\n}\n\nexport interface PollOptions {\n intervalSec: number\n expiresInSec: number\n signal?: AbortSignal\n onTick?: (state: 'pending' | 'slow_down') => void\n http?: AuthHttp\n}\n\nexport async function pollDeviceToken(\n authBase: string,\n clientId: string,\n deviceCode: string,\n opts: PollOptions,\n): Promise<DeviceTokenResponse> {\n const http = opts.http ?? defaultHttp()\n const deadline = Date.now() + opts.expiresInSec * 1000\n let intervalMs = Math.max(1, opts.intervalSec) * 1000\n while (Date.now() < deadline) {\n if (opts.signal?.aborted) {\n throw new MxsError({\n code: MxsErrorCode.AuthDenied,\n message: 'aborted by user',\n })\n }\n await sleep(intervalMs, opts.signal)\n const res = await http.fetch(`${authBase}/device/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }),\n })\n let body: any\n try {\n body = await res.json()\n } catch {\n body = null\n }\n if (res.ok && body?.access_token) {\n return body as DeviceTokenResponse\n }\n const err = body?.error as string | undefined\n if (err === 'authorization_pending') {\n opts.onTick?.('pending')\n continue\n }\n if (err === 'slow_down') {\n intervalMs += 5000\n opts.onTick?.('slow_down')\n continue\n }\n if (err === 'access_denied') {\n throw new MxsError({\n code: MxsErrorCode.AuthDenied,\n message: 'user denied the authorization request',\n })\n }\n if (err === 'expired_token') {\n throw new MxsError({\n code: MxsErrorCode.AuthExpired,\n message: 'device code expired before authorization completed',\n hint: 'run `mxs auth login` again',\n })\n }\n throw new MxsError({\n code: MxsErrorCode.AuthDenied,\n message: `device token request failed (${res.status})`,\n details: body,\n })\n }\n throw new MxsError({\n code: MxsErrorCode.AuthExpired,\n message: 'device authorization timed out',\n hint: 'run `mxs auth login` again',\n })\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(new Error('aborted'))\n const timer = setTimeout(() => {\n if (signal) signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n const onAbort = () => {\n clearTimeout(timer)\n reject(new Error('aborted'))\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport function toCredentials(resp: DeviceTokenResponse): CredentialsShape {\n return {\n access_token: resp.access_token,\n refresh_token: resp.refresh_token,\n expires_at: Date.now() + resp.expires_in * 1000,\n user: resp.user,\n }\n}\n\nexport function isExpiringSoon(\n cred: CredentialsShape,\n bufferMs = 60_000,\n): boolean {\n return cred.expires_at < Date.now() + bufferMs\n}\n\nexport async function refreshAccessToken(\n authBase: string,\n clientId: string,\n cred: CredentialsShape,\n http: AuthHttp = defaultHttp(),\n): Promise<CredentialsShape | null> {\n if (!cred.refresh_token) {\n return refreshSessionToken(authBase, cred, http)\n }\n const res = await http.fetch(`${authBase}/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'refresh_token',\n refresh_token: cred.refresh_token,\n client_id: clientId,\n }),\n })\n if (!res.ok) return null\n const body = (await res.json()) as DeviceTokenResponse\n if (!body?.access_token) return null\n return {\n access_token: body.access_token,\n refresh_token: body.refresh_token ?? cred.refresh_token,\n expires_at: Date.now() + body.expires_in * 1000,\n user: body.user ?? cred.user,\n }\n}\n\nasync function refreshSessionToken(\n authBase: string,\n cred: CredentialsShape,\n http: AuthHttp,\n): Promise<CredentialsShape | null> {\n const res = await http.fetch(`${authBase}/get-session`, {\n method: 'GET',\n headers: {\n accept: 'application/json',\n authorization: `Bearer ${cred.access_token}`,\n },\n })\n if (!res.ok) return null\n const body = (await res.json().catch(() => null)) as {\n session?: { expiresAt?: string | Date | number }\n user?: CredentialsShape['user']\n } | null\n const expiresAt = normalizeExpiresAt(body?.session?.expiresAt)\n if (!expiresAt || expiresAt <= cred.expires_at) return null\n return {\n access_token: res.headers.get('set-auth-token') ?? cred.access_token,\n refresh_token: cred.refresh_token,\n expires_at: expiresAt,\n user: body?.user ?? cred.user,\n }\n}\n\nfunction normalizeExpiresAt(value: string | Date | number | undefined) {\n if (value === undefined) return null\n const time =\n value instanceof Date\n ? value.getTime()\n : typeof value === 'number'\n ? value\n : new Date(value).getTime()\n return Number.isFinite(time) ? time : null\n}\n\nexport async function loadCredentialsOrThrow(): Promise<CredentialsShape> {\n const cred = await readCredentials()\n if (!cred) {\n throw new MxsError({\n code: MxsErrorCode.AuthMissing,\n message: 'not authenticated',\n hint: 'run `mxs auth login`',\n })\n }\n return cred\n}\n\nexport async function ensureFreshToken(\n authBase: string,\n clientId: string,\n http: AuthHttp = defaultHttp(),\n): Promise<CredentialsShape> {\n const cred = await loadCredentialsOrThrow()\n if (!isExpiringSoon(cred)) return cred\n const refreshed = await refreshAccessToken(authBase, clientId, cred, http)\n if (!refreshed) return cred\n await writeCredentials(refreshed)\n return refreshed\n}\n"],"mappings":"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"}