@mx-space/cli 0.1.1 → 0.2.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.
- package/README.md +101 -28
- package/ROADMAP.md +4 -3
- package/dist/{auth-OeKZZ_2x.mjs → auth-Duj8jJn9.mjs} +3 -3
- package/dist/{auth-OeKZZ_2x.mjs.map → auth-Duj8jJn9.mjs.map} +1 -1
- package/dist/bin/mxs.d.mts +2 -1
- package/dist/bin/mxs.mjs +250 -48
- package/dist/bin/mxs.mjs.map +1 -1
- package/dist/{config-store-WL7dNMS6.mjs → config-store-DmwX2iZU.mjs} +15 -76
- package/dist/config-store-DmwX2iZU.mjs.map +1 -0
- package/dist/{create-Cxnqt_Wt.mjs → create-Cqt1rrSZ.mjs} +5 -5
- package/dist/{create-Cxnqt_Wt.mjs.map → create-Cqt1rrSZ.mjs.map} +1 -1
- package/dist/{create-BWA2WGrW.mjs → create-D7cR9xcN.mjs} +3 -3
- package/dist/{create-BWA2WGrW.mjs.map → create-D7cR9xcN.mjs.map} +1 -1
- package/dist/{create-C85MSrtt.mjs → create-DAt3FXLf.mjs} +5 -5
- package/dist/{create-C85MSrtt.mjs.map → create-DAt3FXLf.mjs.map} +1 -1
- package/dist/{create-DUOSAqBm.mjs → create-_H8YO7ze.mjs} +3 -3
- package/dist/{create-DUOSAqBm.mjs.map → create-_H8YO7ze.mjs.map} +1 -1
- package/dist/{create-BVHnXtIH.mjs → create-kYlrs4d6.mjs} +4 -4
- package/dist/{create-BVHnXtIH.mjs.map → create-kYlrs4d6.mjs.map} +1 -1
- package/dist/{delete-Cjxehwj7.mjs → delete-DVNebWqO.mjs} +4 -4
- package/dist/{delete-Cjxehwj7.mjs.map → delete-DVNebWqO.mjs.map} +1 -1
- package/dist/{delete-CGy-cV6k.mjs → delete-D_NRteuq.mjs} +4 -4
- package/dist/{delete-CGy-cV6k.mjs.map → delete-D_NRteuq.mjs.map} +1 -1
- package/dist/{delete-CKqlAUT8.mjs → delete-DmKPzzsQ.mjs} +4 -4
- package/dist/{delete-CKqlAUT8.mjs.map → delete-DmKPzzsQ.mjs.map} +1 -1
- package/dist/{delete-CcyrLNZv.mjs → delete-ZIjkquZj.mjs} +4 -4
- package/dist/{delete-CcyrLNZv.mjs.map → delete-ZIjkquZj.mjs.map} +1 -1
- package/dist/{delete-BEXOOFAJ.mjs → delete-aCVSWuKi.mjs} +4 -4
- package/dist/{delete-BEXOOFAJ.mjs.map → delete-aCVSWuKi.mjs.map} +1 -1
- package/dist/{onboarding-C1t1yoay.mjs → dist-DJF1Ntdn.mjs} +95 -173
- package/dist/dist-DJF1Ntdn.mjs.map +1 -0
- package/dist/{document-output-C5PWbz2p.mjs → document-output-BtY8T7eY.mjs} +3 -3
- package/dist/{document-output-C5PWbz2p.mjs.map → document-output-BtY8T7eY.mjs.map} +1 -1
- package/dist/{edit-t108N11Q.mjs → edit-BWX7X4sy.mjs} +8 -8
- package/dist/{edit-t108N11Q.mjs.map → edit-BWX7X4sy.mjs.map} +1 -1
- package/dist/{edit-BRaZ6GGg.mjs → edit-CHCuoiWT.mjs} +9 -9
- package/dist/{edit-BRaZ6GGg.mjs.map → edit-CHCuoiWT.mjs.map} +1 -1
- package/dist/{edit-BuKMUNVC.mjs → edit-DjRE8Gk-.mjs} +4 -4
- package/dist/{edit-BuKMUNVC.mjs.map → edit-DjRE8Gk-.mjs.map} +1 -1
- package/dist/{edit-DFnOnk4i.mjs → edit-R6H5RtWd.mjs} +8 -8
- package/dist/{edit-DFnOnk4i.mjs.map → edit-R6H5RtWd.mjs.map} +1 -1
- package/dist/{editor-xrF-j3UE.mjs → editor-Dywlo4-8.mjs} +2 -2
- package/dist/{editor-xrF-j3UE.mjs.map → editor-Dywlo4-8.mjs.map} +1 -1
- package/dist/{envelope-overlays-DPAlMNW1.mjs → envelope-overlays-D1gmGVe5.mjs} +2 -2
- package/dist/{envelope-overlays-DPAlMNW1.mjs.map → envelope-overlays-D1gmGVe5.mjs.map} +1 -1
- package/dist/{get-GdRz82RW.mjs → get-CiLnUGHw.mjs} +4 -4
- package/dist/{get-GdRz82RW.mjs.map → get-CiLnUGHw.mjs.map} +1 -1
- package/dist/{get-Doi-NKAh.mjs → get-CkBqVyGi.mjs} +5 -5
- package/dist/{get-Doi-NKAh.mjs.map → get-CkBqVyGi.mjs.map} +1 -1
- package/dist/{get-DxTU7Nom.mjs → get-DNdde54z.mjs} +3 -3
- package/dist/{get-DxTU7Nom.mjs.map → get-DNdde54z.mjs.map} +1 -1
- package/dist/{get-DnDvLa9S.mjs → get-DbH58EkF.mjs} +4 -4
- package/dist/{get-DnDvLa9S.mjs.map → get-DbH58EkF.mjs.map} +1 -1
- package/dist/{get-CwcNFb39.mjs → get-IQQv4_rP.mjs} +3 -3
- package/dist/{get-CwcNFb39.mjs.map → get-IQQv4_rP.mjs.map} +1 -1
- package/dist/{get-BYoAlJwB.mjs → get-xtByxURm.mjs} +4 -4
- package/dist/{get-BYoAlJwB.mjs.map → get-xtByxURm.mjs.map} +1 -1
- package/dist/index.d.mts +19 -2
- package/dist/index.mjs +9 -9
- package/dist/{list-DVunNsXr.mjs → list-Bnlg9SfR.mjs} +3 -3
- package/dist/{list-DVunNsXr.mjs.map → list-Bnlg9SfR.mjs.map} +1 -1
- package/dist/{list-CtME3aDw.mjs → list-C6z1iw4a.mjs} +3 -3
- package/dist/{list-CtME3aDw.mjs.map → list-C6z1iw4a.mjs.map} +1 -1
- package/dist/{list-CLAcZYZ4.mjs → list-CD9j9did.mjs} +3 -3
- package/dist/{list-CLAcZYZ4.mjs.map → list-CD9j9did.mjs.map} +1 -1
- package/dist/{list-DbNCVZbz.mjs → list-DVMtBAHG.mjs} +3 -3
- package/dist/{list-DbNCVZbz.mjs.map → list-DVMtBAHG.mjs.map} +1 -1
- package/dist/{list-DHG-MzOM.mjs → list-DW5TcGxS.mjs} +3 -3
- package/dist/{list-DHG-MzOM.mjs.map → list-DW5TcGxS.mjs.map} +1 -1
- package/dist/{list-DN81zVDA.mjs → list-lmpHwOQx.mjs} +3 -3
- package/dist/{list-DN81zVDA.mjs.map → list-lmpHwOQx.mjs.map} +1 -1
- package/dist/{litexml-codec-CDoRloiR.mjs → litexml-codec-D-1oggXL.mjs} +3 -3
- package/dist/{litexml-codec-CDoRloiR.mjs.map → litexml-codec-D-1oggXL.mjs.map} +1 -1
- package/dist/{login-mjliJn8U.mjs → login-D-SoeV01.mjs} +20 -9
- package/dist/{login-mjliJn8U.mjs.map → login-D-SoeV01.mjs.map} +1 -1
- package/dist/logout-D63ZU-1Q.mjs +17 -0
- package/dist/logout-D63ZU-1Q.mjs.map +1 -0
- package/dist/ls-Bz3BCcwU.mjs +32 -0
- package/dist/ls-Bz3BCcwU.mjs.map +1 -0
- package/dist/mark-N-IpKK17.mjs +28 -0
- package/dist/mark-N-IpKK17.mjs.map +1 -0
- package/dist/onboarding-FPMcuqn8.mjs +212 -0
- package/dist/onboarding-FPMcuqn8.mjs.map +1 -0
- package/dist/{output-CTnO1lYt.d.mts → output-DQMhacTo.d.mts} +1 -1
- package/dist/output-Dg8PISJM.mjs +299 -0
- package/dist/output-Dg8PISJM.mjs.map +1 -0
- package/dist/{payload-CN11pUto.mjs → payload-CjlZ9CeZ.mjs} +3 -3
- package/dist/{payload-CN11pUto.mjs.map → payload-CjlZ9CeZ.mjs.map} +1 -1
- package/dist/{publish-CN3NTJ_r.mjs → publish-C9O5obZ6.mjs} +4 -4
- package/dist/{publish-CN3NTJ_r.mjs.map → publish-C9O5obZ6.mjs.map} +1 -1
- package/dist/{publish-akQWYsnL.mjs → publish-yuM6YGSb.mjs} +4 -4
- package/dist/{publish-akQWYsnL.mjs.map → publish-yuM6YGSb.mjs.map} +1 -1
- package/dist/{resolve-Bp1AfBmM.mjs → resolve-B4-fMQ6I.mjs} +3 -3
- package/dist/{resolve-Bp1AfBmM.mjs.map → resolve-B4-fMQ6I.mjs.map} +1 -1
- package/dist/{resolve-BogJOR7R.mjs → resolve-DIu9N2sD.mjs} +2 -2
- package/dist/{resolve-BogJOR7R.mjs.map → resolve-DIu9N2sD.mjs.map} +1 -1
- package/dist/{resolve-CyjMlaoJ.mjs → resolve-TBYXBS4i.mjs} +3 -3
- package/dist/{resolve-CyjMlaoJ.mjs.map → resolve-TBYXBS4i.mjs.map} +1 -1
- package/dist/{resolve-Bw5Po9yK.mjs → resolve-U6RJ3AnQ.mjs} +3 -3
- package/dist/{resolve-Bw5Po9yK.mjs.map → resolve-U6RJ3AnQ.mjs.map} +1 -1
- package/dist/{resolve-helpers-CahPoJ0Y.mjs → resolve-helpers-C7PIVziv.mjs} +2 -2
- package/dist/{resolve-helpers-CahPoJ0Y.mjs.map → resolve-helpers-C7PIVziv.mjs.map} +1 -1
- package/dist/rm-D9GvLhhF.mjs +32 -0
- package/dist/rm-D9GvLhhF.mjs.map +1 -0
- package/dist/{set-ClbrGFGv.mjs → set-jD79hpuF.mjs} +3 -3
- package/dist/{set-ClbrGFGv.mjs.map → set-jD79hpuF.mjs.map} +1 -1
- package/dist/{shared-C2EAn5h_.mjs → shared-SryY2QPY.mjs} +12 -8
- package/dist/shared-SryY2QPY.mjs.map +1 -0
- package/dist/show-C5Zk0tcK.mjs +38 -0
- package/dist/show-C5Zk0tcK.mjs.map +1 -0
- package/dist/status-evZpPR3N.mjs +22 -0
- package/dist/status-evZpPR3N.mjs.map +1 -0
- package/dist/{update-CHmckeo8.mjs → update--7NPzL_w.mjs} +4 -4
- package/dist/{update-CHmckeo8.mjs.map → update--7NPzL_w.mjs.map} +1 -1
- package/dist/{update-qfiC-9Og.mjs → update-0q5hxJFh.mjs} +5 -5
- package/dist/{update-qfiC-9Og.mjs.map → update-0q5hxJFh.mjs.map} +1 -1
- package/dist/{update-Duh-iVOZ.mjs → update-CPJXcOg_.mjs} +6 -6
- package/dist/{update-Duh-iVOZ.mjs.map → update-CPJXcOg_.mjs.map} +1 -1
- package/dist/{update-CJjwg09n.mjs → update-DN78pXGZ.mjs} +4 -4
- package/dist/{update-CJjwg09n.mjs.map → update-DN78pXGZ.mjs.map} +1 -1
- package/dist/{update-dc-72pUN.mjs → update-hhAcAz_M.mjs} +6 -6
- package/dist/{update-dc-72pUN.mjs.map → update-hhAcAz_M.mjs.map} +1 -1
- package/dist/use-CHDCEe38.mjs +28 -0
- package/dist/use-CHDCEe38.mjs.map +1 -0
- package/dist/{whoami-UwcdRchK.mjs → whoami-BHDYyY5D.mjs} +4 -5
- package/dist/whoami-BHDYyY5D.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-hT5z_Zn9.mjs +0 -35
- package/dist/config-store-WL7dNMS6.mjs.map +0 -1
- package/dist/logout-Bslt_ZJ4.mjs +0 -11
- package/dist/logout-Bslt_ZJ4.mjs.map +0 -1
- package/dist/onboarding-C1t1yoay.mjs.map +0 -1
- package/dist/output-BM7aBFwt.mjs +0 -120
- package/dist/output-BM7aBFwt.mjs.map +0 -1
- package/dist/shared-C2EAn5h_.mjs.map +0 -1
- package/dist/status-Cvyrrx-J.mjs +0 -22
- package/dist/status-Cvyrrx-J.mjs.map +0 -1
- package/dist/whoami-UwcdRchK.mjs.map +0 -1
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { promises } from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
//#region src/core/errors.ts
|
|
5
|
+
var MxsError = class extends Error {
|
|
6
|
+
code;
|
|
7
|
+
details;
|
|
8
|
+
hint;
|
|
9
|
+
constructor(options) {
|
|
10
|
+
super(options.message, options.cause ? { cause: options.cause } : void 0);
|
|
11
|
+
this.name = "MxsError";
|
|
12
|
+
this.code = options.code;
|
|
13
|
+
this.details = options.details;
|
|
14
|
+
this.hint = options.hint;
|
|
15
|
+
}
|
|
16
|
+
toJSON() {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
code: this.code,
|
|
20
|
+
message: this.message,
|
|
21
|
+
...this.details === void 0 ? {} : { details: this.details },
|
|
22
|
+
...this.hint === void 0 ? {} : { hint: this.hint }
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function exitCodeForError(err) {
|
|
27
|
+
if (!(err instanceof MxsError)) return 1;
|
|
28
|
+
const code = err.code;
|
|
29
|
+
if (code === "argv.parse") return 2;
|
|
30
|
+
if (code === "auth.missing" || code === "auth.expired" || code === "auth.denied" || code === "auth.probe") return 3;
|
|
31
|
+
if (code === "network.timeout" || code === "network.dns" || code === "network.refused" || code === "profile.write_requires_explicit" || code === "profile.none_active") return 4;
|
|
32
|
+
if (code === "validation.failed" || code === "validation.xml" || code === "profile.invalid_name" || code === "config.missing.api_url" || code === "config.missing.token") return 5;
|
|
33
|
+
if (code === "server.error") return 6;
|
|
34
|
+
if (code === "resource.not_found") return 7;
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/core/config-dir.ts
|
|
39
|
+
function getConfigDir() {
|
|
40
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
41
|
+
const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), ".config");
|
|
42
|
+
return path.join(base, "mxs");
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/core/profile.ts
|
|
46
|
+
const PROFILE_NAME_RE = /^[\d_a-z-]{1,32}$/;
|
|
47
|
+
const RESERVED_PROFILE_NAMES = new Set(["current"]);
|
|
48
|
+
function validateProfileName(name) {
|
|
49
|
+
if (!name || name.length === 0) throw new MxsError({
|
|
50
|
+
code: "validation.failed",
|
|
51
|
+
message: "profile name must not be empty"
|
|
52
|
+
});
|
|
53
|
+
if (RESERVED_PROFILE_NAMES.has(name)) throw new MxsError({
|
|
54
|
+
code: "validation.failed",
|
|
55
|
+
message: `profile name '${name}' is reserved`
|
|
56
|
+
});
|
|
57
|
+
if (!PROFILE_NAME_RE.test(name)) throw new MxsError({
|
|
58
|
+
code: "validation.failed",
|
|
59
|
+
message: `profile name '${name}' is invalid; must match ^[a-z0-9_-]{1,32}$`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function getProfilesDir() {
|
|
63
|
+
return path.join(getConfigDir(), "profiles");
|
|
64
|
+
}
|
|
65
|
+
function getCurrentPath() {
|
|
66
|
+
return path.join(getConfigDir(), "current");
|
|
67
|
+
}
|
|
68
|
+
function getProfileDir(name) {
|
|
69
|
+
return path.join(getProfilesDir(), name);
|
|
70
|
+
}
|
|
71
|
+
function getProfileConfigPath(name) {
|
|
72
|
+
return path.join(getProfileDir(name), "config.json");
|
|
73
|
+
}
|
|
74
|
+
function getProfileCredentialsPath(name) {
|
|
75
|
+
return path.join(getProfileDir(name), "credentials.json");
|
|
76
|
+
}
|
|
77
|
+
async function listProfiles() {
|
|
78
|
+
const dir = getProfilesDir();
|
|
79
|
+
let entries;
|
|
80
|
+
try {
|
|
81
|
+
entries = await promises.readdir(dir, { withFileTypes: true });
|
|
82
|
+
} catch (err) {
|
|
83
|
+
if (err?.code === "ENOENT") return [];
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
87
|
+
}
|
|
88
|
+
async function getCurrentProfile() {
|
|
89
|
+
const p = getCurrentPath();
|
|
90
|
+
try {
|
|
91
|
+
const name = (await promises.readFile(p, "utf8")).trim();
|
|
92
|
+
return name.length > 0 ? name : null;
|
|
93
|
+
} catch (err) {
|
|
94
|
+
if (err?.code === "ENOENT") return null;
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function setCurrentProfile(name) {
|
|
99
|
+
validateProfileName(name);
|
|
100
|
+
const dir = getProfileDir(name);
|
|
101
|
+
try {
|
|
102
|
+
if (!(await promises.stat(dir)).isDirectory()) throw new MxsError({
|
|
103
|
+
code: "validation.failed",
|
|
104
|
+
message: `profile '${name}' does not exist`
|
|
105
|
+
});
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err instanceof MxsError) throw err;
|
|
108
|
+
if (err?.code === "ENOENT") throw new MxsError({
|
|
109
|
+
code: "validation.failed",
|
|
110
|
+
message: `profile '${name}' does not exist`
|
|
111
|
+
});
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
await promises.writeFile(getCurrentPath(), `${name}\n`, { encoding: "utf8" });
|
|
115
|
+
}
|
|
116
|
+
async function readJsonIfExists(p) {
|
|
117
|
+
try {
|
|
118
|
+
const raw = await promises.readFile(p, "utf8");
|
|
119
|
+
return JSON.parse(raw);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (err?.code === "ENOENT") return null;
|
|
122
|
+
if (err instanceof SyntaxError) throw new MxsError({
|
|
123
|
+
code: "generic",
|
|
124
|
+
message: `failed to parse ${p}: ${err.message}`
|
|
125
|
+
});
|
|
126
|
+
throw err;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function ensureProfileDir(name) {
|
|
130
|
+
const dir = getProfileDir(name);
|
|
131
|
+
await promises.mkdir(dir, {
|
|
132
|
+
recursive: true,
|
|
133
|
+
mode: 448
|
|
134
|
+
});
|
|
135
|
+
try {
|
|
136
|
+
await promises.chmod(dir, 448);
|
|
137
|
+
} catch {}
|
|
138
|
+
}
|
|
139
|
+
async function readProfileConfig(name) {
|
|
140
|
+
return await readJsonIfExists(getProfileConfigPath(name)) ?? {};
|
|
141
|
+
}
|
|
142
|
+
async function writeProfileConfig(name, cfg) {
|
|
143
|
+
await ensureProfileDir(name);
|
|
144
|
+
const p = getProfileConfigPath(name);
|
|
145
|
+
await promises.writeFile(p, JSON.stringify(cfg, null, 2), { mode: 420 });
|
|
146
|
+
try {
|
|
147
|
+
await promises.chmod(p, 420);
|
|
148
|
+
} catch {}
|
|
149
|
+
}
|
|
150
|
+
async function readProfileCredentials(name) {
|
|
151
|
+
const p = getProfileCredentialsPath(name);
|
|
152
|
+
const data = await readJsonIfExists(p);
|
|
153
|
+
if (data) await enforceProfileCredentialsMode(p);
|
|
154
|
+
return data;
|
|
155
|
+
}
|
|
156
|
+
async function writeProfileCredentials(name, creds) {
|
|
157
|
+
await ensureProfileDir(name);
|
|
158
|
+
const p = getProfileCredentialsPath(name);
|
|
159
|
+
await promises.writeFile(p, JSON.stringify(creds, null, 2), { mode: 384 });
|
|
160
|
+
await promises.chmod(p, 384);
|
|
161
|
+
}
|
|
162
|
+
async function deleteProfileCredentials(name) {
|
|
163
|
+
const p = getProfileCredentialsPath(name);
|
|
164
|
+
try {
|
|
165
|
+
await promises.unlink(p);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
if (err?.code !== "ENOENT") throw err;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function removeProfile(name) {
|
|
171
|
+
const dir = getProfileDir(name);
|
|
172
|
+
try {
|
|
173
|
+
await promises.stat(dir);
|
|
174
|
+
} catch (err) {
|
|
175
|
+
if (err?.code === "ENOENT") throw new MxsError({
|
|
176
|
+
code: "resource.not_found",
|
|
177
|
+
message: `profile '${name}' does not exist`
|
|
178
|
+
});
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
await promises.rm(dir, {
|
|
182
|
+
recursive: true,
|
|
183
|
+
force: true
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
async function enforceProfileCredentialsMode(p) {
|
|
187
|
+
let stats;
|
|
188
|
+
try {
|
|
189
|
+
stats = await promises.stat(p);
|
|
190
|
+
} catch (err) {
|
|
191
|
+
if (err?.code === "ENOENT") return false;
|
|
192
|
+
throw err;
|
|
193
|
+
}
|
|
194
|
+
const mode = stats.mode & 511;
|
|
195
|
+
if (mode !== 384) {
|
|
196
|
+
process.stderr.write(`mxs: credentials file ${p} had mode ${mode.toString(8)}; chmod 600\n`);
|
|
197
|
+
await promises.chmod(p, 384);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/core/output.ts
|
|
204
|
+
const defaultOutputOptions = {
|
|
205
|
+
json: false,
|
|
206
|
+
output: "pretty-json",
|
|
207
|
+
quiet: false,
|
|
208
|
+
verbose: false
|
|
209
|
+
};
|
|
210
|
+
function isTTY(stream) {
|
|
211
|
+
return Boolean(stream.isTTY);
|
|
212
|
+
}
|
|
213
|
+
function color(stream, code, text) {
|
|
214
|
+
if (!isTTY(stream)) return text;
|
|
215
|
+
return `[${code}m${text}[0m`;
|
|
216
|
+
}
|
|
217
|
+
function emitSuccess(data, opts) {
|
|
218
|
+
if (opts.json || opts.output === "json") {
|
|
219
|
+
process.stdout.write(`${JSON.stringify({
|
|
220
|
+
ok: true,
|
|
221
|
+
data
|
|
222
|
+
})}\n`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (data === null || data === void 0) return;
|
|
226
|
+
if (typeof data === "string") {
|
|
227
|
+
process.stdout.write(`${data}\n`);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
|
|
231
|
+
}
|
|
232
|
+
function emitInfo(message, opts) {
|
|
233
|
+
if (opts.quiet || opts.json) return;
|
|
234
|
+
process.stderr.write(`${message}\n`);
|
|
235
|
+
}
|
|
236
|
+
function emitWarn(message, opts) {
|
|
237
|
+
if (opts.json) return;
|
|
238
|
+
process.stderr.write(`${color(process.stderr, 33, "warn")}: ${message}\n`);
|
|
239
|
+
}
|
|
240
|
+
function emitError(err, opts) {
|
|
241
|
+
if (err instanceof MxsError) {
|
|
242
|
+
if (opts.json) {
|
|
243
|
+
if (err.code === "profile.write_requires_explicit") {
|
|
244
|
+
const details = err.details;
|
|
245
|
+
process.stdout.write(`${JSON.stringify({
|
|
246
|
+
ok: false,
|
|
247
|
+
error: err.code,
|
|
248
|
+
profile: details?.profile ?? null,
|
|
249
|
+
api_url: details?.api_url ?? null,
|
|
250
|
+
hint: err.hint ?? null
|
|
251
|
+
})}\n`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
process.stdout.write(`${JSON.stringify(err.toJSON())}\n`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
process.stderr.write(`${color(process.stderr, 31, "✘")} ${err.message}\n`);
|
|
258
|
+
if (err.details) {
|
|
259
|
+
const detailLines = formatDetails(err.details);
|
|
260
|
+
for (const line of detailLines) process.stderr.write(` · ${line}\n`);
|
|
261
|
+
}
|
|
262
|
+
if (err.hint) process.stderr.write(`\nhint: ${err.hint}\n`);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
266
|
+
if (opts.json) {
|
|
267
|
+
process.stdout.write(`${JSON.stringify({
|
|
268
|
+
ok: false,
|
|
269
|
+
code: "generic",
|
|
270
|
+
message
|
|
271
|
+
})}\n`);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
process.stderr.write(`${color(process.stderr, 31, "✘")} ${message}\n`);
|
|
275
|
+
}
|
|
276
|
+
function formatDetails(details) {
|
|
277
|
+
if (!details || typeof details !== "object") return [String(details)];
|
|
278
|
+
if (Array.isArray(details)) return details.map((item) => formatIssue(item));
|
|
279
|
+
if ("issues" in details && Array.isArray(details.issues)) return details.issues.map((issue) => formatIssue(issue));
|
|
280
|
+
return [JSON.stringify(details)];
|
|
281
|
+
}
|
|
282
|
+
function formatIssue(issue) {
|
|
283
|
+
if (!issue || typeof issue !== "object") return String(issue);
|
|
284
|
+
const obj = issue;
|
|
285
|
+
const path = Array.isArray(obj.path) ? obj.path.join(".") : "";
|
|
286
|
+
const message = typeof obj.message === "string" ? obj.message : JSON.stringify(obj);
|
|
287
|
+
const line = typeof obj.line === "number" ? ` (line ${obj.line})` : "";
|
|
288
|
+
const suggestions = Array.isArray(obj.suggestions) ? ` — did you mean ${obj.suggestions.join(", ")}?` : "";
|
|
289
|
+
return `${path ? `${path}: ` : ""}${message}${line}${suggestions}`;
|
|
290
|
+
}
|
|
291
|
+
function renderTable(rows, columns) {
|
|
292
|
+
if (rows.length === 0) return "(no rows)";
|
|
293
|
+
const widths = columns.map((col) => Math.max(col.length, ...rows.map((row) => String(row[col] ?? "").length)));
|
|
294
|
+
return `${columns.map((col, i) => col.padEnd(widths[i] ?? 0)).join(" ")}\n${widths.map((w) => "-".repeat(w)).join(" ")}\n${rows.map((row) => columns.map((col, i) => String(row[col] ?? "").padEnd(widths[i] ?? 0)).join(" ")).join("\n")}`;
|
|
295
|
+
}
|
|
296
|
+
//#endregion
|
|
297
|
+
export { MxsError as C, getConfigDir as S, removeProfile as _, emitWarn as a, writeProfileConfig as b, getCurrentPath as c, getProfileCredentialsPath as d, getProfileDir as f, readProfileCredentials as g, readProfileConfig as h, emitSuccess as i, getCurrentProfile as l, listProfiles as m, emitError as n, renderTable as o, getProfilesDir as p, emitInfo as r, deleteProfileCredentials as s, defaultOutputOptions as t, getProfileConfigPath as u, setCurrentProfile as v, exitCodeForError as w, writeProfileCredentials as x, validateProfileName as y };
|
|
298
|
+
|
|
299
|
+
//# sourceMappingURL=output-Dg8PISJM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-Dg8PISJM.mjs","names":["fs"],"sources":["../src/core/errors.ts","../src/core/config-dir.ts","../src/core/profile.ts","../src/core/output.ts"],"sourcesContent":["export type MxsErrorCode =\n | 'generic'\n | 'argv.parse'\n | 'auth.missing'\n | 'auth.expired'\n | 'auth.denied'\n | 'auth.probe'\n | 'network.timeout'\n | 'network.dns'\n | 'network.refused'\n | 'validation.failed'\n | 'validation.xml'\n | 'server.error'\n | 'resource.not_found'\n | 'config.missing.api_url'\n | 'config.missing.token'\n | 'config.migration.failed'\n | 'profile.not_found'\n | 'profile.none_active'\n | 'profile.invalid_name'\n | 'profile.write_requires_explicit'\n | (string & {})\n\nexport interface MxsErrorOptions {\n code: MxsErrorCode\n message: string\n details?: unknown\n hint?: string\n cause?: unknown\n}\n\nexport class MxsError extends Error {\n readonly code: MxsErrorCode\n readonly details?: unknown\n readonly hint?: string\n\n constructor(options: MxsErrorOptions) {\n super(options.message, options.cause ? { cause: options.cause } : undefined)\n this.name = 'MxsError'\n this.code = options.code\n this.details = options.details\n this.hint = options.hint\n }\n\n toJSON() {\n return {\n ok: false as const,\n code: this.code,\n message: this.message,\n ...(this.details === undefined ? {} : { details: this.details }),\n ...(this.hint === undefined ? {} : { hint: this.hint }),\n }\n }\n}\n\nexport function exitCodeForError(err: unknown): number {\n if (!(err instanceof MxsError)) return 1\n const code = err.code\n if (code === 'argv.parse') return 2\n if (\n code === 'auth.missing' ||\n code === 'auth.expired' ||\n code === 'auth.denied' ||\n code === 'auth.probe'\n )\n return 3\n if (\n code === 'network.timeout' ||\n code === 'network.dns' ||\n code === 'network.refused' ||\n code === 'profile.write_requires_explicit' || // exit code 4: production write gate refusal\n code === 'profile.none_active'\n )\n return 4\n if (\n code === 'validation.failed' ||\n code === 'validation.xml' ||\n code === 'profile.invalid_name' ||\n code === 'config.missing.api_url' ||\n code === 'config.missing.token'\n )\n return 5\n if (code === 'server.error') return 6\n if (code === 'resource.not_found') return 7\n return 1\n}\n","import os from 'node:os'\nimport path from 'node:path'\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","import { type Dirent, promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nimport { getConfigDir } from './config-dir'\nimport type { ConfigShape, CredentialsShape } from './config-store'\nimport { MxsError } from './errors'\n\nexport { getConfigDir }\n\nexport const PROFILE_NAME_RE = /^[\\d_a-z-]{1,32}$/\n\nexport const RESERVED_PROFILE_NAMES = new Set(['current'])\n\nexport function validateProfileName(name: string): void {\n if (!name || name.length === 0) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'profile name must not be empty',\n })\n }\n if (RESERVED_PROFILE_NAMES.has(name)) {\n throw new MxsError({\n code: 'validation.failed',\n message: `profile name '${name}' is reserved`,\n })\n }\n if (!PROFILE_NAME_RE.test(name)) {\n throw new MxsError({\n code: 'validation.failed',\n message: `profile name '${name}' is invalid; must match ^[a-z0-9_-]{1,32}$`,\n })\n }\n}\n\nexport function getProfilesDir(): string {\n return path.join(getConfigDir(), 'profiles')\n}\n\nexport function getCurrentPath(): string {\n return path.join(getConfigDir(), 'current')\n}\n\nexport function getProfileDir(name: string): string {\n return path.join(getProfilesDir(), name)\n}\n\nexport function getProfileConfigPath(name: string): string {\n return path.join(getProfileDir(name), 'config.json')\n}\n\nexport function getProfileCredentialsPath(name: string): string {\n return path.join(getProfileDir(name), 'credentials.json')\n}\n\nexport async function listProfiles(): Promise<string[]> {\n const dir = getProfilesDir()\n let entries: Dirent[]\n try {\n entries = await fs.readdir(dir, { withFileTypes: true })\n } catch (err: any) {\n if (err?.code === 'ENOENT') return []\n throw err\n }\n return entries\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => e.name)\n .sort()\n}\n\nexport async function getCurrentProfile(): Promise<string | null> {\n const p = getCurrentPath()\n try {\n const raw = await fs.readFile(p, 'utf8')\n const name = raw.trim()\n return name.length > 0 ? name : null\n } catch (err: any) {\n if (err?.code === 'ENOENT') return null\n throw err\n }\n}\n\nexport async function setCurrentProfile(name: string): Promise<void> {\n validateProfileName(name)\n const dir = getProfileDir(name)\n try {\n const stat = await fs.stat(dir)\n if (!stat.isDirectory()) {\n throw new MxsError({\n code: 'validation.failed',\n message: `profile '${name}' does not exist`,\n })\n }\n } catch (err: any) {\n if (err instanceof MxsError) throw err\n if (err?.code === 'ENOENT') {\n throw new MxsError({\n code: 'validation.failed',\n message: `profile '${name}' does not exist`,\n })\n }\n throw err\n }\n await fs.writeFile(getCurrentPath(), `${name}\\n`, { encoding: 'utf8' })\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\nasync function ensureProfileDir(name: string): Promise<void> {\n const dir = getProfileDir(name)\n await fs.mkdir(dir, { recursive: true, mode: 0o700 })\n try {\n await fs.chmod(dir, 0o700)\n } catch {}\n}\n\nexport type ProfileConfigShape = ConfigShape\nexport type ProfileCredentialsShape = CredentialsShape\n\nexport async function readProfileConfig(\n name: string,\n): Promise<ProfileConfigShape> {\n const data = await readJsonIfExists<ProfileConfigShape>(\n getProfileConfigPath(name),\n )\n return data ?? {}\n}\n\nexport async function writeProfileConfig(\n name: string,\n cfg: ProfileConfigShape,\n): Promise<void> {\n await ensureProfileDir(name)\n const p = getProfileConfigPath(name)\n await fs.writeFile(p, JSON.stringify(cfg, null, 2), { mode: 0o644 })\n try {\n await fs.chmod(p, 0o644)\n } catch {}\n}\n\nexport async function readProfileCredentials(\n name: string,\n): Promise<ProfileCredentialsShape | null> {\n const p = getProfileCredentialsPath(name)\n const data = await readJsonIfExists<ProfileCredentialsShape>(p)\n if (data) {\n await enforceProfileCredentialsMode(p)\n }\n return data\n}\n\nexport async function writeProfileCredentials(\n name: string,\n creds: ProfileCredentialsShape,\n): Promise<void> {\n await ensureProfileDir(name)\n const p = getProfileCredentialsPath(name)\n await fs.writeFile(p, JSON.stringify(creds, null, 2), { mode: 0o600 })\n await fs.chmod(p, 0o600)\n}\n\nexport async function deleteProfileCredentials(name: string): Promise<void> {\n const p = getProfileCredentialsPath(name)\n try {\n await fs.unlink(p)\n } catch (err: any) {\n if (err?.code !== 'ENOENT') throw err\n }\n}\n\nexport async function removeProfile(name: string): Promise<void> {\n const dir = getProfileDir(name)\n try {\n await fs.stat(dir)\n } catch (err: any) {\n if (err?.code === 'ENOENT') {\n throw new MxsError({\n code: 'resource.not_found',\n message: `profile '${name}' does not exist`,\n })\n }\n throw err\n }\n await fs.rm(dir, { recursive: true, force: true })\n}\n\nasync function enforceProfileCredentialsMode(p: string): 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","import { MxsError } from './errors'\n\nexport interface OutputOptions {\n json: boolean\n output?: string\n quiet: boolean\n verbose: boolean\n}\n\nexport const defaultOutputOptions: OutputOptions = {\n json: false,\n output: 'pretty-json',\n quiet: false,\n verbose: false,\n}\n\nfunction isTTY(stream: NodeJS.WriteStream): boolean {\n return Boolean(stream.isTTY)\n}\n\nfunction color(stream: NodeJS.WriteStream, code: number, text: string): string {\n if (!isTTY(stream)) return text\n return `\u001b[${code}m${text}\u001b[0m`\n}\n\nexport function emitSuccess(data: unknown, opts: OutputOptions): void {\n if (opts.json || opts.output === 'json') {\n process.stdout.write(`${JSON.stringify({ ok: true, data })}\\n`)\n return\n }\n if (data === null || data === undefined) {\n return\n }\n if (typeof data === 'string') {\n process.stdout.write(`${data}\\n`)\n return\n }\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`)\n}\n\nexport function emitInfo(message: string, opts: OutputOptions): void {\n if (opts.quiet || opts.json) return\n process.stderr.write(`${message}\\n`)\n}\n\nexport function emitWarn(message: string, opts: OutputOptions): void {\n if (opts.json) return\n process.stderr.write(`${color(process.stderr, 33, 'warn')}: ${message}\\n`)\n}\n\nexport function emitError(err: unknown, opts: OutputOptions): void {\n if (err instanceof MxsError) {\n if (opts.json) {\n if (err.code === 'profile.write_requires_explicit') {\n const details = err.details as\n | { profile?: unknown; api_url?: unknown }\n | undefined\n process.stdout.write(\n `${JSON.stringify({\n ok: false,\n error: err.code,\n profile: details?.profile ?? null,\n api_url: details?.api_url ?? null,\n hint: err.hint ?? null,\n })}\\n`,\n )\n return\n }\n process.stdout.write(`${JSON.stringify(err.toJSON())}\\n`)\n return\n }\n process.stderr.write(`${color(process.stderr, 31, '✘')} ${err.message}\\n`)\n if (err.details) {\n const detailLines = formatDetails(err.details)\n for (const line of detailLines) {\n process.stderr.write(` · ${line}\\n`)\n }\n }\n if (err.hint) {\n process.stderr.write(`\\nhint: ${err.hint}\\n`)\n }\n return\n }\n const message = err instanceof Error ? err.message : String(err)\n if (opts.json) {\n process.stdout.write(\n `${JSON.stringify({ ok: false, code: 'generic', message })}\\n`,\n )\n return\n }\n process.stderr.write(`${color(process.stderr, 31, '✘')} ${message}\\n`)\n}\n\nfunction formatDetails(details: unknown): string[] {\n if (!details || typeof details !== 'object') return [String(details)]\n if (Array.isArray(details)) {\n return details.map((item) => formatIssue(item))\n }\n if (\n 'issues' in (details as Record<string, unknown>) &&\n Array.isArray((details as any).issues)\n ) {\n return (details as any).issues.map((issue: unknown) => formatIssue(issue))\n }\n return [JSON.stringify(details)]\n}\n\nfunction formatIssue(issue: unknown): string {\n if (!issue || typeof issue !== 'object') return String(issue)\n const obj = issue as Record<string, unknown>\n const path = Array.isArray(obj.path) ? obj.path.join('.') : ''\n const message =\n typeof obj.message === 'string' ? obj.message : JSON.stringify(obj)\n const line = typeof obj.line === 'number' ? ` (line ${obj.line})` : ''\n const suggestions = Array.isArray(obj.suggestions)\n ? ` — did you mean ${obj.suggestions.join(', ')}?`\n : ''\n return `${path ? `${path}: ` : ''}${message}${line}${suggestions}`\n}\n\nexport function renderTable(\n rows: Record<string, unknown>[],\n columns: string[],\n): string {\n if (rows.length === 0) return '(no rows)'\n const widths = columns.map((col) =>\n Math.max(col.length, ...rows.map((row) => String(row[col] ?? '').length)),\n )\n const header = columns.map((col, i) => col.padEnd(widths[i] ?? 0)).join(' ')\n const sep = widths.map((w) => '-'.repeat(w)).join(' ')\n const body = rows\n .map((row) =>\n columns\n .map((col, i) => String(row[col] ?? '').padEnd(widths[i] ?? 0))\n .join(' '),\n )\n .join('\\n')\n return `${header}\\n${sep}\\n${body}`\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as emptyLexicalState, r as parseToLexical, t as deriveTextFromLexical } from "./litexml-codec-
|
|
1
|
+
import { C as MxsError } from "./output-Dg8PISJM.mjs";
|
|
2
|
+
import { n as emptyLexicalState, r as parseToLexical, t as deriveTextFromLexical } from "./litexml-codec-D-1oggXL.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { promises } from "node:fs";
|
|
5
5
|
//#region src/core/content-spec.ts
|
|
@@ -544,4 +544,4 @@ function emptyPayload(format) {
|
|
|
544
544
|
//#endregion
|
|
545
545
|
export { coerceMeta as a, tagToFlag as c, emptyPayload as i, readContentSpec as l, buildPagePayload as n, flagToTag as o, buildPostPayload as r, parseEnvelope as s, buildNotePayload as t, readJsonSpec as u };
|
|
546
546
|
|
|
547
|
-
//# sourceMappingURL=payload-
|
|
547
|
+
//# sourceMappingURL=payload-CjlZ9CeZ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload-CN11pUto.mjs","names":["fs","fs"],"sources":["../src/core/content-spec.ts","../src/core/envelope.ts","../src/core/payload.ts"],"sourcesContent":["import { promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nimport { MxsError } from './errors'\n\nexport interface ContentSource {\n text: string\n origin: 'inline' | 'file' | 'stdin'\n path?: string\n}\n\nexport async function readContentSpec(\n spec: string | undefined,\n { cwd = process.cwd() }: { cwd?: string } = {},\n): Promise<ContentSource | null> {\n if (spec === undefined) return null\n if (spec === '-' || spec === 'stdin') {\n const text = await readStdin()\n return { text, origin: 'stdin' }\n }\n if (spec.startsWith('file=')) {\n const p = path.resolve(cwd, spec.slice('file='.length))\n try {\n const text = await fs.readFile(p, 'utf8')\n return { text, origin: 'file', path: p }\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read ${p}: ${err?.message ?? err}`,\n })\n }\n }\n return { text: spec, origin: 'inline' }\n}\n\nexport async function readJsonSpec(spec: string | undefined): Promise<unknown> {\n if (spec === undefined) return undefined\n if (spec.startsWith('file=')) {\n const p = path.resolve(process.cwd(), spec.slice('file='.length))\n try {\n const text = await fs.readFile(p, 'utf8')\n return JSON.parse(text)\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read JSON from ${p}: ${err?.message ?? err}`,\n })\n }\n }\n try {\n return JSON.parse(spec)\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to parse JSON: ${err?.message ?? err}`,\n })\n }\n}\n\nexport async function readStdin(): Promise<string> {\n if (process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'requested stdin content but stdin is a TTY',\n })\n }\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks).toString('utf8')\n}\n","import { MxsError } from './errors'\n\nexport type EnvelopeKind = 'post' | 'note'\n\nexport interface ParsedEnvelope {\n kind: EnvelopeKind\n meta: Record<string, unknown>\n contentXml: string\n sourceMap: Record<string, number>\n}\n\nconst ROOT_TAGS: Record<EnvelopeKind, string> = {\n post: 'mxpost',\n note: 'mxnote',\n}\n\nconst ARRAY_TAGS: Record<string, string> = {\n tags: 'tag',\n related: 'id',\n}\n\nconst SKIP_TEXT_RE = /^\\s*$/\n\nfunction kebabToCamel(name: string): string {\n return name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction camelToKebab(name: string): string {\n return name.replaceAll(/([A-Z])/g, (_, c) => `-${c.toLowerCase()}`)\n}\n\nexport function flagToTag(flag: string): string {\n return kebabToCamel(flag.replace(/^--/, ''))\n}\n\nexport function tagToFlag(tag: string): string {\n return `--${camelToKebab(tag)}`\n}\n\ninterface Token {\n kind: 'open' | 'close' | 'self' | 'text' | 'cdata'\n name?: string\n raw?: string\n text?: string\n line: number\n}\n\nfunction tokenize(xml: string): Token[] {\n const tokens: Token[] = []\n let i = 0\n let line = 1\n while (i < xml.length) {\n const ch = xml[i]\n if (ch === '<') {\n if (xml.startsWith('<!--', i)) {\n const end = xml.indexOf('-->', i + 4)\n if (end < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated XML comment',\n details: { line },\n })\n }\n line += countLines(xml.slice(i, end + 3))\n i = end + 3\n continue\n }\n if (xml.startsWith('<![CDATA[', i)) {\n const end = xml.indexOf(']]>', i + 9)\n if (end < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated CDATA',\n details: { line },\n })\n }\n const inner = xml.slice(i + 9, end)\n tokens.push({ kind: 'cdata', text: inner, line })\n line += countLines(xml.slice(i, end + 3))\n i = end + 3\n continue\n }\n const close = xml.indexOf('>', i)\n if (close < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated tag',\n details: { line },\n })\n }\n const raw = xml.slice(i + 1, close).trim()\n if (raw.startsWith('/')) {\n tokens.push({ kind: 'close', name: raw.slice(1).trim(), line })\n } else if (raw.endsWith('/')) {\n const name = raw.slice(0, -1).trim().split(/\\s+/)[0] ?? ''\n tokens.push({ kind: 'self', name, raw, line })\n } else {\n const name = raw.split(/\\s+/)[0] ?? ''\n tokens.push({ kind: 'open', name, raw, line })\n }\n line += countLines(xml.slice(i, close + 1))\n i = close + 1\n } else {\n const next = xml.indexOf('<', i)\n const text = xml.slice(i, next < 0 ? xml.length : next)\n tokens.push({ kind: 'text', text, line })\n line += countLines(text)\n i = next < 0 ? xml.length : next\n }\n }\n return tokens\n}\n\nfunction countLines(s: string): number {\n let count = 0\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) === 10) count++\n }\n return count\n}\n\nfunction decodeXmlEntities(s: string): string {\n return s\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('"', '\"')\n .replaceAll(''', \"'\")\n .replaceAll('&', '&')\n}\n\nexport function parseEnvelope(xml: string, kind: EnvelopeKind): ParsedEnvelope {\n const tokens = tokenize(xml)\n const rootName = ROOT_TAGS[kind]\n\n const rootStart = tokens.findIndex(\n (t) => t.kind === 'open' && t.name === rootName,\n )\n if (rootStart < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: `expected root <${rootName}>`,\n details: { line: 1 },\n })\n }\n let depth = 0\n let rootEnd = -1\n for (let i = rootStart; i < tokens.length; i++) {\n const t = tokens[i]!\n if (t.kind === 'open' && t.name === rootName) depth++\n else if (t.kind === 'close' && t.name === rootName) {\n depth--\n if (depth === 0) {\n rootEnd = i\n break\n }\n }\n }\n if (rootEnd < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: `unterminated <${rootName}>`,\n details: { line: tokens[rootStart]?.line ?? 1 },\n })\n }\n\n const inner = tokens.slice(rootStart + 1, rootEnd)\n const meta: Record<string, unknown> = {}\n const sourceMap: Record<string, number> = {}\n let contentXml = ''\n\n let i = 0\n while (i < inner.length) {\n const t = inner[i]!\n if (t.kind === 'text' || t.kind === 'cdata') {\n i++\n continue\n }\n if (t.kind === 'open' && t.name === 'meta') {\n const closeIdx = findMatchingClose(inner, i, 'meta')\n parseMeta(inner.slice(i + 1, closeIdx), meta, sourceMap)\n i = closeIdx + 1\n continue\n }\n if (t.kind === 'open' && t.name === 'content') {\n const closeIdx = findMatchingClose(inner, i, 'content')\n contentXml = renderInnerXml(inner.slice(i + 1, closeIdx))\n sourceMap.content = t.line\n i = closeIdx + 1\n continue\n }\n if (t.kind === 'self' && t.name === 'content') {\n contentXml = ''\n sourceMap.content = t.line\n i++\n continue\n }\n if (t.kind === 'open' || t.kind === 'self') {\n throw new MxsError({\n code: 'validation.xml',\n message: `unexpected <${t.name}> at root`,\n details: { line: t.line },\n })\n }\n i++\n }\n\n return { kind, meta, contentXml, sourceMap }\n}\n\nfunction findMatchingClose(\n tokens: Token[],\n startOpen: number,\n name: string,\n): number {\n let depth = 0\n for (let i = startOpen; i < tokens.length; i++) {\n const t = tokens[i]!\n if (t.kind === 'open' && t.name === name) depth++\n else if (t.kind === 'close' && t.name === name) {\n depth--\n if (depth === 0) return i\n }\n }\n throw new MxsError({\n code: 'validation.xml',\n message: `unterminated <${name}>`,\n details: { line: tokens[startOpen]?.line ?? 1 },\n })\n}\n\nfunction parseMeta(\n tokens: Token[],\n meta: Record<string, unknown>,\n sourceMap: Record<string, number>,\n): void {\n let i = 0\n while (i < tokens.length) {\n const t = tokens[i]!\n if (t.kind === 'text' || t.kind === 'cdata') {\n i++\n continue\n }\n if (t.kind === 'close') {\n i++\n continue\n }\n if (t.kind === 'self') {\n const key = t.name!\n meta[key] = ''\n sourceMap[`meta.${key}`] = t.line\n i++\n continue\n }\n if (t.kind === 'open') {\n const name = t.name!\n const closeIdx = findMatchingClose(tokens, i, name)\n const inner = tokens.slice(i + 1, closeIdx)\n if (ARRAY_TAGS[name]) {\n const childTag = ARRAY_TAGS[name]\n const items: string[] = []\n let j = 0\n while (j < inner.length) {\n const c = inner[j]!\n if (c.kind === 'open' && c.name === childTag) {\n const cc = findMatchingClose(inner, j, childTag)\n items.push(textOf(inner.slice(j + 1, cc)))\n j = cc + 1\n } else {\n j++\n }\n }\n meta[name] = items\n } else {\n meta[name] = textOf(inner)\n }\n sourceMap[`meta.${name}`] = t.line\n i = closeIdx + 1\n continue\n }\n i++\n }\n}\n\nfunction textOf(tokens: Token[]): string {\n let s = ''\n for (const t of tokens) {\n if (t.kind === 'text' && t.text) s += t.text\n else if (t.kind === 'cdata' && t.text) s += t.text\n }\n return decodeXmlEntities(s).trim()\n}\n\nfunction renderInnerXml(tokens: Token[]): string {\n let out = ''\n for (const t of tokens) {\n if (t.kind === 'text') out += t.text ?? ''\n else if (t.kind === 'cdata') out += `<![CDATA[${t.text ?? ''}]]>`\n else if (t.kind === 'open') out += `<${t.raw ?? t.name}>`\n else if (t.kind === 'self') out += `<${t.raw ?? `${t.name}/`}>`\n else if (t.kind === 'close') out += `</${t.name}>`\n }\n if (out.startsWith('\\n')) out = out.slice(1)\n if (out.endsWith('\\n')) out = out.slice(0, -1)\n if (SKIP_TEXT_RE.test(out)) return ''\n return out\n}\n\nexport interface EnvelopeMeta {\n title?: string\n slug?: string\n category?: string\n topic?: string\n state?: 'publish' | 'draft'\n summary?: string\n copyright?: boolean\n pin?: string\n pinOrder?: number\n related?: string[]\n tags?: string[]\n mood?: string\n weather?: string\n publicAt?: string\n password?: string\n bookmark?: boolean\n location?: string\n subtitle?: string\n order?: number\n format?: 'lexical' | 'markdown'\n}\n\nexport function coerceMeta(raw: Record<string, unknown>): EnvelopeMeta {\n const out: EnvelopeMeta = {}\n const get = (key: string) => raw[key]\n\n const title = get('title')\n if (typeof title === 'string') out.title = title\n const slug = get('slug')\n if (typeof slug === 'string') out.slug = slug\n const category = get('category')\n if (typeof category === 'string') out.category = category\n const topic = get('topic')\n if (typeof topic === 'string') out.topic = topic\n const summary = get('summary')\n if (typeof summary === 'string') out.summary = summary\n const state = get('state')\n if (state === 'publish' || state === 'draft') out.state = state\n const copyright = get('copyright')\n if (typeof copyright === 'string') {\n out.copyright = copyright === 'true'\n }\n const pin = get('pin')\n if (typeof pin === 'string') out.pin = pin\n const pinOrder = get('pinOrder')\n if (typeof pinOrder === 'string' && pinOrder.length > 0) {\n const n = Number(pinOrder)\n if (!Number.isNaN(n)) out.pinOrder = n\n }\n const tags = get('tags')\n if (Array.isArray(tags)) out.tags = tags as string[]\n const related = get('related')\n if (Array.isArray(related)) out.related = related as string[]\n const mood = get('mood')\n if (typeof mood === 'string') out.mood = mood\n const weather = get('weather')\n if (typeof weather === 'string') out.weather = weather\n const publicAt = get('publicAt')\n if (typeof publicAt === 'string') out.publicAt = publicAt\n const password = get('password')\n if (typeof password === 'string') out.password = password\n const bookmark = get('bookmark')\n if (typeof bookmark === 'string') {\n out.bookmark = bookmark === 'true'\n }\n const location = get('location')\n if (typeof location === 'string') out.location = location\n const subtitle = get('subtitle')\n if (typeof subtitle === 'string') out.subtitle = subtitle\n const order = get('order')\n if (typeof order === 'string' && order.length > 0) {\n const n = Number(order)\n if (!Number.isNaN(n)) out.order = n\n }\n const format = get('format')\n if (format === 'lexical' || format === 'markdown') out.format = format\n\n return out\n}\n\nexport function listUnknownMetaKeys(\n raw: Record<string, unknown>,\n known: ReadonlyArray<string>,\n): string[] {\n return Object.keys(raw).filter((k) => !known.includes(k))\n}\n","import { promises as fs } from 'node:fs'\n\nimport { readContentSpec, readJsonSpec, readStdin } from './content-spec'\nimport {\n coerceMeta,\n type EnvelopeKind,\n type EnvelopeMeta,\n type ParsedEnvelope,\n parseEnvelope,\n} from './envelope'\nimport { MxsError } from './errors'\nimport {\n deriveTextFromLexical,\n emptyLexicalState,\n parseToLexical,\n} from './litexml-codec'\n\nexport type ContentFormat = 'lexical' | 'markdown'\n\nexport interface PostFlagInputs {\n title?: string\n slug?: string\n category?: string\n content?: string\n format?: ContentFormat\n summary?: string\n state?: 'publish' | 'draft'\n tags?: string[]\n copyright?: boolean\n pin?: string\n pinOrder?: number\n related?: string[]\n meta?: string\n file?: string\n}\n\nexport interface NoteFlagInputs {\n title?: string\n slug?: string\n topic?: string\n content?: string\n format?: ContentFormat\n state?: 'publish' | 'draft'\n mood?: string\n weather?: string\n publicAt?: string\n password?: string\n bookmark?: boolean\n coords?: string\n location?: string\n images?: string\n meta?: string\n file?: string\n}\n\nexport interface PageFlagInputs {\n title?: string\n slug?: string\n subtitle?: string\n order?: number\n content?: string\n format?: ContentFormat\n meta?: string\n file?: string\n}\n\nexport interface BuiltPayload {\n payload: Record<string, unknown>\n envelopeMeta?: EnvelopeMeta\n contentSource?: 'flag' | 'envelope' | 'none'\n}\n\nexport async function loadEnvelopeIfAny(\n filePath: string | undefined,\n kind: EnvelopeKind,\n): Promise<ParsedEnvelope | null> {\n if (!filePath) return null\n if (filePath === '-' || filePath === 'stdin' || filePath === '/dev/stdin') {\n return parseEnvelope(await readStdin(), kind)\n }\n if (filePath.startsWith('file=')) {\n const src = await readContentSpec(filePath)\n return parseEnvelope(src?.text ?? '', kind)\n }\n const xml = await fs.readFile(filePath, 'utf8').catch((err) => {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read ${filePath}: ${err?.message ?? err}`,\n })\n })\n return parseEnvelope(xml, kind)\n}\n\nexport async function buildPostPayload(\n flags: PostFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'post')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title\n if (title !== undefined) payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n if (flags.category) payload.__categoryName = flags.category\n else if (envMeta.category) payload.__categoryName = envMeta.category\n const summary = flags.summary ?? envMeta.summary\n if (summary !== undefined) payload.summary = summary\n const state = flags.state ?? envMeta.state\n if (state !== undefined) payload.isPublished = state === 'publish'\n const tags = flags.tags ?? envMeta.tags\n if (tags !== undefined) payload.tags = tags\n const copyright = flags.copyright ?? envMeta.copyright\n if (copyright !== undefined) payload.copyright = copyright\n const pin = flags.pin ?? envMeta.pin\n if (pin !== undefined) payload.pin = pin\n const pinOrder = flags.pinOrder ?? envMeta.pinOrder\n if (pinOrder !== undefined) payload.pinOrder = pinOrder\n const related = flags.related ?? envMeta.related\n if (related !== undefined) payload.relatedId = related\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\nexport async function buildNotePayload(\n flags: NoteFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'note')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title ?? '无题'\n payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n if (flags.topic) payload.__topicName = flags.topic\n else if (envMeta.topic) payload.__topicName = envMeta.topic\n const state = flags.state ?? envMeta.state\n if (state !== undefined) payload.isPublished = state === 'publish'\n const mood = flags.mood ?? envMeta.mood\n if (mood !== undefined) payload.mood = mood\n const weather = flags.weather ?? envMeta.weather\n if (weather !== undefined) payload.weather = weather\n const publicAt = flags.publicAt ?? envMeta.publicAt\n if (publicAt !== undefined) payload.publicAt = publicAt\n const password = flags.password ?? envMeta.password\n if (password !== undefined) payload.password = password\n const bookmark = flags.bookmark ?? envMeta.bookmark\n if (bookmark !== undefined) payload.bookmark = bookmark\n const location = flags.location ?? envMeta.location\n if (location !== undefined) payload.location = location\n\n if (flags.coords) {\n const [latRaw, lngRaw] = flags.coords.split(',').map((s) => s.trim())\n const lat = Number(latRaw)\n const lng = Number(lngRaw)\n if (Number.isNaN(lat) || Number.isNaN(lng)) {\n throw new MxsError({\n code: 'validation.failed',\n message: `invalid --coords value \"${flags.coords}\", expected \"lat,lng\"`,\n })\n }\n payload.coordinates = { latitude: lat, longitude: lng }\n }\n if (flags.images !== undefined) {\n payload.images = await readJsonSpec(flags.images)\n }\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\nexport async function buildPagePayload(\n flags: PageFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'post')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title\n if (title !== undefined) payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n const subtitle = flags.subtitle ?? envMeta.subtitle\n if (subtitle !== undefined) payload.subtitle = subtitle\n const order = flags.order ?? envMeta.order\n if (order !== undefined) payload.order = order\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\ninterface ResolvedContent {\n content: string\n text: string\n origin: 'flag' | 'envelope'\n}\n\nasync function resolveContent(\n flagSpec: string | undefined,\n envelope: ParsedEnvelope | null,\n format: ContentFormat,\n): Promise<ResolvedContent | null> {\n let source: { text: string; origin: 'flag' | 'envelope' } | null = null\n if (flagSpec !== undefined) {\n const src = await readContentSpec(flagSpec)\n if (src) source = { text: src.text, origin: 'flag' }\n } else if (envelope) {\n source = { text: envelope.contentXml, origin: 'envelope' }\n }\n if (!source) return null\n\n if (format === 'markdown') {\n return { content: source.text, text: source.text, origin: source.origin }\n }\n if (source.text.length === 0) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'content is required when contentFormat is lexical',\n details: { issues: [{ path: ['content'], message: 'required' }] },\n })\n }\n const state = parseToLexical(source.text)\n const lexicalJson = JSON.stringify(state)\n const text = deriveTextFromLexical(state)\n return { content: lexicalJson, text, origin: source.origin }\n}\n\nexport function emptyPayload(format: ContentFormat): {\n content: string\n text: string\n} {\n if (format === 'markdown') return { content: '', text: '' }\n const state = emptyLexicalState()\n return { content: JSON.stringify(state), text: '' }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"payload-CjlZ9CeZ.mjs","names":["fs","fs"],"sources":["../src/core/content-spec.ts","../src/core/envelope.ts","../src/core/payload.ts"],"sourcesContent":["import { promises as fs } from 'node:fs'\nimport path from 'node:path'\n\nimport { MxsError } from './errors'\n\nexport interface ContentSource {\n text: string\n origin: 'inline' | 'file' | 'stdin'\n path?: string\n}\n\nexport async function readContentSpec(\n spec: string | undefined,\n { cwd = process.cwd() }: { cwd?: string } = {},\n): Promise<ContentSource | null> {\n if (spec === undefined) return null\n if (spec === '-' || spec === 'stdin') {\n const text = await readStdin()\n return { text, origin: 'stdin' }\n }\n if (spec.startsWith('file=')) {\n const p = path.resolve(cwd, spec.slice('file='.length))\n try {\n const text = await fs.readFile(p, 'utf8')\n return { text, origin: 'file', path: p }\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read ${p}: ${err?.message ?? err}`,\n })\n }\n }\n return { text: spec, origin: 'inline' }\n}\n\nexport async function readJsonSpec(spec: string | undefined): Promise<unknown> {\n if (spec === undefined) return undefined\n if (spec.startsWith('file=')) {\n const p = path.resolve(process.cwd(), spec.slice('file='.length))\n try {\n const text = await fs.readFile(p, 'utf8')\n return JSON.parse(text)\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read JSON from ${p}: ${err?.message ?? err}`,\n })\n }\n }\n try {\n return JSON.parse(spec)\n } catch (err: any) {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to parse JSON: ${err?.message ?? err}`,\n })\n }\n}\n\nexport async function readStdin(): Promise<string> {\n if (process.stdin.isTTY) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'requested stdin content but stdin is a TTY',\n })\n }\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks).toString('utf8')\n}\n","import { MxsError } from './errors'\n\nexport type EnvelopeKind = 'post' | 'note'\n\nexport interface ParsedEnvelope {\n kind: EnvelopeKind\n meta: Record<string, unknown>\n contentXml: string\n sourceMap: Record<string, number>\n}\n\nconst ROOT_TAGS: Record<EnvelopeKind, string> = {\n post: 'mxpost',\n note: 'mxnote',\n}\n\nconst ARRAY_TAGS: Record<string, string> = {\n tags: 'tag',\n related: 'id',\n}\n\nconst SKIP_TEXT_RE = /^\\s*$/\n\nfunction kebabToCamel(name: string): string {\n return name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction camelToKebab(name: string): string {\n return name.replaceAll(/([A-Z])/g, (_, c) => `-${c.toLowerCase()}`)\n}\n\nexport function flagToTag(flag: string): string {\n return kebabToCamel(flag.replace(/^--/, ''))\n}\n\nexport function tagToFlag(tag: string): string {\n return `--${camelToKebab(tag)}`\n}\n\ninterface Token {\n kind: 'open' | 'close' | 'self' | 'text' | 'cdata'\n name?: string\n raw?: string\n text?: string\n line: number\n}\n\nfunction tokenize(xml: string): Token[] {\n const tokens: Token[] = []\n let i = 0\n let line = 1\n while (i < xml.length) {\n const ch = xml[i]\n if (ch === '<') {\n if (xml.startsWith('<!--', i)) {\n const end = xml.indexOf('-->', i + 4)\n if (end < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated XML comment',\n details: { line },\n })\n }\n line += countLines(xml.slice(i, end + 3))\n i = end + 3\n continue\n }\n if (xml.startsWith('<![CDATA[', i)) {\n const end = xml.indexOf(']]>', i + 9)\n if (end < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated CDATA',\n details: { line },\n })\n }\n const inner = xml.slice(i + 9, end)\n tokens.push({ kind: 'cdata', text: inner, line })\n line += countLines(xml.slice(i, end + 3))\n i = end + 3\n continue\n }\n const close = xml.indexOf('>', i)\n if (close < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: 'unterminated tag',\n details: { line },\n })\n }\n const raw = xml.slice(i + 1, close).trim()\n if (raw.startsWith('/')) {\n tokens.push({ kind: 'close', name: raw.slice(1).trim(), line })\n } else if (raw.endsWith('/')) {\n const name = raw.slice(0, -1).trim().split(/\\s+/)[0] ?? ''\n tokens.push({ kind: 'self', name, raw, line })\n } else {\n const name = raw.split(/\\s+/)[0] ?? ''\n tokens.push({ kind: 'open', name, raw, line })\n }\n line += countLines(xml.slice(i, close + 1))\n i = close + 1\n } else {\n const next = xml.indexOf('<', i)\n const text = xml.slice(i, next < 0 ? xml.length : next)\n tokens.push({ kind: 'text', text, line })\n line += countLines(text)\n i = next < 0 ? xml.length : next\n }\n }\n return tokens\n}\n\nfunction countLines(s: string): number {\n let count = 0\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) === 10) count++\n }\n return count\n}\n\nfunction decodeXmlEntities(s: string): string {\n return s\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('"', '\"')\n .replaceAll(''', \"'\")\n .replaceAll('&', '&')\n}\n\nexport function parseEnvelope(xml: string, kind: EnvelopeKind): ParsedEnvelope {\n const tokens = tokenize(xml)\n const rootName = ROOT_TAGS[kind]\n\n const rootStart = tokens.findIndex(\n (t) => t.kind === 'open' && t.name === rootName,\n )\n if (rootStart < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: `expected root <${rootName}>`,\n details: { line: 1 },\n })\n }\n let depth = 0\n let rootEnd = -1\n for (let i = rootStart; i < tokens.length; i++) {\n const t = tokens[i]!\n if (t.kind === 'open' && t.name === rootName) depth++\n else if (t.kind === 'close' && t.name === rootName) {\n depth--\n if (depth === 0) {\n rootEnd = i\n break\n }\n }\n }\n if (rootEnd < 0) {\n throw new MxsError({\n code: 'validation.xml',\n message: `unterminated <${rootName}>`,\n details: { line: tokens[rootStart]?.line ?? 1 },\n })\n }\n\n const inner = tokens.slice(rootStart + 1, rootEnd)\n const meta: Record<string, unknown> = {}\n const sourceMap: Record<string, number> = {}\n let contentXml = ''\n\n let i = 0\n while (i < inner.length) {\n const t = inner[i]!\n if (t.kind === 'text' || t.kind === 'cdata') {\n i++\n continue\n }\n if (t.kind === 'open' && t.name === 'meta') {\n const closeIdx = findMatchingClose(inner, i, 'meta')\n parseMeta(inner.slice(i + 1, closeIdx), meta, sourceMap)\n i = closeIdx + 1\n continue\n }\n if (t.kind === 'open' && t.name === 'content') {\n const closeIdx = findMatchingClose(inner, i, 'content')\n contentXml = renderInnerXml(inner.slice(i + 1, closeIdx))\n sourceMap.content = t.line\n i = closeIdx + 1\n continue\n }\n if (t.kind === 'self' && t.name === 'content') {\n contentXml = ''\n sourceMap.content = t.line\n i++\n continue\n }\n if (t.kind === 'open' || t.kind === 'self') {\n throw new MxsError({\n code: 'validation.xml',\n message: `unexpected <${t.name}> at root`,\n details: { line: t.line },\n })\n }\n i++\n }\n\n return { kind, meta, contentXml, sourceMap }\n}\n\nfunction findMatchingClose(\n tokens: Token[],\n startOpen: number,\n name: string,\n): number {\n let depth = 0\n for (let i = startOpen; i < tokens.length; i++) {\n const t = tokens[i]!\n if (t.kind === 'open' && t.name === name) depth++\n else if (t.kind === 'close' && t.name === name) {\n depth--\n if (depth === 0) return i\n }\n }\n throw new MxsError({\n code: 'validation.xml',\n message: `unterminated <${name}>`,\n details: { line: tokens[startOpen]?.line ?? 1 },\n })\n}\n\nfunction parseMeta(\n tokens: Token[],\n meta: Record<string, unknown>,\n sourceMap: Record<string, number>,\n): void {\n let i = 0\n while (i < tokens.length) {\n const t = tokens[i]!\n if (t.kind === 'text' || t.kind === 'cdata') {\n i++\n continue\n }\n if (t.kind === 'close') {\n i++\n continue\n }\n if (t.kind === 'self') {\n const key = t.name!\n meta[key] = ''\n sourceMap[`meta.${key}`] = t.line\n i++\n continue\n }\n if (t.kind === 'open') {\n const name = t.name!\n const closeIdx = findMatchingClose(tokens, i, name)\n const inner = tokens.slice(i + 1, closeIdx)\n if (ARRAY_TAGS[name]) {\n const childTag = ARRAY_TAGS[name]\n const items: string[] = []\n let j = 0\n while (j < inner.length) {\n const c = inner[j]!\n if (c.kind === 'open' && c.name === childTag) {\n const cc = findMatchingClose(inner, j, childTag)\n items.push(textOf(inner.slice(j + 1, cc)))\n j = cc + 1\n } else {\n j++\n }\n }\n meta[name] = items\n } else {\n meta[name] = textOf(inner)\n }\n sourceMap[`meta.${name}`] = t.line\n i = closeIdx + 1\n continue\n }\n i++\n }\n}\n\nfunction textOf(tokens: Token[]): string {\n let s = ''\n for (const t of tokens) {\n if (t.kind === 'text' && t.text) s += t.text\n else if (t.kind === 'cdata' && t.text) s += t.text\n }\n return decodeXmlEntities(s).trim()\n}\n\nfunction renderInnerXml(tokens: Token[]): string {\n let out = ''\n for (const t of tokens) {\n if (t.kind === 'text') out += t.text ?? ''\n else if (t.kind === 'cdata') out += `<![CDATA[${t.text ?? ''}]]>`\n else if (t.kind === 'open') out += `<${t.raw ?? t.name}>`\n else if (t.kind === 'self') out += `<${t.raw ?? `${t.name}/`}>`\n else if (t.kind === 'close') out += `</${t.name}>`\n }\n if (out.startsWith('\\n')) out = out.slice(1)\n if (out.endsWith('\\n')) out = out.slice(0, -1)\n if (SKIP_TEXT_RE.test(out)) return ''\n return out\n}\n\nexport interface EnvelopeMeta {\n title?: string\n slug?: string\n category?: string\n topic?: string\n state?: 'publish' | 'draft'\n summary?: string\n copyright?: boolean\n pin?: string\n pinOrder?: number\n related?: string[]\n tags?: string[]\n mood?: string\n weather?: string\n publicAt?: string\n password?: string\n bookmark?: boolean\n location?: string\n subtitle?: string\n order?: number\n format?: 'lexical' | 'markdown'\n}\n\nexport function coerceMeta(raw: Record<string, unknown>): EnvelopeMeta {\n const out: EnvelopeMeta = {}\n const get = (key: string) => raw[key]\n\n const title = get('title')\n if (typeof title === 'string') out.title = title\n const slug = get('slug')\n if (typeof slug === 'string') out.slug = slug\n const category = get('category')\n if (typeof category === 'string') out.category = category\n const topic = get('topic')\n if (typeof topic === 'string') out.topic = topic\n const summary = get('summary')\n if (typeof summary === 'string') out.summary = summary\n const state = get('state')\n if (state === 'publish' || state === 'draft') out.state = state\n const copyright = get('copyright')\n if (typeof copyright === 'string') {\n out.copyright = copyright === 'true'\n }\n const pin = get('pin')\n if (typeof pin === 'string') out.pin = pin\n const pinOrder = get('pinOrder')\n if (typeof pinOrder === 'string' && pinOrder.length > 0) {\n const n = Number(pinOrder)\n if (!Number.isNaN(n)) out.pinOrder = n\n }\n const tags = get('tags')\n if (Array.isArray(tags)) out.tags = tags as string[]\n const related = get('related')\n if (Array.isArray(related)) out.related = related as string[]\n const mood = get('mood')\n if (typeof mood === 'string') out.mood = mood\n const weather = get('weather')\n if (typeof weather === 'string') out.weather = weather\n const publicAt = get('publicAt')\n if (typeof publicAt === 'string') out.publicAt = publicAt\n const password = get('password')\n if (typeof password === 'string') out.password = password\n const bookmark = get('bookmark')\n if (typeof bookmark === 'string') {\n out.bookmark = bookmark === 'true'\n }\n const location = get('location')\n if (typeof location === 'string') out.location = location\n const subtitle = get('subtitle')\n if (typeof subtitle === 'string') out.subtitle = subtitle\n const order = get('order')\n if (typeof order === 'string' && order.length > 0) {\n const n = Number(order)\n if (!Number.isNaN(n)) out.order = n\n }\n const format = get('format')\n if (format === 'lexical' || format === 'markdown') out.format = format\n\n return out\n}\n\nexport function listUnknownMetaKeys(\n raw: Record<string, unknown>,\n known: ReadonlyArray<string>,\n): string[] {\n return Object.keys(raw).filter((k) => !known.includes(k))\n}\n","import { promises as fs } from 'node:fs'\n\nimport { readContentSpec, readJsonSpec, readStdin } from './content-spec'\nimport {\n coerceMeta,\n type EnvelopeKind,\n type EnvelopeMeta,\n type ParsedEnvelope,\n parseEnvelope,\n} from './envelope'\nimport { MxsError } from './errors'\nimport {\n deriveTextFromLexical,\n emptyLexicalState,\n parseToLexical,\n} from './litexml-codec'\n\nexport type ContentFormat = 'lexical' | 'markdown'\n\nexport interface PostFlagInputs {\n title?: string\n slug?: string\n category?: string\n content?: string\n format?: ContentFormat\n summary?: string\n state?: 'publish' | 'draft'\n tags?: string[]\n copyright?: boolean\n pin?: string\n pinOrder?: number\n related?: string[]\n meta?: string\n file?: string\n}\n\nexport interface NoteFlagInputs {\n title?: string\n slug?: string\n topic?: string\n content?: string\n format?: ContentFormat\n state?: 'publish' | 'draft'\n mood?: string\n weather?: string\n publicAt?: string\n password?: string\n bookmark?: boolean\n coords?: string\n location?: string\n images?: string\n meta?: string\n file?: string\n}\n\nexport interface PageFlagInputs {\n title?: string\n slug?: string\n subtitle?: string\n order?: number\n content?: string\n format?: ContentFormat\n meta?: string\n file?: string\n}\n\nexport interface BuiltPayload {\n payload: Record<string, unknown>\n envelopeMeta?: EnvelopeMeta\n contentSource?: 'flag' | 'envelope' | 'none'\n}\n\nexport async function loadEnvelopeIfAny(\n filePath: string | undefined,\n kind: EnvelopeKind,\n): Promise<ParsedEnvelope | null> {\n if (!filePath) return null\n if (filePath === '-' || filePath === 'stdin' || filePath === '/dev/stdin') {\n return parseEnvelope(await readStdin(), kind)\n }\n if (filePath.startsWith('file=')) {\n const src = await readContentSpec(filePath)\n return parseEnvelope(src?.text ?? '', kind)\n }\n const xml = await fs.readFile(filePath, 'utf8').catch((err) => {\n throw new MxsError({\n code: 'validation.failed',\n message: `failed to read ${filePath}: ${err?.message ?? err}`,\n })\n })\n return parseEnvelope(xml, kind)\n}\n\nexport async function buildPostPayload(\n flags: PostFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'post')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title\n if (title !== undefined) payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n if (flags.category) payload.__categoryName = flags.category\n else if (envMeta.category) payload.__categoryName = envMeta.category\n const summary = flags.summary ?? envMeta.summary\n if (summary !== undefined) payload.summary = summary\n const state = flags.state ?? envMeta.state\n if (state !== undefined) payload.isPublished = state === 'publish'\n const tags = flags.tags ?? envMeta.tags\n if (tags !== undefined) payload.tags = tags\n const copyright = flags.copyright ?? envMeta.copyright\n if (copyright !== undefined) payload.copyright = copyright\n const pin = flags.pin ?? envMeta.pin\n if (pin !== undefined) payload.pin = pin\n const pinOrder = flags.pinOrder ?? envMeta.pinOrder\n if (pinOrder !== undefined) payload.pinOrder = pinOrder\n const related = flags.related ?? envMeta.related\n if (related !== undefined) payload.relatedId = related\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\nexport async function buildNotePayload(\n flags: NoteFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'note')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title ?? '无题'\n payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n if (flags.topic) payload.__topicName = flags.topic\n else if (envMeta.topic) payload.__topicName = envMeta.topic\n const state = flags.state ?? envMeta.state\n if (state !== undefined) payload.isPublished = state === 'publish'\n const mood = flags.mood ?? envMeta.mood\n if (mood !== undefined) payload.mood = mood\n const weather = flags.weather ?? envMeta.weather\n if (weather !== undefined) payload.weather = weather\n const publicAt = flags.publicAt ?? envMeta.publicAt\n if (publicAt !== undefined) payload.publicAt = publicAt\n const password = flags.password ?? envMeta.password\n if (password !== undefined) payload.password = password\n const bookmark = flags.bookmark ?? envMeta.bookmark\n if (bookmark !== undefined) payload.bookmark = bookmark\n const location = flags.location ?? envMeta.location\n if (location !== undefined) payload.location = location\n\n if (flags.coords) {\n const [latRaw, lngRaw] = flags.coords.split(',').map((s) => s.trim())\n const lat = Number(latRaw)\n const lng = Number(lngRaw)\n if (Number.isNaN(lat) || Number.isNaN(lng)) {\n throw new MxsError({\n code: 'validation.failed',\n message: `invalid --coords value \"${flags.coords}\", expected \"lat,lng\"`,\n })\n }\n payload.coordinates = { latitude: lat, longitude: lng }\n }\n if (flags.images !== undefined) {\n payload.images = await readJsonSpec(flags.images)\n }\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\nexport async function buildPagePayload(\n flags: PageFlagInputs,\n): Promise<BuiltPayload> {\n const envelope = await loadEnvelopeIfAny(flags.file, 'post')\n const envMeta: EnvelopeMeta = envelope ? coerceMeta(envelope.meta) : {}\n const payload: Record<string, unknown> = {}\n const title = flags.title ?? envMeta.title\n if (title !== undefined) payload.title = title\n const slug = flags.slug ?? envMeta.slug\n if (slug !== undefined) payload.slug = slug\n const subtitle = flags.subtitle ?? envMeta.subtitle\n if (subtitle !== undefined) payload.subtitle = subtitle\n const order = flags.order ?? envMeta.order\n if (order !== undefined) payload.order = order\n if (flags.meta !== undefined) {\n payload.meta = await readJsonSpec(flags.meta)\n }\n const format = flags.format ?? envMeta.format ?? 'lexical'\n payload.contentFormat = format\n const contentSrc = await resolveContent(flags.content, envelope, format)\n if (contentSrc) {\n payload.content = contentSrc.content\n payload.text = contentSrc.text\n }\n return {\n payload,\n envelopeMeta: envMeta,\n contentSource: contentSrc?.origin ?? 'none',\n }\n}\n\ninterface ResolvedContent {\n content: string\n text: string\n origin: 'flag' | 'envelope'\n}\n\nasync function resolveContent(\n flagSpec: string | undefined,\n envelope: ParsedEnvelope | null,\n format: ContentFormat,\n): Promise<ResolvedContent | null> {\n let source: { text: string; origin: 'flag' | 'envelope' } | null = null\n if (flagSpec !== undefined) {\n const src = await readContentSpec(flagSpec)\n if (src) source = { text: src.text, origin: 'flag' }\n } else if (envelope) {\n source = { text: envelope.contentXml, origin: 'envelope' }\n }\n if (!source) return null\n\n if (format === 'markdown') {\n return { content: source.text, text: source.text, origin: source.origin }\n }\n if (source.text.length === 0) {\n throw new MxsError({\n code: 'validation.failed',\n message: 'content is required when contentFormat is lexical',\n details: { issues: [{ path: ['content'], message: 'required' }] },\n })\n }\n const state = parseToLexical(source.text)\n const lexicalJson = JSON.stringify(state)\n const text = deriveTextFromLexical(state)\n return { content: lexicalJson, text, origin: source.origin }\n}\n\nexport function emptyPayload(format: ContentFormat): {\n content: string\n text: string\n} {\n if (format === 'markdown') return { content: '', text: '' }\n const state = emptyLexicalState()\n return { content: JSON.stringify(state), text: '' }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as emitSuccess } from "./output-
|
|
2
|
-
import { n as resolveContext, t as buildApiClient } from "./shared-
|
|
3
|
-
import { t as resolveNoteId } from "./resolve-
|
|
1
|
+
import { i as emitSuccess } from "./output-Dg8PISJM.mjs";
|
|
2
|
+
import { n as resolveContext, t as buildApiClient } from "./shared-SryY2QPY.mjs";
|
|
3
|
+
import { t as resolveNoteId } from "./resolve-TBYXBS4i.mjs";
|
|
4
4
|
//#region src/commands/note/publish.ts
|
|
5
5
|
async function run(slugOrId, publish, flags, out) {
|
|
6
6
|
const client = buildApiClient(await resolveContext(flags, out), flags);
|
|
@@ -20,4 +20,4 @@ async function run(slugOrId, publish, flags, out) {
|
|
|
20
20
|
//#endregion
|
|
21
21
|
export { run };
|
|
22
22
|
|
|
23
|
-
//# sourceMappingURL=publish-
|
|
23
|
+
//# sourceMappingURL=publish-C9O5obZ6.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-
|
|
1
|
+
{"version":3,"file":"publish-C9O5obZ6.mjs","names":[],"sources":["../src/commands/note/publish.ts"],"sourcesContent":["import { 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 publish: boolean,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolveNoteId(client, slugOrId)\n if (flags.dryRun) {\n emitSuccess({ would_set: { id, isPublished: publish } }, out)\n return\n }\n const res = await client.request(`/notes/${id}/publish`, {\n method: 'PATCH',\n body: { isPublished: publish },\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;;AAQA,eAAsB,IACpB,UACA,SACA,OACA,KACA;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,cAAc,QAAQ,QAAQ;CAC/C,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,WAAW;GAAE;GAAI,aAAa;EAAQ,EAAE,GAAG,GAAG;EAC5D;CACF;CAKA,aAAY,MAJM,OAAO,QAAQ,UAAU,GAAG,WAAW;EACvD,QAAQ;EACR,MAAM,EAAE,aAAa,QAAQ;CAC/B,CAAC,GACe,MAAM,GAAG;AAC3B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as emitSuccess } from "./output-
|
|
2
|
-
import { n as resolveContext, t as buildApiClient } from "./shared-
|
|
3
|
-
import { t as resolvePostId } from "./resolve-
|
|
1
|
+
import { i as emitSuccess } from "./output-Dg8PISJM.mjs";
|
|
2
|
+
import { n as resolveContext, t as buildApiClient } from "./shared-SryY2QPY.mjs";
|
|
3
|
+
import { t as resolvePostId } from "./resolve-B4-fMQ6I.mjs";
|
|
4
4
|
//#region src/commands/post/publish.ts
|
|
5
5
|
async function run(slugOrId, publish, flags, out) {
|
|
6
6
|
const client = buildApiClient(await resolveContext(flags, out), flags);
|
|
@@ -20,4 +20,4 @@ async function run(slugOrId, publish, flags, out) {
|
|
|
20
20
|
//#endregion
|
|
21
21
|
export { run };
|
|
22
22
|
|
|
23
|
-
//# sourceMappingURL=publish-
|
|
23
|
+
//# sourceMappingURL=publish-yuM6YGSb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-
|
|
1
|
+
{"version":3,"file":"publish-yuM6YGSb.mjs","names":[],"sources":["../src/commands/post/publish.ts"],"sourcesContent":["import { 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 publish: boolean,\n flags: GlobalFlags,\n out: OutputOptions,\n) {\n const ctx = await resolveContext(flags, out)\n const client = buildApiClient(ctx, flags)\n const id = await resolvePostId(client, slugOrId)\n if (flags.dryRun) {\n emitSuccess({ would_set: { id, isPublished: publish } }, out)\n return\n }\n const res = await client.request(`/posts/${id}`, {\n method: 'PATCH',\n body: { isPublished: publish },\n })\n emitSuccess(res.data, out)\n}\n"],"mappings":";;;;AAIA,eAAsB,IACpB,UACA,SACA,OACA,KACA;CAEA,MAAM,SAAS,eAAe,MADZ,eAAe,OAAO,GAAG,GACR,KAAK;CACxC,MAAM,KAAK,MAAM,cAAc,QAAQ,QAAQ;CAC/C,IAAI,MAAM,QAAQ;EAChB,YAAY,EAAE,WAAW;GAAE;GAAI,aAAa;EAAQ,EAAE,GAAG,GAAG;EAC5D;CACF;CAKA,aAAY,MAJM,OAAO,QAAQ,UAAU,MAAM;EAC/C,QAAQ;EACR,MAAM,EAAE,aAAa,QAAQ;CAC/B,CAAC,GACe,MAAM,GAAG;AAC3B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as isSnowflakeId } from "./resolve-
|
|
1
|
+
import { C as MxsError } from "./output-Dg8PISJM.mjs";
|
|
2
|
+
import { r as isSnowflakeId } from "./resolve-DIu9N2sD.mjs";
|
|
3
3
|
//#region src/commands/post/resolve.ts
|
|
4
4
|
async function resolvePostReadPath(client, slugOrId) {
|
|
5
5
|
if (isSnowflakeId(slugOrId)) return `/posts/${slugOrId}`;
|
|
@@ -23,4 +23,4 @@ async function resolvePostId(client, slugOrId) {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
export { resolvePostReadPath as n, resolvePostId as t };
|
|
25
25
|
|
|
26
|
-
//# sourceMappingURL=resolve-
|
|
26
|
+
//# sourceMappingURL=resolve-B4-fMQ6I.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-
|
|
1
|
+
{"version":3,"file":"resolve-B4-fMQ6I.mjs","names":[],"sources":["../src/commands/post/resolve.ts"],"sourcesContent":["import type { ApiClient } from '../../core/api-client'\nimport { MxsError } from '../../core/errors'\nimport { isSnowflakeId } from '../../core/resolve'\n\ninterface PostSlugUrl {\n path?: string\n}\n\ninterface PostIdResult {\n id?: string\n}\n\nexport async function resolvePostReadPath(\n client: ApiClient,\n slugOrId: string,\n): Promise<string> {\n if (isSnowflakeId(slugOrId)) return `/posts/${slugOrId}`\n\n const resolved = await client.request<PostSlugUrl>(\n `/posts/get-url/${encodeURIComponent(slugOrId)}`,\n )\n const path = resolved.data?.path\n if (!path) {\n throw new MxsError({\n code: 'resource.not_found',\n message: `post not found: ${slugOrId}`,\n })\n }\n return `/posts${path.startsWith('/') ? path : `/${path}`}`\n}\n\nexport async function resolvePostId(\n client: ApiClient,\n slugOrId: string,\n): Promise<string> {\n if (isSnowflakeId(slugOrId)) return slugOrId\n\n const path = await resolvePostReadPath(client, slugOrId)\n const res = await client.request<PostIdResult>(path)\n if (!res.data?.id) {\n throw new MxsError({\n code: 'resource.not_found',\n message: `post not found: ${slugOrId}`,\n })\n }\n return res.data.id\n}\n"],"mappings":";;;AAYA,eAAsB,oBACpB,QACA,UACiB;CACjB,IAAI,cAAc,QAAQ,GAAG,OAAO,UAAU;CAK9C,MAAM,QAAO,MAHU,OAAO,QAC5B,kBAAkB,mBAAmB,QAAQ,GAC/C,GACsB,MAAM;CAC5B,IAAI,CAAC,MACH,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS,mBAAmB;CAC9B,CAAC;CAEH,OAAO,SAAS,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI;AACpD;AAEA,eAAsB,cACpB,QACA,UACiB;CACjB,IAAI,cAAc,QAAQ,GAAG,OAAO;CAEpC,MAAM,OAAO,MAAM,oBAAoB,QAAQ,QAAQ;CACvD,MAAM,MAAM,MAAM,OAAO,QAAsB,IAAI;CACnD,IAAI,CAAC,IAAI,MAAM,IACb,MAAM,IAAI,SAAS;EACjB,MAAM;EACN,SAAS,mBAAmB;CAC9B,CAAC;CAEH,OAAO,IAAI,KAAK;AAClB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as MxsError } from "./output-Dg8PISJM.mjs";
|
|
2
2
|
//#region src/core/resolve.ts
|
|
3
3
|
const SNOWFLAKE_RE = /^\d{15,}$/;
|
|
4
4
|
function isSnowflakeId(value) {
|
|
@@ -116,4 +116,4 @@ function fuzzySuggest(items, value, maxDistance = 2) {
|
|
|
116
116
|
//#endregion
|
|
117
117
|
export { matchItem as a, levenshtein as i, fuzzySuggest as n, isSnowflakeId as r, NameResolver as t };
|
|
118
118
|
|
|
119
|
-
//# sourceMappingURL=resolve-
|
|
119
|
+
//# sourceMappingURL=resolve-DIu9N2sD.mjs.map
|