@mx-space/cli 0.1.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 (190) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +375 -0
  3. package/ROADMAP.md +42 -0
  4. package/bin/mxs.cjs +40 -0
  5. package/dist/Lexical.dev-DpU35QTu.mjs +10992 -0
  6. package/dist/Lexical.dev-DpU35QTu.mjs.map +1 -0
  7. package/dist/Lexical.node-gYNDt_p9.mjs +247 -0
  8. package/dist/Lexical.node-gYNDt_p9.mjs.map +1 -0
  9. package/dist/Lexical.prod-t4c3bHV3.mjs +5579 -0
  10. package/dist/Lexical.prod-t4c3bHV3.mjs.map +1 -0
  11. package/dist/LexicalClipboard.dev-CdeeWCIq.mjs +496 -0
  12. package/dist/LexicalClipboard.dev-CdeeWCIq.mjs.map +1 -0
  13. package/dist/LexicalClipboard.node-0e9GBL1g.mjs +26 -0
  14. package/dist/LexicalClipboard.node-0e9GBL1g.mjs.map +1 -0
  15. package/dist/LexicalClipboard.prod-CsCWYmV7.mjs +293 -0
  16. package/dist/LexicalClipboard.prod-CsCWYmV7.mjs.map +1 -0
  17. package/dist/LexicalCodeCore.dev-haI2cqH8.mjs +539 -0
  18. package/dist/LexicalCodeCore.dev-haI2cqH8.mjs.map +1 -0
  19. package/dist/LexicalCodeCore.prod-D_k7zuE5.mjs +383 -0
  20. package/dist/LexicalCodeCore.prod-D_k7zuE5.mjs.map +1 -0
  21. package/dist/LexicalDragon.dev-CAggdFh_.mjs +90 -0
  22. package/dist/LexicalDragon.dev-CAggdFh_.mjs.map +1 -0
  23. package/dist/LexicalDragon.node-QMR_wqJg.mjs +15 -0
  24. package/dist/LexicalDragon.node-QMR_wqJg.mjs.map +1 -0
  25. package/dist/LexicalDragon.prod-OssQhwS-.mjs +61 -0
  26. package/dist/LexicalDragon.prod-OssQhwS-.mjs.map +1 -0
  27. package/dist/LexicalExtension.dev-CtDZiMCU.mjs +1665 -0
  28. package/dist/LexicalExtension.dev-CtDZiMCU.mjs.map +1 -0
  29. package/dist/LexicalExtension.node-BM0gh8zu.mjs +51 -0
  30. package/dist/LexicalExtension.node-BM0gh8zu.mjs.map +1 -0
  31. package/dist/LexicalExtension.prod-Ug6emhEO.mjs +971 -0
  32. package/dist/LexicalExtension.prod-Ug6emhEO.mjs.map +1 -0
  33. package/dist/LexicalHeadless.dev-D4yQpl_s.mjs +45 -0
  34. package/dist/LexicalHeadless.dev-D4yQpl_s.mjs.map +1 -0
  35. package/dist/LexicalHeadless.prod-jeN65B3k.mjs +31 -0
  36. package/dist/LexicalHeadless.prod-jeN65B3k.mjs.map +1 -0
  37. package/dist/LexicalHtml.dev-BdU1_ITQ.mjs +686 -0
  38. package/dist/LexicalHtml.dev-BdU1_ITQ.mjs.map +1 -0
  39. package/dist/LexicalHtml.node-DLtAh00E.mjs +26 -0
  40. package/dist/LexicalHtml.node-DLtAh00E.mjs.map +1 -0
  41. package/dist/LexicalHtml.prod-DdLE1HHT.mjs +432 -0
  42. package/dist/LexicalHtml.prod-DdLE1HHT.mjs.map +1 -0
  43. package/dist/LexicalLink.dev-DK87Biuy.mjs +1084 -0
  44. package/dist/LexicalLink.dev-DK87Biuy.mjs.map +1 -0
  45. package/dist/LexicalLink.prod-fssuv6Sf.mjs +717 -0
  46. package/dist/LexicalLink.prod-fssuv6Sf.mjs.map +1 -0
  47. package/dist/LexicalList.dev-BJ4dr_rk.mjs +1352 -0
  48. package/dist/LexicalList.dev-BJ4dr_rk.mjs.map +1 -0
  49. package/dist/LexicalList.prod-jWBbaWfi.mjs +841 -0
  50. package/dist/LexicalList.prod-jWBbaWfi.mjs.map +1 -0
  51. package/dist/LexicalMarkdown.dev-C8e-eh6y.mjs +1207 -0
  52. package/dist/LexicalMarkdown.dev-C8e-eh6y.mjs.map +1 -0
  53. package/dist/LexicalMarkdown.prod-k73tZVb2.mjs +756 -0
  54. package/dist/LexicalMarkdown.prod-k73tZVb2.mjs.map +1 -0
  55. package/dist/LexicalRichText.dev-CrSqq3K-.mjs +645 -0
  56. package/dist/LexicalRichText.dev-CrSqq3K-.mjs.map +1 -0
  57. package/dist/LexicalRichText.node-B7k7wlQz.mjs +106 -0
  58. package/dist/LexicalRichText.node-B7k7wlQz.mjs.map +1 -0
  59. package/dist/LexicalRichText.prod-CqvyxQ9m.mjs +429 -0
  60. package/dist/LexicalRichText.prod-CqvyxQ9m.mjs.map +1 -0
  61. package/dist/LexicalSelection.dev-sNOHKHe_.mjs +725 -0
  62. package/dist/LexicalSelection.dev-sNOHKHe_.mjs.map +1 -0
  63. package/dist/LexicalSelection.node-Di7GwBCZ.mjs +38 -0
  64. package/dist/LexicalSelection.node-Di7GwBCZ.mjs.map +1 -0
  65. package/dist/LexicalSelection.prod-SWllPJop.mjs +388 -0
  66. package/dist/LexicalSelection.prod-SWllPJop.mjs.map +1 -0
  67. package/dist/LexicalTable.dev-CQkLHXJx.mjs +3262 -0
  68. package/dist/LexicalTable.dev-CQkLHXJx.mjs.map +1 -0
  69. package/dist/LexicalTable.prod-BtqCwKSi.mjs +2218 -0
  70. package/dist/LexicalTable.prod-BtqCwKSi.mjs.map +1 -0
  71. package/dist/LexicalUtils.dev-DiUpsXE8.mjs +850 -0
  72. package/dist/LexicalUtils.dev-DiUpsXE8.mjs.map +1 -0
  73. package/dist/LexicalUtils.node-CmK462d1.mjs +66 -0
  74. package/dist/LexicalUtils.node-CmK462d1.mjs.map +1 -0
  75. package/dist/LexicalUtils.prod-bWwV4GAF.mjs +377 -0
  76. package/dist/LexicalUtils.prod-bWwV4GAF.mjs.map +1 -0
  77. package/dist/auth-DIFZzoMm.mjs +211 -0
  78. package/dist/auth-DIFZzoMm.mjs.map +1 -0
  79. package/dist/bin/mxs.d.mts +927 -0
  80. package/dist/bin/mxs.mjs +3249 -0
  81. package/dist/bin/mxs.mjs.map +1 -0
  82. package/dist/chunk-hT5z_Zn9.mjs +35 -0
  83. package/dist/config-store-DIu7x0ao.mjs +121 -0
  84. package/dist/config-store-DIu7x0ao.mjs.map +1 -0
  85. package/dist/create-B2AOQL1e.mjs +24 -0
  86. package/dist/create-B2AOQL1e.mjs.map +1 -0
  87. package/dist/create-CwjGcv2n.mjs +23 -0
  88. package/dist/create-CwjGcv2n.mjs.map +1 -0
  89. package/dist/create-DT1l2hue.mjs +23 -0
  90. package/dist/create-DT1l2hue.mjs.map +1 -0
  91. package/dist/create-DjlRHPXy.mjs +23 -0
  92. package/dist/create-DjlRHPXy.mjs.map +1 -0
  93. package/dist/create-Dz6rJJSS.mjs +19 -0
  94. package/dist/create-Dz6rJJSS.mjs.map +1 -0
  95. package/dist/delete-B4dGrrus.mjs +22 -0
  96. package/dist/delete-B4dGrrus.mjs.map +1 -0
  97. package/dist/delete-BH6ZngTz.mjs +22 -0
  98. package/dist/delete-BH6ZngTz.mjs.map +1 -0
  99. package/dist/delete-BrY5zJ6S.mjs +22 -0
  100. package/dist/delete-BrY5zJ6S.mjs.map +1 -0
  101. package/dist/delete-CaG2d_xt.mjs +31 -0
  102. package/dist/delete-CaG2d_xt.mjs.map +1 -0
  103. package/dist/delete-YzRliRn8.mjs +31 -0
  104. package/dist/delete-YzRliRn8.mjs.map +1 -0
  105. package/dist/document-output-BVB8emLt.mjs +145 -0
  106. package/dist/document-output-BVB8emLt.mjs.map +1 -0
  107. package/dist/edit-Bb0Ze4w6.mjs +79 -0
  108. package/dist/edit-Bb0Ze4w6.mjs.map +1 -0
  109. package/dist/edit-BeFmC3XD.mjs +80 -0
  110. package/dist/edit-BeFmC3XD.mjs.map +1 -0
  111. package/dist/edit-DLDw_ZWX.mjs +86 -0
  112. package/dist/edit-DLDw_ZWX.mjs.map +1 -0
  113. package/dist/edit-z55ofr1S.mjs +40 -0
  114. package/dist/edit-z55ofr1S.mjs.map +1 -0
  115. package/dist/editor-xrF-j3UE.mjs +42 -0
  116. package/dist/editor-xrF-j3UE.mjs.map +1 -0
  117. package/dist/envelope-overlays-DPAlMNW1.mjs +26 -0
  118. package/dist/envelope-overlays-DPAlMNW1.mjs.map +1 -0
  119. package/dist/get-2qjq0wgG.mjs +28 -0
  120. package/dist/get-2qjq0wgG.mjs.map +1 -0
  121. package/dist/get-BGAk1Zmv.mjs +14 -0
  122. package/dist/get-BGAk1Zmv.mjs.map +1 -0
  123. package/dist/get-CRR13lgj.mjs +10 -0
  124. package/dist/get-CRR13lgj.mjs.map +1 -0
  125. package/dist/get-ClkpDBTL.mjs +13 -0
  126. package/dist/get-ClkpDBTL.mjs.map +1 -0
  127. package/dist/get-DJfUJ3sP.mjs +10 -0
  128. package/dist/get-DJfUJ3sP.mjs.map +1 -0
  129. package/dist/get-DiqaQvoS.mjs +14 -0
  130. package/dist/get-DiqaQvoS.mjs.map +1 -0
  131. package/dist/index.d.mts +338 -0
  132. package/dist/index.mjs +10 -0
  133. package/dist/list-BYzhflDg.mjs +14 -0
  134. package/dist/list-BYzhflDg.mjs.map +1 -0
  135. package/dist/list-DY-tPNG-.mjs +10 -0
  136. package/dist/list-DY-tPNG-.mjs.map +1 -0
  137. package/dist/list-DlQSkbqx.mjs +10 -0
  138. package/dist/list-DlQSkbqx.mjs.map +1 -0
  139. package/dist/list-DsrA5wIz.mjs +15 -0
  140. package/dist/list-DsrA5wIz.mjs.map +1 -0
  141. package/dist/list-Fp4nKfQb.mjs +10 -0
  142. package/dist/list-Fp4nKfQb.mjs.map +1 -0
  143. package/dist/list-s_tloiEX.mjs +10 -0
  144. package/dist/list-s_tloiEX.mjs.map +1 -0
  145. package/dist/litexml-codec-CDoRloiR.mjs +13451 -0
  146. package/dist/litexml-codec-CDoRloiR.mjs.map +1 -0
  147. package/dist/login-CLOJ-fTJ.mjs +579 -0
  148. package/dist/login-CLOJ-fTJ.mjs.map +1 -0
  149. package/dist/logout-v8ihxsim.mjs +11 -0
  150. package/dist/logout-v8ihxsim.mjs.map +1 -0
  151. package/dist/onboarding-640IldLz.mjs +888 -0
  152. package/dist/onboarding-640IldLz.mjs.map +1 -0
  153. package/dist/output-BM7aBFwt.mjs +120 -0
  154. package/dist/output-BM7aBFwt.mjs.map +1 -0
  155. package/dist/output-CTnO1lYt.d.mts +16 -0
  156. package/dist/payload-CN11pUto.mjs +547 -0
  157. package/dist/payload-CN11pUto.mjs.map +1 -0
  158. package/dist/publish-DkTYB-eK.mjs +23 -0
  159. package/dist/publish-DkTYB-eK.mjs.map +1 -0
  160. package/dist/publish-pRBfTJfe.mjs +23 -0
  161. package/dist/publish-pRBfTJfe.mjs.map +1 -0
  162. package/dist/resolve-BogJOR7R.mjs +119 -0
  163. package/dist/resolve-BogJOR7R.mjs.map +1 -0
  164. package/dist/resolve-Bp1AfBmM.mjs +26 -0
  165. package/dist/resolve-Bp1AfBmM.mjs.map +1 -0
  166. package/dist/resolve-Bw5Po9yK.mjs +16 -0
  167. package/dist/resolve-Bw5Po9yK.mjs.map +1 -0
  168. package/dist/resolve-CyjMlaoJ.mjs +23 -0
  169. package/dist/resolve-CyjMlaoJ.mjs.map +1 -0
  170. package/dist/resolve-helpers-CahPoJ0Y.mjs +30 -0
  171. package/dist/resolve-helpers-CahPoJ0Y.mjs.map +1 -0
  172. package/dist/set-BEGQz2si.mjs +43 -0
  173. package/dist/set-BEGQz2si.mjs.map +1 -0
  174. package/dist/shared-D0HVBDHI.mjs +39 -0
  175. package/dist/shared-D0HVBDHI.mjs.map +1 -0
  176. package/dist/status-LXrN9fI-.mjs +22 -0
  177. package/dist/status-LXrN9fI-.mjs.map +1 -0
  178. package/dist/update-B9ynFCdZ.mjs +30 -0
  179. package/dist/update-B9ynFCdZ.mjs.map +1 -0
  180. package/dist/update-BMZQPOvR.mjs +28 -0
  181. package/dist/update-BMZQPOvR.mjs.map +1 -0
  182. package/dist/update-BXz0l7Lz.mjs +36 -0
  183. package/dist/update-BXz0l7Lz.mjs.map +1 -0
  184. package/dist/update-Dx6AF8tf.mjs +30 -0
  185. package/dist/update-Dx6AF8tf.mjs.map +1 -0
  186. package/dist/update-q66TLS38.mjs +37 -0
  187. package/dist/update-q66TLS38.mjs.map +1 -0
  188. package/dist/whoami-CTkctOEd.mjs +22 -0
  189. package/dist/whoami-CTkctOEd.mjs.map +1 -0
  190. package/package.json +77 -0
@@ -0,0 +1,121 @@
1
+ import { s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import path from "node:path";
3
+ import { promises } from "node:fs";
4
+ import os from "node:os";
5
+ //#region src/core/config-store.ts
6
+ const DEFAULT_CLIENT_ID = "mxs-cli";
7
+ function getConfigDir() {
8
+ const xdg = process.env.XDG_CONFIG_HOME;
9
+ const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), ".config");
10
+ return path.join(base, "mxs");
11
+ }
12
+ function getConfigPath() {
13
+ return path.join(getConfigDir(), "config.json");
14
+ }
15
+ function getCredentialsPath() {
16
+ return path.join(getConfigDir(), "credentials.json");
17
+ }
18
+ async function readJsonIfExists(p) {
19
+ try {
20
+ const raw = await promises.readFile(p, "utf8");
21
+ return JSON.parse(raw);
22
+ } catch (err) {
23
+ if (err?.code === "ENOENT") return null;
24
+ if (err instanceof SyntaxError) throw new MxsError({
25
+ code: "generic",
26
+ message: `failed to parse ${p}: ${err.message}`
27
+ });
28
+ throw err;
29
+ }
30
+ }
31
+ async function readConfig() {
32
+ return await readJsonIfExists(getConfigPath()) ?? {};
33
+ }
34
+ async function writeConfig(cfg) {
35
+ const dir = getConfigDir();
36
+ await promises.mkdir(dir, { recursive: true });
37
+ await promises.writeFile(getConfigPath(), JSON.stringify(cfg, null, 2), { mode: 420 });
38
+ try {
39
+ await promises.chmod(getConfigPath(), 420);
40
+ } catch {}
41
+ }
42
+ async function readCredentials() {
43
+ const p = getCredentialsPath();
44
+ const data = await readJsonIfExists(p);
45
+ if (data) await enforceCredentialsMode(p);
46
+ return data;
47
+ }
48
+ async function writeCredentials(cred) {
49
+ const dir = getConfigDir();
50
+ await promises.mkdir(dir, { recursive: true });
51
+ const p = getCredentialsPath();
52
+ await promises.writeFile(p, JSON.stringify(cred, null, 2), { mode: 384 });
53
+ await promises.chmod(p, 384);
54
+ }
55
+ async function deleteCredentials() {
56
+ const p = getCredentialsPath();
57
+ try {
58
+ await promises.unlink(p);
59
+ } catch (err) {
60
+ if (err?.code !== "ENOENT") throw err;
61
+ }
62
+ }
63
+ async function enforceCredentialsMode(p = getCredentialsPath()) {
64
+ let stats;
65
+ try {
66
+ stats = await promises.stat(p);
67
+ } catch (err) {
68
+ if (err?.code === "ENOENT") return false;
69
+ throw err;
70
+ }
71
+ const mode = stats.mode & 511;
72
+ if (mode !== 384) {
73
+ process.stderr.write(`mxs: credentials file ${p} had mode ${mode.toString(8)}; chmod 600\n`);
74
+ await promises.chmod(p, 384);
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ function normalizeApiUrl(input) {
80
+ let url = input.trim();
81
+ if (!url) throw new MxsError({
82
+ code: "config.missing.api_url",
83
+ message: "API URL is empty"
84
+ });
85
+ if (!/^https?:\/\//i.test(url)) url = /^(?:localhost|127\.0\.0\.1|::1)(?::\d+)?$/i.test(url) ? `http://${url}` : `https://${url}`;
86
+ return url.replace(/\/+$/, "");
87
+ }
88
+ async function resolveConfig(overrides = {}) {
89
+ const envApiUrl = process.env.MXS_API_URL?.trim();
90
+ const envToken = process.env.MXS_TOKEN?.trim();
91
+ const envApiKey = process.env.MXS_API_KEY?.trim();
92
+ const file = await readConfig();
93
+ const credentials = await readCredentials();
94
+ const rawApiUrl = overrides.apiUrl || envApiUrl || file.api_url;
95
+ if (!rawApiUrl) throw new MxsError({
96
+ code: "config.missing.api_url",
97
+ message: "API URL is not configured",
98
+ hint: "set MXS_API_URL or pass --api-url <url>, or run `mxs auth login` in an interactive shell"
99
+ });
100
+ const apiUrl = normalizeApiUrl(rawApiUrl);
101
+ const apiVersion = file.api_version ?? 2;
102
+ const apiBase = overrides.apiUrl || envApiUrl ? `${apiUrl}/api/v${apiVersion}` : file.api_base || `${apiUrl}/api/v${apiVersion}`;
103
+ const authBase = overrides.apiUrl || envApiUrl ? `${apiBase}/auth` : file.auth_base || `${apiBase}/auth`;
104
+ const token = overrides.token || envToken || credentials?.access_token;
105
+ const apiKey = overrides.apiKey || envApiKey;
106
+ return {
107
+ apiUrl,
108
+ apiBase,
109
+ authBase,
110
+ apiVersion,
111
+ clientId: file.client_id || DEFAULT_CLIENT_ID,
112
+ token,
113
+ apiKey,
114
+ configPath: getConfigPath(),
115
+ credentialsPath: getCredentialsPath()
116
+ };
117
+ }
118
+ //#endregion
119
+ export { getCredentialsPath as a, readCredentials as c, writeCredentials as d, getConfigPath as i, resolveConfig as l, enforceCredentialsMode as n, normalizeApiUrl as o, getConfigDir as r, readConfig as s, deleteCredentials as t, writeConfig as u };
120
+
121
+ //# sourceMappingURL=config-store-DIu7x0ao.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store-DIu7x0ao.mjs","names":["fs"],"sources":["../src/core/config-store.ts"],"sourcesContent":["import { promises as fs } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { MxsError } from './errors'\n\nexport interface ConfigShape {\n api_url?: string\n api_base?: string\n auth_base?: string\n api_version?: number\n client_id?: string\n}\n\nexport interface CredentialsShape {\n access_token: string\n refresh_token?: string\n expires_at: number\n user?: {\n id?: string\n email?: string\n name?: string\n }\n}\n\nexport interface ResolvedConfig {\n apiUrl: string\n apiBase: string\n authBase: string\n apiVersion: number\n clientId: string\n token?: string\n apiKey?: string\n configPath: string\n credentialsPath: string\n}\n\nexport interface StoreOverrides {\n apiUrl?: string\n token?: string\n apiKey?: string\n}\n\nconst DEFAULT_CLIENT_ID = 'mxs-cli'\n\nexport function getConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME\n const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), '.config')\n return path.join(base, 'mxs')\n}\n\nexport function getConfigPath(): string {\n return path.join(getConfigDir(), 'config.json')\n}\n\nexport function getCredentialsPath(): string {\n return path.join(getConfigDir(), 'credentials.json')\n}\n\nasync function readJsonIfExists<T>(p: string): Promise<T | null> {\n try {\n const raw = await fs.readFile(p, 'utf8')\n return JSON.parse(raw) as T\n } catch (err: any) {\n if (err?.code === 'ENOENT') return null\n if (err instanceof SyntaxError) {\n throw new MxsError({\n code: 'generic',\n message: `failed to parse ${p}: ${err.message}`,\n })\n }\n throw err\n }\n}\n\nexport async function readConfig(): Promise<ConfigShape> {\n const data = await readJsonIfExists<ConfigShape>(getConfigPath())\n return data ?? {}\n}\n\nexport async function writeConfig(cfg: ConfigShape): Promise<void> {\n const dir = getConfigDir()\n await fs.mkdir(dir, { recursive: true })\n await fs.writeFile(getConfigPath(), JSON.stringify(cfg, null, 2), {\n mode: 0o644,\n })\n try {\n await fs.chmod(getConfigPath(), 0o644)\n } catch {}\n}\n\nexport async function readCredentials(): Promise<CredentialsShape | null> {\n const p = getCredentialsPath()\n const data = await readJsonIfExists<CredentialsShape>(p)\n if (data) {\n await enforceCredentialsMode(p)\n }\n return data\n}\n\nexport async function writeCredentials(cred: CredentialsShape): Promise<void> {\n const dir = getConfigDir()\n await fs.mkdir(dir, { recursive: true })\n const p = getCredentialsPath()\n await fs.writeFile(p, JSON.stringify(cred, null, 2), { mode: 0o600 })\n await fs.chmod(p, 0o600)\n}\n\nexport async function deleteCredentials(): Promise<void> {\n const p = getCredentialsPath()\n try {\n await fs.unlink(p)\n } catch (err: any) {\n if (err?.code !== 'ENOENT') throw err\n }\n}\n\nexport async function enforceCredentialsMode(\n p = getCredentialsPath(),\n): Promise<boolean> {\n let stats\n try {\n stats = await fs.stat(p)\n } catch (err: any) {\n if (err?.code === 'ENOENT') return false\n throw err\n }\n const mode = stats.mode & 0o777\n if (mode !== 0o600) {\n process.stderr.write(\n `mxs: credentials file ${p} had mode ${mode.toString(8)}; chmod 600\\n`,\n )\n await fs.chmod(p, 0o600)\n return true\n }\n return false\n}\n\nexport function normalizeApiUrl(input: string): string {\n let url = input.trim()\n if (!url) {\n throw new MxsError({\n code: 'config.missing.api_url',\n message: 'API URL is empty',\n })\n }\n if (!/^https?:\\/\\//i.test(url)) {\n const isLocal = /^(?:localhost|127\\.0\\.0\\.1|::1)(?::\\d+)?$/i.test(url)\n url = isLocal ? `http://${url}` : `https://${url}`\n }\n return url.replace(/\\/+$/, '')\n}\n\nexport async function resolveConfig(\n overrides: StoreOverrides = {},\n): Promise<ResolvedConfig> {\n const envApiUrl = process.env.MXS_API_URL?.trim()\n const envToken = process.env.MXS_TOKEN?.trim()\n const envApiKey = process.env.MXS_API_KEY?.trim()\n\n const file = await readConfig()\n const credentials = await readCredentials()\n\n const rawApiUrl = overrides.apiUrl || envApiUrl || file.api_url\n if (!rawApiUrl) {\n throw new MxsError({\n code: 'config.missing.api_url',\n message: 'API URL is not configured',\n hint: 'set MXS_API_URL or pass --api-url <url>, or run `mxs auth login` in an interactive shell',\n })\n }\n const apiUrl = normalizeApiUrl(rawApiUrl)\n const apiVersion = file.api_version ?? 2\n const apiBase =\n overrides.apiUrl || envApiUrl\n ? `${apiUrl}/api/v${apiVersion}`\n : file.api_base || `${apiUrl}/api/v${apiVersion}`\n const authBase =\n overrides.apiUrl || envApiUrl\n ? `${apiBase}/auth`\n : file.auth_base || `${apiBase}/auth`\n\n const token = overrides.token || envToken || credentials?.access_token\n const apiKey = overrides.apiKey || envApiKey\n\n return {\n apiUrl,\n apiBase,\n authBase,\n apiVersion,\n clientId: file.client_id || DEFAULT_CLIENT_ID,\n token,\n apiKey,\n configPath: getConfigPath(),\n credentialsPath: getCredentialsPath(),\n }\n}\n"],"mappings":";;;;;AA2CA,MAAM,oBAAoB;AAE1B,SAAgB,eAAuB;CACrC,MAAM,MAAM,QAAQ,IAAI;CACxB,MAAM,OAAO,OAAO,IAAI,SAAS,IAAI,MAAM,KAAK,KAAK,GAAG,QAAQ,GAAG,SAAS;CAC5E,OAAO,KAAK,KAAK,MAAM,KAAK;AAC9B;AAEA,SAAgB,gBAAwB;CACtC,OAAO,KAAK,KAAK,aAAa,GAAG,aAAa;AAChD;AAEA,SAAgB,qBAA6B;CAC3C,OAAO,KAAK,KAAK,aAAa,GAAG,kBAAkB;AACrD;AAEA,eAAe,iBAAoB,GAA8B;CAC/D,IAAI;EACF,MAAM,MAAM,MAAMA,SAAG,SAAS,GAAG,MAAM;EACvC,OAAO,KAAK,MAAM,GAAG;CACvB,SAAS,KAAU;EACjB,IAAI,KAAK,SAAS,UAAU,OAAO;EACnC,IAAI,eAAe,aACjB,MAAM,IAAI,SAAS;GACjB,MAAM;GACN,SAAS,mBAAmB,EAAE,IAAI,IAAI;EACxC,CAAC;EAEH,MAAM;CACR;AACF;AAEA,eAAsB,aAAmC;CAEvD,OAAO,MADY,iBAA8B,cAAc,CAAC,KACjD,CAAC;AAClB;AAEA,eAAsB,YAAY,KAAiC;CACjE,MAAM,MAAM,aAAa;CACzB,MAAMA,SAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;CACvC,MAAMA,SAAG,UAAU,cAAc,GAAG,KAAK,UAAU,KAAK,MAAM,CAAC,GAAG,EAChE,MAAM,IACR,CAAC;CACD,IAAI;EACF,MAAMA,SAAG,MAAM,cAAc,GAAG,GAAK;CACvC,QAAQ,CAAC;AACX;AAEA,eAAsB,kBAAoD;CACxE,MAAM,IAAI,mBAAmB;CAC7B,MAAM,OAAO,MAAM,iBAAmC,CAAC;CACvD,IAAI,MACF,MAAM,uBAAuB,CAAC;CAEhC,OAAO;AACT;AAEA,eAAsB,iBAAiB,MAAuC;CAC5E,MAAM,MAAM,aAAa;CACzB,MAAMA,SAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;CACvC,MAAM,IAAI,mBAAmB;CAC7B,MAAMA,SAAG,UAAU,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;CACpE,MAAMA,SAAG,MAAM,GAAG,GAAK;AACzB;AAEA,eAAsB,oBAAmC;CACvD,MAAM,IAAI,mBAAmB;CAC7B,IAAI;EACF,MAAMA,SAAG,OAAO,CAAC;CACnB,SAAS,KAAU;EACjB,IAAI,KAAK,SAAS,UAAU,MAAM;CACpC;AACF;AAEA,eAAsB,uBACpB,IAAI,mBAAmB,GACL;CAClB,IAAI;CACJ,IAAI;EACF,QAAQ,MAAMA,SAAG,KAAK,CAAC;CACzB,SAAS,KAAU;EACjB,IAAI,KAAK,SAAS,UAAU,OAAO;EACnC,MAAM;CACR;CACA,MAAM,OAAO,MAAM,OAAO;CAC1B,IAAI,SAAS,KAAO;EAClB,QAAQ,OAAO,MACb,yBAAyB,EAAE,YAAY,KAAK,SAAS,CAAC,EAAE,cAC1D;EACA,MAAMA,SAAG,MAAM,GAAG,GAAK;EACvB,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAAuB;CACrD,IAAI,MAAM,MAAM,KAAK;CACrB,IAAI,CAAC,KACH,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,CAAC,gBAAgB,KAAK,GAAG,GAE3B,MADgB,6CAA6C,KAAK,GACtD,IAAI,UAAU,QAAQ,WAAW;CAE/C,OAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;AAEA,eAAsB,cACpB,YAA4B,CAAC,GACJ;CACzB,MAAM,YAAY,QAAQ,IAAI,aAAa,KAAK;CAChD,MAAM,WAAW,QAAQ,IAAI,WAAW,KAAK;CAC7C,MAAM,YAAY,QAAQ,IAAI,aAAa,KAAK;CAEhD,MAAM,OAAO,MAAM,WAAW;CAC9B,MAAM,cAAc,MAAM,gBAAgB;CAE1C,MAAM,YAAY,UAAU,UAAU,aAAa,KAAK;CACxD,IAAI,CAAC,WACH,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CAEH,MAAM,SAAS,gBAAgB,SAAS;CACxC,MAAM,aAAa,KAAK,eAAe;CACvC,MAAM,UACJ,UAAU,UAAU,YAChB,GAAG,OAAO,QAAQ,eAClB,KAAK,YAAY,GAAG,OAAO,QAAQ;CACzC,MAAM,WACJ,UAAU,UAAU,YAChB,GAAG,QAAQ,SACX,KAAK,aAAa,GAAG,QAAQ;CAEnC,MAAM,QAAQ,UAAU,SAAS,YAAY,aAAa;CAC1D,MAAM,SAAS,UAAU,UAAU;CAEnC,OAAO;EACL;EACA;EACA;EACA;EACA,UAAU,KAAK,aAAa;EAC5B;EACA;EACA,YAAY,cAAc;EAC1B,iBAAiB,mBAAmB;CACtC;AACF"}
@@ -0,0 +1,24 @@
1
+ import { i as emitSuccess, r as emitInfo } from "./output-BM7aBFwt.mjs";
2
+ import { r as buildPostPayload } from "./payload-CN11pUto.mjs";
3
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
4
+ import { n as resolveCategoryRefs, t as buildResolver } from "./resolve-helpers-CahPoJ0Y.mjs";
5
+ //#region src/commands/post/create.ts
6
+ async function run(opts, flags, out) {
7
+ const built = await buildPostPayload(opts);
8
+ if (flags.dryRun) {
9
+ emitInfo("dry-run — payload below", out);
10
+ emitSuccess(built.payload, out);
11
+ return;
12
+ }
13
+ const client = buildApiClient(await resolveContext(flags, out), flags);
14
+ const resolver = buildResolver(client);
15
+ await resolveCategoryRefs(built.payload, resolver);
16
+ emitSuccess((await client.request("/posts", {
17
+ method: "POST",
18
+ body: built.payload
19
+ })).data, out);
20
+ }
21
+ //#endregion
22
+ export { run };
23
+
24
+ //# sourceMappingURL=create-B2AOQL1e.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-B2AOQL1e.mjs","names":[],"sources":["../src/commands/post/create.ts"],"sourcesContent":["import { emitInfo, emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildPostPayload, type PostFlagInputs } from '../../core/payload'\nimport { buildResolver, resolveCategoryRefs } from '../internal/resolve-helpers'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport async function run(\n opts: PostFlagInputs,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const built = await buildPostPayload(opts)\n if (flags.dryRun) {\n emitInfo('dry-run — payload below', out)\n emitSuccess(built.payload, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const resolver = buildResolver(client)\n await resolveCategoryRefs(built.payload, resolver)\n const res = await client.request('/posts', {\n method: 'POST',\n body: built.payload,\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;;;AAKA,eAAsB,IACpB,MACA,OACA,KACA;CACA,MAAM,QAAQ,MAAM,iBAAiB,IAAI;CACzC,IAAI,MAAM,QAAQ;EAChB,SAAS,2BAA2B,GAAG;EACvC,YAAY,MAAM,SAAS,GAAG;EAC9B;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,WAAW,cAAc,MAAM;CACrC,MAAM,oBAAoB,MAAM,SAAS,QAAQ;CAKjD,aAAY,MAJM,OAAO,QAAQ,UAAU;EACzC,QAAQ;EACR,MAAM,MAAM;CACd,CAAC,GACe,MAAM,GAAG;AAC3B"}
@@ -0,0 +1,23 @@
1
+ import { i as emitSuccess } from "./output-BM7aBFwt.mjs";
2
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
3
+ //#region src/commands/category/create.ts
4
+ async function run(opts, flags, out) {
5
+ const body = {
6
+ name: opts.name,
7
+ slug: opts.slug
8
+ };
9
+ if (opts.type) body.type = opts.type === "tag" ? 1 : 0;
10
+ if (opts.icon) body.icon = opts.icon;
11
+ if (flags.dryRun) {
12
+ emitSuccess(body, out);
13
+ return;
14
+ }
15
+ emitSuccess((await buildApiClient(await resolveContext(flags, out), flags).request("/categories", {
16
+ method: "POST",
17
+ body
18
+ })).data, out);
19
+ }
20
+ //#endregion
21
+ export { run };
22
+
23
+ //# sourceMappingURL=create-CwjGcv2n.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-CwjGcv2n.mjs","names":[],"sources":["../src/commands/category/create.ts"],"sourcesContent":["import { emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport interface CategoryCreateFlags {\n name: string\n slug: string\n type?: 'category' | 'tag'\n icon?: string\n}\n\nexport async function run(\n opts: CategoryCreateFlags,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const body: Record<string, unknown> = {\n name: opts.name,\n slug: opts.slug,\n }\n if (opts.type) body.type = opts.type === 'tag' ? 1 : 0\n if (opts.icon) body.icon = opts.icon\n if (flags.dryRun) {\n emitSuccess(body, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const res = await client.request('/categories', {\n method: 'POST',\n body,\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;AAUA,eAAsB,IACpB,MACA,OACA,KACA;CACA,MAAM,OAAgC;EACpC,MAAM,KAAK;EACX,MAAM,KAAK;CACb;CACA,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,SAAS,QAAQ,IAAI;CACrD,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK;CAChC,IAAI,MAAM,QAAQ;EAChB,YAAY,MAAM,GAAG;EACrB;CACF;CAOA,aAAY,MALG,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KACZ,EAAE,QAAQ,eAAe;EAC9C,QAAQ;EACR;CACF,CAAC,GACe,MAAM,GAAG;AAC3B"}
@@ -0,0 +1,23 @@
1
+ import { i as emitSuccess } from "./output-BM7aBFwt.mjs";
2
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
3
+ //#region src/commands/topic/create.ts
4
+ async function run(opts, flags, out) {
5
+ const body = {
6
+ name: opts.name,
7
+ slug: opts.slug
8
+ };
9
+ if (opts.description) body.description = opts.description;
10
+ if (opts.icon) body.icon = opts.icon;
11
+ if (flags.dryRun) {
12
+ emitSuccess(body, out);
13
+ return;
14
+ }
15
+ emitSuccess((await buildApiClient(await resolveContext(flags, out), flags).request("/topics", {
16
+ method: "POST",
17
+ body
18
+ })).data, out);
19
+ }
20
+ //#endregion
21
+ export { run };
22
+
23
+ //# sourceMappingURL=create-DT1l2hue.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-DT1l2hue.mjs","names":[],"sources":["../src/commands/topic/create.ts"],"sourcesContent":["import { emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport interface TopicCreateFlags {\n name: string\n slug: string\n description?: string\n icon?: string\n}\n\nexport async function run(\n opts: TopicCreateFlags,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const body: Record<string, unknown> = {\n name: opts.name,\n slug: opts.slug,\n }\n if (opts.description) body.description = opts.description\n if (opts.icon) body.icon = opts.icon\n if (flags.dryRun) {\n emitSuccess(body, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const res = await client.request('/topics', { method: 'POST', body })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;AAUA,eAAsB,IACpB,MACA,OACA,KACA;CACA,MAAM,OAAgC;EACpC,MAAM,KAAK;EACX,MAAM,KAAK;CACb;CACA,IAAI,KAAK,aAAa,KAAK,cAAc,KAAK;CAC9C,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK;CAChC,IAAI,MAAM,QAAQ;EAChB,YAAY,MAAM,GAAG;EACrB;CACF;CAIA,aAAY,MAFG,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KACZ,EAAE,QAAQ,WAAW;EAAE,QAAQ;EAAQ;CAAK,CAAC,GACpD,MAAM,GAAG;AAC3B"}
@@ -0,0 +1,23 @@
1
+ import { i as emitSuccess } from "./output-BM7aBFwt.mjs";
2
+ import { t as buildNotePayload } from "./payload-CN11pUto.mjs";
3
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
4
+ import { r as resolveTopicRefs, t as buildResolver } from "./resolve-helpers-CahPoJ0Y.mjs";
5
+ //#region src/commands/note/create.ts
6
+ async function run(opts, flags, out) {
7
+ const built = await buildNotePayload(opts);
8
+ if (flags.dryRun) {
9
+ emitSuccess(built.payload, out);
10
+ return;
11
+ }
12
+ const client = buildApiClient(await resolveContext(flags, out), flags);
13
+ const resolver = buildResolver(client);
14
+ await resolveTopicRefs(built.payload, resolver);
15
+ emitSuccess((await client.request("/notes", {
16
+ method: "POST",
17
+ body: built.payload
18
+ })).data, out);
19
+ }
20
+ //#endregion
21
+ export { run };
22
+
23
+ //# sourceMappingURL=create-DjlRHPXy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-DjlRHPXy.mjs","names":[],"sources":["../src/commands/note/create.ts"],"sourcesContent":["import { emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildNotePayload, type NoteFlagInputs } from '../../core/payload'\nimport { buildResolver, resolveTopicRefs } from '../internal/resolve-helpers'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport async function run(\n opts: NoteFlagInputs,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const built = await buildNotePayload(opts)\n if (flags.dryRun) {\n emitSuccess(built.payload, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const resolver = buildResolver(client)\n await resolveTopicRefs(built.payload, resolver)\n const res = await client.request('/notes', {\n method: 'POST',\n body: built.payload,\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;;;AAKA,eAAsB,IACpB,MACA,OACA,KACA;CACA,MAAM,QAAQ,MAAM,iBAAiB,IAAI;CACzC,IAAI,MAAM,QAAQ;EAChB,YAAY,MAAM,SAAS,GAAG;EAC9B;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,WAAW,cAAc,MAAM;CACrC,MAAM,iBAAiB,MAAM,SAAS,QAAQ;CAK9C,aAAY,MAJM,OAAO,QAAQ,UAAU;EACzC,QAAQ;EACR,MAAM,MAAM;CACd,CAAC,GACe,MAAM,GAAG;AAC3B"}
@@ -0,0 +1,19 @@
1
+ import { i as emitSuccess } from "./output-BM7aBFwt.mjs";
2
+ import { n as buildPagePayload } from "./payload-CN11pUto.mjs";
3
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
4
+ //#region src/commands/page/create.ts
5
+ async function run(_id, opts, flags, out) {
6
+ const built = await buildPagePayload(opts);
7
+ if (flags.dryRun) {
8
+ emitSuccess(built.payload, out);
9
+ return;
10
+ }
11
+ emitSuccess((await buildApiClient(await resolveContext(flags, out), flags).request("/pages", {
12
+ method: "POST",
13
+ body: built.payload
14
+ })).data, out);
15
+ }
16
+ //#endregion
17
+ export { run };
18
+
19
+ //# sourceMappingURL=create-Dz6rJJSS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-Dz6rJJSS.mjs","names":[],"sources":["../src/commands/page/create.ts"],"sourcesContent":["import { emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildPagePayload, type PageFlagInputs } from '../../core/payload'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport async function run(\n _id: unknown,\n opts: PageFlagInputs,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const built = await buildPagePayload(opts)\n if (flags.dryRun) {\n emitSuccess(built.payload, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const res = await client.request('/pages', {\n method: 'POST',\n body: built.payload,\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;;AAIA,eAAsB,IACpB,KACA,MACA,OACA,KACA;CACA,MAAM,QAAQ,MAAM,iBAAiB,IAAI;CACzC,IAAI,MAAM,QAAQ;EAChB,YAAY,MAAM,SAAS,GAAG;EAC9B;CACF;CAOA,aAAY,MALG,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KACZ,EAAE,QAAQ,UAAU;EACzC,QAAQ;EACR,MAAM,MAAM;CACd,CAAC,GACe,MAAM,GAAG;AAC3B"}
@@ -0,0 +1,22 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
3
+ import { t as resolvePostId } from "./resolve-Bp1AfBmM.mjs";
4
+ //#region src/commands/post/delete.ts
5
+ async function run(slugOrId, opts, flags, out) {
6
+ if (!opts.force && !flags.dryRun && !process.stdin.isTTY) throw new MxsError({
7
+ code: "validation.failed",
8
+ message: "refusing to delete without --force in non-TTY context"
9
+ });
10
+ if (flags.dryRun) {
11
+ emitSuccess({ would_delete: slugOrId }, out);
12
+ return;
13
+ }
14
+ const client = buildApiClient(await resolveContext(flags, out), flags);
15
+ const id = await resolvePostId(client, slugOrId);
16
+ await client.request(`/posts/${id}`, { method: "DELETE" });
17
+ emitSuccess({ deleted: id }, out);
18
+ }
19
+ //#endregion
20
+ export { run };
21
+
22
+ //# sourceMappingURL=delete-B4dGrrus.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-B4dGrrus.mjs","names":[],"sources":["../src/commands/post/delete.ts"],"sourcesContent":["import { MxsError } from '../../core/errors'\nimport { emitSuccess, type OutputOptions } from '../../core/output'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\nimport { resolvePostId } from './resolve'\n\nexport async function run(\n slugOrId: string,\n opts: { force?: boolean },\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n if (!opts.force && !flags.dryRun && !process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'refusing to delete without --force in non-TTY context',\n })\n }\n if (flags.dryRun) {\n emitSuccess({ would_delete: slugOrId }, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolvePostId(client, slugOrId)\n await client.request(`/posts/${id}`, { method: 'DELETE' })\n emitSuccess({ deleted: id }, out)\n}\n"],"mappings":";;;;AAKA,eAAsB,IACpB,UACA,MACA,OACA,KACA;CACA,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,MAAM,OACjD,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,cAAc,SAAS,GAAG,GAAG;EAC3C;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,cAAc,QAAQ,QAAQ;CAC/C,MAAM,OAAO,QAAQ,UAAU,MAAM,EAAE,QAAQ,SAAS,CAAC;CACzD,YAAY,EAAE,SAAS,GAAG,GAAG,GAAG;AAClC"}
@@ -0,0 +1,22 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
3
+ import { t as resolveNoteId } from "./resolve-CyjMlaoJ.mjs";
4
+ //#region src/commands/note/delete.ts
5
+ async function run(slugOrId, opts, flags, out) {
6
+ if (!opts.force && !flags.dryRun && !process.stdin.isTTY) throw new MxsError({
7
+ code: "validation.failed",
8
+ message: "refusing to delete without --force in non-TTY context"
9
+ });
10
+ if (flags.dryRun) {
11
+ emitSuccess({ would_delete: slugOrId }, out);
12
+ return;
13
+ }
14
+ const client = buildApiClient(await resolveContext(flags, out), flags);
15
+ const id = await resolveNoteId(client, slugOrId);
16
+ await client.request(`/notes/${id}`, { method: "DELETE" });
17
+ emitSuccess({ deleted: id }, out);
18
+ }
19
+ //#endregion
20
+ export { run };
21
+
22
+ //# sourceMappingURL=delete-BH6ZngTz.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-BH6ZngTz.mjs","names":[],"sources":["../src/commands/note/delete.ts"],"sourcesContent":["import { MxsError } from '../../core/errors'\nimport { emitSuccess, type OutputOptions } from '../../core/output'\nimport {\n buildApiClient,\n type GlobalFlags,\n resolveContext,\n} from '../internal/shared'\nimport { resolveNoteId } from './resolve'\n\nexport async function run(\n slugOrId: string,\n opts: { force?: boolean },\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n if (!opts.force && !flags.dryRun && !process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'refusing to delete without --force in non-TTY context',\n })\n }\n if (flags.dryRun) {\n emitSuccess({ would_delete: slugOrId }, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolveNoteId(client, slugOrId)\n await client.request(`/notes/${id}`, { method: 'DELETE' })\n emitSuccess({ deleted: id }, out)\n}\n"],"mappings":";;;;AASA,eAAsB,IACpB,UACA,MACA,OACA,KACA;CACA,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,MAAM,OACjD,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,cAAc,SAAS,GAAG,GAAG;EAC3C;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,cAAc,QAAQ,QAAQ;CAC/C,MAAM,OAAO,QAAQ,UAAU,MAAM,EAAE,QAAQ,SAAS,CAAC;CACzD,YAAY,EAAE,SAAS,GAAG,GAAG,GAAG;AAClC"}
@@ -0,0 +1,22 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
3
+ import { t as resolveCategoryId } from "./resolve-Bw5Po9yK.mjs";
4
+ //#region src/commands/category/delete.ts
5
+ async function run(slugOrId, opts, flags, out) {
6
+ if (!opts.force && !flags.dryRun && !process.stdin.isTTY) throw new MxsError({
7
+ code: "validation.failed",
8
+ message: "refusing to delete without --force in non-TTY context"
9
+ });
10
+ if (flags.dryRun) {
11
+ emitSuccess({ would_delete: slugOrId }, out);
12
+ return;
13
+ }
14
+ const client = buildApiClient(await resolveContext(flags, out), flags);
15
+ const id = await resolveCategoryId(client, slugOrId);
16
+ await client.request(`/categories/${id}`, { method: "DELETE" });
17
+ emitSuccess({ deleted: id }, out);
18
+ }
19
+ //#endregion
20
+ export { run };
21
+
22
+ //# sourceMappingURL=delete-BrY5zJ6S.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-BrY5zJ6S.mjs","names":[],"sources":["../src/commands/category/delete.ts"],"sourcesContent":["import { MxsError } from '../../core/errors'\nimport { emitSuccess, type OutputOptions } from '../../core/output'\nimport {\n buildApiClient,\n type GlobalFlags,\n resolveContext,\n} from '../internal/shared'\nimport { resolveCategoryId } from './resolve'\n\nexport async function run(\n slugOrId: string,\n opts: { force?: boolean },\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n if (!opts.force && !flags.dryRun && !process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'refusing to delete without --force in non-TTY context',\n })\n }\n if (flags.dryRun) {\n emitSuccess({ would_delete: slugOrId }, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolveCategoryId(client, slugOrId)\n await client.request(`/categories/${id}`, { method: 'DELETE' })\n emitSuccess({ deleted: id }, out)\n}\n"],"mappings":";;;;AASA,eAAsB,IACpB,UACA,MACA,OACA,KACA;CACA,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,MAAM,OACjD,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,cAAc,SAAS,GAAG,GAAG;EAC3C;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,kBAAkB,QAAQ,QAAQ;CACnD,MAAM,OAAO,QAAQ,eAAe,MAAM,EAAE,QAAQ,SAAS,CAAC;CAC9D,YAAY,EAAE,SAAS,GAAG,GAAG,GAAG;AAClC"}
@@ -0,0 +1,31 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { r as isSnowflakeId } from "./resolve-BogJOR7R.mjs";
3
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
4
+ //#region src/commands/page/delete.ts
5
+ async function run(slugOrId, opts, flags, out) {
6
+ if (!opts.force && !flags.dryRun && !process.stdin.isTTY) throw new MxsError({
7
+ code: "validation.failed",
8
+ message: "refusing to delete without --force in non-TTY context"
9
+ });
10
+ if (flags.dryRun) {
11
+ emitSuccess({ would_delete: slugOrId }, out);
12
+ return;
13
+ }
14
+ const client = buildApiClient(await resolveContext(flags, out), flags);
15
+ const id = await resolveId(client, slugOrId);
16
+ await client.request(`/pages/${id}`, { method: "DELETE" });
17
+ emitSuccess({ deleted: id }, out);
18
+ }
19
+ async function resolveId(client, slugOrId) {
20
+ if (isSnowflakeId(slugOrId)) return slugOrId;
21
+ const res = await client.request(`/pages/slug/${slugOrId}`);
22
+ if (!res.data?.id) throw new MxsError({
23
+ code: "resource.not_found",
24
+ message: `page not found: ${slugOrId}`
25
+ });
26
+ return res.data.id;
27
+ }
28
+ //#endregion
29
+ export { run };
30
+
31
+ //# sourceMappingURL=delete-CaG2d_xt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-CaG2d_xt.mjs","names":[],"sources":["../src/commands/page/delete.ts"],"sourcesContent":["import type { ApiClient } from '../../core/api-client'\nimport { MxsError } from '../../core/errors'\nimport { emitSuccess, type OutputOptions } from '../../core/output'\nimport { isSnowflakeId } from '../../core/resolve'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport async function run(\n slugOrId: string,\n opts: { force?: boolean },\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n if (!opts.force && !flags.dryRun && !process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'refusing to delete without --force in non-TTY context',\n })\n }\n if (flags.dryRun) {\n emitSuccess({ would_delete: slugOrId }, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolveId(client, slugOrId)\n await client.request(`/pages/${id}`, { method: 'DELETE' })\n emitSuccess({ deleted: id }, out)\n}\n\nasync function resolveId(client: ApiClient, slugOrId: string): Promise<string> {\n if (isSnowflakeId(slugOrId)) return slugOrId\n const res = await client.request<{ id: string }>(`/pages/slug/${slugOrId}`)\n if (!res.data?.id)\n throw new MxsError({\n code: 'resource.not_found',\n message: `page not found: ${slugOrId}`,\n })\n return res.data.id\n}\n"],"mappings":";;;;AAMA,eAAsB,IACpB,UACA,MACA,OACA,KACA;CACA,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,MAAM,OACjD,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,cAAc,SAAS,GAAG,GAAG;EAC3C;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,UAAU,QAAQ,QAAQ;CAC3C,MAAM,OAAO,QAAQ,UAAU,MAAM,EAAE,QAAQ,SAAS,CAAC;CACzD,YAAY,EAAE,SAAS,GAAG,GAAG,GAAG;AAClC;AAEA,eAAe,UAAU,QAAmB,UAAmC;CAC7E,IAAI,cAAc,QAAQ,GAAG,OAAO;CACpC,MAAM,MAAM,MAAM,OAAO,QAAwB,eAAe,UAAU;CAC1E,IAAI,CAAC,IAAI,MAAM,IACb,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS,mBAAmB;CAC9B,CAAC;CACH,OAAO,IAAI,KAAK;AAClB"}
@@ -0,0 +1,31 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { r as isSnowflakeId } from "./resolve-BogJOR7R.mjs";
3
+ import { n as resolveContext, t as buildApiClient } from "./shared-D0HVBDHI.mjs";
4
+ //#region src/commands/topic/delete.ts
5
+ async function run(slugOrId, opts, flags, out) {
6
+ if (!opts.force && !flags.dryRun && !process.stdin.isTTY) throw new MxsError({
7
+ code: "validation.failed",
8
+ message: "refusing to delete without --force in non-TTY context"
9
+ });
10
+ if (flags.dryRun) {
11
+ emitSuccess({ would_delete: slugOrId }, out);
12
+ return;
13
+ }
14
+ const client = buildApiClient(await resolveContext(flags, out), flags);
15
+ const id = await resolveId(client, slugOrId);
16
+ await client.request(`/topics/${id}`, { method: "DELETE" });
17
+ emitSuccess({ deleted: id }, out);
18
+ }
19
+ async function resolveId(client, slugOrId) {
20
+ if (isSnowflakeId(slugOrId)) return slugOrId;
21
+ const res = await client.request(`/topics/slug/${slugOrId}`);
22
+ if (!res.data?.id) throw new MxsError({
23
+ code: "resource.not_found",
24
+ message: `topic not found: ${slugOrId}`
25
+ });
26
+ return res.data.id;
27
+ }
28
+ //#endregion
29
+ export { run };
30
+
31
+ //# sourceMappingURL=delete-YzRliRn8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-YzRliRn8.mjs","names":[],"sources":["../src/commands/topic/delete.ts"],"sourcesContent":["import type { ApiClient } from '../../core/api-client'\nimport { MxsError } from '../../core/errors'\nimport { emitSuccess, type OutputOptions } from '../../core/output'\nimport { isSnowflakeId } from '../../core/resolve'\nimport { buildApiClient, type GlobalFlags, resolveContext } from '../internal/shared'\n\nexport async function run(\n slugOrId: string,\n opts: { force?: boolean },\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n if (!opts.force && !flags.dryRun && !process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'refusing to delete without --force in non-TTY context',\n })\n }\n if (flags.dryRun) {\n emitSuccess({ would_delete: slugOrId }, out)\n return\n }\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolveId(client, slugOrId)\n await client.request(`/topics/${id}`, { method: 'DELETE' })\n emitSuccess({ deleted: id }, out)\n}\n\nasync function resolveId(client: ApiClient, slugOrId: string): Promise<string> {\n if (isSnowflakeId(slugOrId)) return slugOrId\n const res = await client.request<{ id?: string }>(`/topics/slug/${slugOrId}`)\n if (!res.data?.id)\n throw new MxsError({\n code: 'resource.not_found',\n message: `topic not found: ${slugOrId}`,\n })\n return res.data.id\n}\n"],"mappings":";;;;AAMA,eAAsB,IACpB,UACA,MACA,OACA,KACA;CACA,IAAI,CAAC,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,MAAM,OACjD,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS;CACX,CAAC;CAEH,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,cAAc,SAAS,GAAG,GAAG;EAC3C;CACF;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,UAAU,QAAQ,QAAQ;CAC3C,MAAM,OAAO,QAAQ,WAAW,MAAM,EAAE,QAAQ,SAAS,CAAC;CAC1D,YAAY,EAAE,SAAS,GAAG,GAAG,GAAG;AAClC;AAEA,eAAe,UAAU,QAAmB,UAAmC;CAC7E,IAAI,cAAc,QAAQ,GAAG,OAAO;CACpC,MAAM,MAAM,MAAM,OAAO,QAAyB,gBAAgB,UAAU;CAC5E,IAAI,CAAC,IAAI,MAAM,IACb,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS,oBAAoB;CAC/B,CAAC;CACH,OAAO,IAAI,KAAK;AAClB"}
@@ -0,0 +1,145 @@
1
+ import { i as emitSuccess, s as MxsError } from "./output-BM7aBFwt.mjs";
2
+ import { i as serializeFromLexical } from "./litexml-codec-CDoRloiR.mjs";
3
+ //#region src/core/document-output.ts
4
+ const DOCUMENT_OUTPUT_MODES = new Set([
5
+ "pretty-json",
6
+ "json",
7
+ "readable",
8
+ "llm",
9
+ "envelope"
10
+ ]);
11
+ function emitDocument(kind, data, opts) {
12
+ const mode = opts.output ?? "pretty-json";
13
+ if (!DOCUMENT_OUTPUT_MODES.has(mode)) throw new MxsError({
14
+ code: "validation.failed",
15
+ message: `unsupported --output value: ${mode}`,
16
+ hint: "use --output pretty-json, json, readable, llm, or envelope"
17
+ });
18
+ if (opts.json || mode === "json" || mode === "pretty-json") {
19
+ emitSuccess(data, opts);
20
+ return;
21
+ }
22
+ const doc = unwrapDocument(data);
23
+ const rendered = mode === "envelope" ? renderDocumentEnvelope(kind, doc) : renderReadableDocument(kind, doc);
24
+ process.stdout.write(`${rendered}\n`);
25
+ }
26
+ function renderReadableDocument(kind, data) {
27
+ const doc = asRecord(data);
28
+ const lines = [kind];
29
+ const fields = collectReadableFields(kind, doc);
30
+ for (const [key, value] of fields) {
31
+ if (value === void 0 || value === null || value === "") continue;
32
+ lines.push(`${key}: ${formatScalar(value)}`);
33
+ }
34
+ const summary = firstString(doc, "summary", "subtitle");
35
+ if (summary) lines.push("", "summary:", summary);
36
+ const content = renderContent(doc);
37
+ if (content.body) lines.push("", `content_format: ${content.format}`, "", "content:", content.body);
38
+ return lines.join("\n");
39
+ }
40
+ function renderDocumentEnvelope(kind, data) {
41
+ const doc = asRecord(data);
42
+ const root = kind === "note" ? "mxnote" : "mxpost";
43
+ const metaLines = collectEnvelopeMeta(kind, doc).map(([key, value]) => renderEnvelopeMeta(key, value));
44
+ const content = renderContent(doc);
45
+ return `<${root}>
46
+ <meta>
47
+ ${metaLines.join("\n")}
48
+ </meta>
49
+ <content>
50
+ ${content.body}
51
+ </content>
52
+ </${root}>`;
53
+ }
54
+ function collectReadableFields(kind, doc) {
55
+ const base = [
56
+ ["id", first(doc, "id")],
57
+ ["title", first(doc, "title")],
58
+ ["slug", first(doc, "slug")]
59
+ ];
60
+ if (kind === "post") base.push(["state", publishState(doc)], ["category", relationLabel(first(doc, "category"))], ["tags", first(doc, "tags")], ["pin", first(doc, "pin")]);
61
+ else if (kind === "note") base.push(["nid", first(doc, "nid")], ["state", publishState(doc)], ["topic", relationLabel(first(doc, "topic"))], ["mood", first(doc, "mood")], ["weather", first(doc, "weather")], ["public_at", first(doc, "public_at", "publicAt")], ["bookmark", first(doc, "bookmark")]);
62
+ else base.push(["subtitle", first(doc, "subtitle")], ["order", first(doc, "order")]);
63
+ base.push(["created_at", first(doc, "created_at", "createdAt")], ["modified_at", first(doc, "modified_at", "modifiedAt")], ["source_lang", first(doc, "source_lang", "sourceLang")], ["translated", first(doc, "is_translated", "isTranslated")]);
64
+ return base;
65
+ }
66
+ function collectEnvelopeMeta(kind, doc) {
67
+ const meta = [["title", first(doc, "title")], ["slug", first(doc, "slug")]];
68
+ if (kind === "post") meta.push(["category", relationSlugOrLabel(first(doc, "category"))], ["state", publishState(doc) === "published" ? "publish" : "draft"], ["summary", first(doc, "summary")], ["tags", first(doc, "tags")]);
69
+ else if (kind === "note") meta.push(["topic", relationSlugOrLabel(first(doc, "topic"))], ["state", publishState(doc) === "published" ? "publish" : "draft"], ["mood", first(doc, "mood")], ["weather", first(doc, "weather")], ["publicAt", first(doc, "public_at", "publicAt")], ["bookmark", first(doc, "bookmark")], ["location", first(doc, "location")]);
70
+ else meta.push(["subtitle", first(doc, "subtitle")], ["order", first(doc, "order")]);
71
+ meta.push(["format", contentFormat(doc)]);
72
+ return meta.filter(([, value]) => value !== void 0 && value !== null && value !== "");
73
+ }
74
+ function renderContent(doc) {
75
+ const format = contentFormat(doc);
76
+ const content = firstString(doc, "content");
77
+ const text = firstString(doc, "text");
78
+ if (format === "lexical" && content) try {
79
+ return {
80
+ body: serializeFromLexical(JSON.parse(content)),
81
+ format: "litexml"
82
+ };
83
+ } catch {
84
+ return {
85
+ body: text || content,
86
+ format: text ? "text" : "markdown"
87
+ };
88
+ }
89
+ return {
90
+ body: content || text || "",
91
+ format: format === "markdown" ? "markdown" : "text"
92
+ };
93
+ }
94
+ function unwrapDocument(data) {
95
+ const nested = asRecord(data).data;
96
+ if (nested && typeof nested === "object" && !Array.isArray(nested)) return nested;
97
+ return data;
98
+ }
99
+ function asRecord(value) {
100
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
101
+ }
102
+ function first(record, ...keys) {
103
+ for (const key of keys) if (record[key] !== void 0 && record[key] !== null) return record[key];
104
+ }
105
+ function firstString(record, ...keys) {
106
+ const value = first(record, ...keys);
107
+ return typeof value === "string" ? value : "";
108
+ }
109
+ function contentFormat(doc) {
110
+ const value = first(doc, "content_format", "contentFormat");
111
+ return typeof value === "string" ? value : "markdown";
112
+ }
113
+ function publishState(doc) {
114
+ const value = first(doc, "is_published", "isPublished");
115
+ if (typeof value === "boolean") return value ? "published" : "draft";
116
+ }
117
+ function relationLabel(value) {
118
+ if (!value) return void 0;
119
+ if (typeof value === "string") return value;
120
+ const obj = asRecord(value);
121
+ return firstString(obj, "name") || firstString(obj, "slug") || firstString(obj, "id");
122
+ }
123
+ function relationSlugOrLabel(value) {
124
+ if (!value) return void 0;
125
+ if (typeof value === "string") return value;
126
+ const obj = asRecord(value);
127
+ return firstString(obj, "slug") || firstString(obj, "name") || firstString(obj, "id");
128
+ }
129
+ function formatScalar(value) {
130
+ if (Array.isArray(value)) return value.map(formatScalar).join(", ");
131
+ if (value instanceof Date) return value.toISOString();
132
+ if (typeof value === "object" && value !== null) return JSON.stringify(value);
133
+ return String(value);
134
+ }
135
+ function renderEnvelopeMeta(key, value) {
136
+ if (key === "tags" && Array.isArray(value)) return ` <tags>\n${value.map((item) => ` <tag>${escapeXml(formatScalar(item))}</tag>`).join("\n")}\n </tags>`;
137
+ return ` <${key}>${escapeXml(formatScalar(value))}</${key}>`;
138
+ }
139
+ function escapeXml(value) {
140
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
141
+ }
142
+ //#endregion
143
+ export { renderDocumentEnvelope as n, renderReadableDocument as r, emitDocument as t };
144
+
145
+ //# sourceMappingURL=document-output-BVB8emLt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-output-BVB8emLt.mjs","names":[],"sources":["../src/core/document-output.ts"],"sourcesContent":["import { MxsError } from './errors'\nimport { serializeFromLexical, type LexicalState } from './litexml-codec'\nimport { emitSuccess, type OutputOptions } from './output'\n\nexport type DocumentKind = 'post' | 'note' | 'page'\n\nconst DOCUMENT_OUTPUT_MODES = new Set([\n 'pretty-json',\n 'json',\n 'readable',\n 'llm',\n 'envelope',\n])\n\nexport function emitDocument(\n kind: DocumentKind,\n data: unknown,\n opts: OutputOptions,\n): void {\n const mode = opts.output ?? 'pretty-json'\n if (!DOCUMENT_OUTPUT_MODES.has(mode)) {\n throw new MxsError({\n code: 'validation.failed',\n message: `unsupported --output value: ${mode}`,\n hint: 'use --output pretty-json, json, readable, llm, or envelope',\n })\n }\n\n if (opts.json || mode === 'json' || mode === 'pretty-json') {\n emitSuccess(data, opts)\n return\n }\n\n const doc = unwrapDocument(data)\n const rendered =\n mode === 'envelope'\n ? renderDocumentEnvelope(kind, doc)\n : renderReadableDocument(kind, doc)\n process.stdout.write(`${rendered}\\n`)\n}\n\nexport function renderReadableDocument(\n kind: DocumentKind,\n data: unknown,\n): string {\n const doc = asRecord(data)\n const lines: string[] = [kind]\n const fields = collectReadableFields(kind, doc)\n\n for (const [key, value] of fields) {\n if (value === undefined || value === null || value === '') continue\n lines.push(`${key}: ${formatScalar(value)}`)\n }\n\n const summary = firstString(doc, 'summary', 'subtitle')\n if (summary) {\n lines.push('', 'summary:', summary)\n }\n\n const content = renderContent(doc)\n if (content.body) {\n lines.push(\n '',\n `content_format: ${content.format}`,\n '',\n 'content:',\n content.body,\n )\n }\n\n return lines.join('\\n')\n}\n\nexport function renderDocumentEnvelope(\n kind: DocumentKind,\n data: unknown,\n): string {\n const doc = asRecord(data)\n const root = kind === 'note' ? 'mxnote' : 'mxpost'\n const meta = collectEnvelopeMeta(kind, doc)\n const metaLines = meta.map(([key, value]) => renderEnvelopeMeta(key, value))\n const content = renderContent(doc)\n\n return `<${root}>\n <meta>\n${metaLines.join('\\n')}\n </meta>\n <content>\n${content.body}\n </content>\n</${root}>`\n}\n\nfunction collectReadableFields(\n kind: DocumentKind,\n doc: Record<string, unknown>,\n): Array<[string, unknown]> {\n const base: Array<[string, unknown]> = [\n ['id', first(doc, 'id')],\n ['title', first(doc, 'title')],\n ['slug', first(doc, 'slug')],\n ]\n\n if (kind === 'post') {\n base.push(\n ['state', publishState(doc)],\n ['category', relationLabel(first(doc, 'category'))],\n ['tags', first(doc, 'tags')],\n ['pin', first(doc, 'pin')],\n )\n } else if (kind === 'note') {\n base.push(\n ['nid', first(doc, 'nid')],\n ['state', publishState(doc)],\n ['topic', relationLabel(first(doc, 'topic'))],\n ['mood', first(doc, 'mood')],\n ['weather', first(doc, 'weather')],\n ['public_at', first(doc, 'public_at', 'publicAt')],\n ['bookmark', first(doc, 'bookmark')],\n )\n } else {\n base.push(\n ['subtitle', first(doc, 'subtitle')],\n ['order', first(doc, 'order')],\n )\n }\n\n base.push(\n ['created_at', first(doc, 'created_at', 'createdAt')],\n ['modified_at', first(doc, 'modified_at', 'modifiedAt')],\n ['source_lang', first(doc, 'source_lang', 'sourceLang')],\n ['translated', first(doc, 'is_translated', 'isTranslated')],\n )\n\n return base\n}\n\nfunction collectEnvelopeMeta(\n kind: DocumentKind,\n doc: Record<string, unknown>,\n): Array<[string, unknown]> {\n const meta: Array<[string, unknown]> = [\n ['title', first(doc, 'title')],\n ['slug', first(doc, 'slug')],\n ]\n\n if (kind === 'post') {\n meta.push(\n ['category', relationSlugOrLabel(first(doc, 'category'))],\n ['state', publishState(doc) === 'published' ? 'publish' : 'draft'],\n ['summary', first(doc, 'summary')],\n ['tags', first(doc, 'tags')],\n )\n } else if (kind === 'note') {\n meta.push(\n ['topic', relationSlugOrLabel(first(doc, 'topic'))],\n ['state', publishState(doc) === 'published' ? 'publish' : 'draft'],\n ['mood', first(doc, 'mood')],\n ['weather', first(doc, 'weather')],\n ['publicAt', first(doc, 'public_at', 'publicAt')],\n ['bookmark', first(doc, 'bookmark')],\n ['location', first(doc, 'location')],\n )\n } else {\n meta.push(\n ['subtitle', first(doc, 'subtitle')],\n ['order', first(doc, 'order')],\n )\n }\n\n meta.push(['format', contentFormat(doc)])\n return meta.filter(\n ([, value]) => value !== undefined && value !== null && value !== '',\n )\n}\n\nfunction renderContent(doc: Record<string, unknown>): {\n body: string\n format: 'litexml' | 'markdown' | 'text'\n} {\n const format = contentFormat(doc)\n const content = firstString(doc, 'content')\n const text = firstString(doc, 'text')\n\n if (format === 'lexical' && content) {\n try {\n return {\n body: serializeFromLexical(JSON.parse(content) as LexicalState),\n format: 'litexml',\n }\n } catch {\n return { body: text || content, format: text ? 'text' : 'markdown' }\n }\n }\n\n return {\n body: content || text || '',\n format: format === 'markdown' ? 'markdown' : 'text',\n }\n}\n\nfunction unwrapDocument(data: unknown): unknown {\n const obj = asRecord(data)\n const nested = obj.data\n if (nested && typeof nested === 'object' && !Array.isArray(nested))\n return nested\n return data\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction first(record: Record<string, unknown>, ...keys: string[]): unknown {\n for (const key of keys) {\n if (record[key] !== undefined && record[key] !== null) return record[key]\n }\n return undefined\n}\n\nfunction firstString(\n record: Record<string, unknown>,\n ...keys: string[]\n): string {\n const value = first(record, ...keys)\n return typeof value === 'string' ? value : ''\n}\n\nfunction contentFormat(doc: Record<string, unknown>): string {\n const value = first(doc, 'content_format', 'contentFormat')\n return typeof value === 'string' ? value : 'markdown'\n}\n\nfunction publishState(doc: Record<string, unknown>): string | undefined {\n const value = first(doc, 'is_published', 'isPublished')\n if (typeof value === 'boolean') return value ? 'published' : 'draft'\n return undefined\n}\n\nfunction relationLabel(value: unknown): string | undefined {\n if (!value) return undefined\n if (typeof value === 'string') return value\n const obj = asRecord(value)\n return (\n firstString(obj, 'name') ||\n firstString(obj, 'slug') ||\n firstString(obj, 'id')\n )\n}\n\nfunction relationSlugOrLabel(value: unknown): string | undefined {\n if (!value) return undefined\n if (typeof value === 'string') return value\n const obj = asRecord(value)\n return (\n firstString(obj, 'slug') ||\n firstString(obj, 'name') ||\n firstString(obj, 'id')\n )\n}\n\nfunction formatScalar(value: unknown): string {\n if (Array.isArray(value)) return value.map(formatScalar).join(', ')\n if (value instanceof Date) return value.toISOString()\n if (typeof value === 'object' && value !== null) return JSON.stringify(value)\n return String(value)\n}\n\nfunction renderEnvelopeMeta(key: string, value: unknown): string {\n if (key === 'tags' && Array.isArray(value)) {\n const tags = value\n .map((item) => ` <tag>${escapeXml(formatScalar(item))}</tag>`)\n .join('\\n')\n return ` <tags>\\n${tags}\\n </tags>`\n }\n\n return ` <${key}>${escapeXml(formatScalar(value))}</${key}>`\n}\n\nfunction escapeXml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n}\n"],"mappings":"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"}