@wenyan-md/core 1.0.9 → 1.0.10
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/dist/browser/wenyan-core.js +42 -42
- package/dist/core.js +202 -204
- package/dist/publish.js +114 -103
- package/dist/types/wechatApi.d.ts +8 -0
- package/package.json +3 -2
package/dist/publish.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { JSDOM as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
var
|
|
1
|
+
import { JSDOM as P } from "jsdom";
|
|
2
|
+
import { createReadStream as W } from "fs";
|
|
3
|
+
import { stat as B } from "fs/promises";
|
|
4
|
+
import b, { basename as L } from "path";
|
|
5
|
+
import { FormData as N, Blob as j } from "formdata-node";
|
|
6
|
+
var F = (t, e, r) => {
|
|
7
7
|
if (!e.has(t))
|
|
8
8
|
throw TypeError("Cannot " + r);
|
|
9
|
-
}, c = (t, e, r) => (
|
|
9
|
+
}, c = (t, e, r) => (F(t, e, "read from private field"), r ? r.call(t) : e.get(t)), p = (t, e, r) => {
|
|
10
10
|
if (e.has(t))
|
|
11
11
|
throw TypeError("Cannot add the same private member more than once");
|
|
12
12
|
e instanceof WeakSet ? e.add(t) : e.set(t, r);
|
|
13
|
-
},
|
|
14
|
-
async function*
|
|
15
|
-
if (t.byteLength <=
|
|
13
|
+
}, y = (t, e, r, a) => (F(t, e, "write to private field"), e.set(t, r), r), I = (t) => typeof t == "object" && t != null && !Array.isArray(t), h = (t) => typeof t == "function", R = (t) => I(t) && h(t[Symbol.asyncIterator]), T = 65536;
|
|
14
|
+
async function* z(t) {
|
|
15
|
+
if (t.byteLength <= T) {
|
|
16
16
|
yield t;
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
let e = 0;
|
|
20
20
|
for (; e < t.byteLength; ) {
|
|
21
|
-
const r = Math.min(t.byteLength - e,
|
|
21
|
+
const r = Math.min(t.byteLength - e, T), a = t.buffer.slice(e, e + r);
|
|
22
22
|
e += a.byteLength, yield new Uint8Array(a);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -31,51 +31,51 @@ async function* C(t) {
|
|
|
31
31
|
yield a;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
async function*
|
|
34
|
+
async function* x(t) {
|
|
35
35
|
for await (const e of t)
|
|
36
|
-
yield*
|
|
36
|
+
yield* z(e);
|
|
37
37
|
}
|
|
38
|
-
var
|
|
38
|
+
var D = (t) => {
|
|
39
39
|
if (R(t))
|
|
40
|
-
return
|
|
40
|
+
return x(t);
|
|
41
41
|
if (h(t.getReader))
|
|
42
|
-
return
|
|
42
|
+
return x(C(t));
|
|
43
43
|
throw new TypeError(
|
|
44
44
|
"Unsupported data source: Expected either ReadableStream or async iterable."
|
|
45
45
|
);
|
|
46
46
|
};
|
|
47
|
-
async function*
|
|
47
|
+
async function* U(t) {
|
|
48
48
|
let e = 0;
|
|
49
49
|
for (; e !== t.size; ) {
|
|
50
50
|
const a = await t.slice(
|
|
51
51
|
e,
|
|
52
|
-
Math.min(t.size, e +
|
|
52
|
+
Math.min(t.size, e + T)
|
|
53
53
|
).arrayBuffer();
|
|
54
54
|
e += a.byteLength, yield new Uint8Array(a);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
async function* S(t, e = !1) {
|
|
58
58
|
for (const r of t)
|
|
59
|
-
ArrayBuffer.isView(r) ? e ? yield*
|
|
59
|
+
ArrayBuffer.isView(r) ? e ? yield* z(r) : yield r : h(r.stream) ? yield* D(r.stream()) : yield* U(r);
|
|
60
60
|
}
|
|
61
61
|
function* H(t, e, r = 0, a) {
|
|
62
62
|
a ??= e;
|
|
63
63
|
let n = r < 0 ? Math.max(e + r, 0) : Math.min(r, e), i = a < 0 ? Math.max(e + a, 0) : Math.min(a, e);
|
|
64
64
|
const s = Math.max(i - n, 0);
|
|
65
65
|
let o = 0;
|
|
66
|
-
for (const
|
|
66
|
+
for (const l of t) {
|
|
67
67
|
if (o >= s)
|
|
68
68
|
break;
|
|
69
|
-
const
|
|
70
|
-
if (n &&
|
|
71
|
-
n -=
|
|
69
|
+
const f = ArrayBuffer.isView(l) ? l.byteLength : l.size;
|
|
70
|
+
if (n && f <= n)
|
|
71
|
+
n -= f, i -= f;
|
|
72
72
|
else {
|
|
73
|
-
let
|
|
74
|
-
ArrayBuffer.isView(
|
|
73
|
+
let d;
|
|
74
|
+
ArrayBuffer.isView(l) ? (d = l.subarray(n, Math.min(f, i)), o += d.byteLength) : (d = l.slice(n, Math.min(f, i)), o += d.size), i -= f, n = 0, yield d;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
var u, _, g, O = class
|
|
78
|
+
var u, _, g, O = class v {
|
|
79
79
|
/**
|
|
80
80
|
* Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.
|
|
81
81
|
* The content of the blob consists of the concatenation of the values given in the parameter array.
|
|
@@ -102,10 +102,10 @@ var u, _, g, O = class A {
|
|
|
102
102
|
ArrayBuffer.isView(i) ? s = new Uint8Array(i.buffer.slice(
|
|
103
103
|
i.byteOffset,
|
|
104
104
|
i.byteOffset + i.byteLength
|
|
105
|
-
)) : i instanceof ArrayBuffer ? s = new Uint8Array(i.slice(0)) : i instanceof
|
|
105
|
+
)) : i instanceof ArrayBuffer ? s = new Uint8Array(i.slice(0)) : i instanceof v ? s = i : s = a.encode(String(i)), y(this, g, c(this, g) + (ArrayBuffer.isView(s) ? s.byteLength : s.size)), c(this, u).push(s);
|
|
106
106
|
}
|
|
107
107
|
const n = r.type === void 0 ? "" : String(r.type);
|
|
108
|
-
|
|
108
|
+
y(this, _, /^[\x20-\x7E]*$/.test(n) ? n : "");
|
|
109
109
|
}
|
|
110
110
|
static [Symbol.hasInstance](e) {
|
|
111
111
|
return !!(e && typeof e == "object" && h(e.constructor) && (h(e.stream) || h(e.arrayBuffer)) && /^(Blob|File)$/.test(e[Symbol.toStringTag]));
|
|
@@ -130,7 +130,7 @@ var u, _, g, O = class A {
|
|
|
130
130
|
* @param contentType The content type to assign to the new Blob; this will be the value of its type property. The default value is an empty string.
|
|
131
131
|
*/
|
|
132
132
|
slice(e, r, a) {
|
|
133
|
-
return new
|
|
133
|
+
return new v(H(c(this, u), this.size, e, r), {
|
|
134
134
|
type: a
|
|
135
135
|
});
|
|
136
136
|
}
|
|
@@ -178,8 +178,8 @@ var u, _, g, O = class A {
|
|
|
178
178
|
u = /* @__PURE__ */ new WeakMap();
|
|
179
179
|
_ = /* @__PURE__ */ new WeakMap();
|
|
180
180
|
g = /* @__PURE__ */ new WeakMap();
|
|
181
|
-
var
|
|
182
|
-
Object.defineProperties(
|
|
181
|
+
var A = O;
|
|
182
|
+
Object.defineProperties(A.prototype, {
|
|
183
183
|
type: { enumerable: !0 },
|
|
184
184
|
size: { enumerable: !0 },
|
|
185
185
|
slice: { enumerable: !0 },
|
|
@@ -187,7 +187,7 @@ Object.defineProperties(T.prototype, {
|
|
|
187
187
|
text: { enumerable: !0 },
|
|
188
188
|
arrayBuffer: { enumerable: !0 }
|
|
189
189
|
});
|
|
190
|
-
var
|
|
190
|
+
var k, M, V = class extends A {
|
|
191
191
|
/**
|
|
192
192
|
* Creates a new File instance.
|
|
193
193
|
*
|
|
@@ -196,22 +196,22 @@ var M, k, V = class extends T {
|
|
|
196
196
|
* @param options An options object containing optional attributes for the file.
|
|
197
197
|
*/
|
|
198
198
|
constructor(t, e, r = {}) {
|
|
199
|
-
if (super(t, r), p(this,
|
|
199
|
+
if (super(t, r), p(this, k, void 0), p(this, M, 0), arguments.length < 2)
|
|
200
200
|
throw new TypeError(
|
|
201
201
|
`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`
|
|
202
202
|
);
|
|
203
|
-
|
|
203
|
+
y(this, k, String(e));
|
|
204
204
|
const a = r.lastModified === void 0 ? Date.now() : Number(r.lastModified);
|
|
205
|
-
Number.isNaN(a) ||
|
|
205
|
+
Number.isNaN(a) || y(this, M, a);
|
|
206
206
|
}
|
|
207
207
|
static [Symbol.hasInstance](t) {
|
|
208
|
-
return t instanceof
|
|
208
|
+
return t instanceof A && t[Symbol.toStringTag] === "File" && typeof t.name == "string";
|
|
209
209
|
}
|
|
210
210
|
/**
|
|
211
211
|
* Name of the file referenced by the File object.
|
|
212
212
|
*/
|
|
213
213
|
get name() {
|
|
214
|
-
return c(this,
|
|
214
|
+
return c(this, k);
|
|
215
215
|
}
|
|
216
216
|
/* c8 ignore next 3 */
|
|
217
217
|
get webkitRelativePath() {
|
|
@@ -221,36 +221,36 @@ var M, k, V = class extends T {
|
|
|
221
221
|
* The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.
|
|
222
222
|
*/
|
|
223
223
|
get lastModified() {
|
|
224
|
-
return c(this,
|
|
224
|
+
return c(this, M);
|
|
225
225
|
}
|
|
226
226
|
get [Symbol.toStringTag]() {
|
|
227
227
|
return "File";
|
|
228
228
|
}
|
|
229
229
|
};
|
|
230
|
-
M = /* @__PURE__ */ new WeakMap();
|
|
231
230
|
k = /* @__PURE__ */ new WeakMap();
|
|
232
|
-
|
|
231
|
+
M = /* @__PURE__ */ new WeakMap();
|
|
232
|
+
var m, w, J = class q {
|
|
233
233
|
constructor(e) {
|
|
234
|
-
p(this, m, void 0), p(this,
|
|
234
|
+
p(this, m, void 0), p(this, w, void 0), y(this, m, e.path), y(this, w, e.start || 0), this.name = L(c(this, m)), this.size = e.size, this.lastModified = e.lastModified;
|
|
235
235
|
}
|
|
236
236
|
slice(e, r) {
|
|
237
|
-
return new
|
|
237
|
+
return new q({
|
|
238
238
|
path: c(this, m),
|
|
239
239
|
lastModified: this.lastModified,
|
|
240
|
-
start: c(this,
|
|
240
|
+
start: c(this, w) + e,
|
|
241
241
|
size: r - e
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
244
|
async *stream() {
|
|
245
|
-
const { mtimeMs: e } = await
|
|
245
|
+
const { mtimeMs: e } = await B(c(this, m));
|
|
246
246
|
if (e > this.lastModified)
|
|
247
247
|
throw new DOMException(
|
|
248
248
|
"The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.",
|
|
249
249
|
"NotReadableError"
|
|
250
250
|
);
|
|
251
|
-
this.size && (yield*
|
|
252
|
-
start: c(this,
|
|
253
|
-
end: c(this,
|
|
251
|
+
this.size && (yield* W(c(this, m), {
|
|
252
|
+
start: c(this, w),
|
|
253
|
+
end: c(this, w) + this.size - 1
|
|
254
254
|
}));
|
|
255
255
|
}
|
|
256
256
|
get [Symbol.toStringTag]() {
|
|
@@ -258,11 +258,11 @@ var m, y, J = class P {
|
|
|
258
258
|
}
|
|
259
259
|
};
|
|
260
260
|
m = /* @__PURE__ */ new WeakMap();
|
|
261
|
-
|
|
261
|
+
w = /* @__PURE__ */ new WeakMap();
|
|
262
262
|
var G = J;
|
|
263
263
|
function K(t, { mtimeMs: e, size: r }, a, n = {}) {
|
|
264
264
|
let i;
|
|
265
|
-
|
|
265
|
+
I(a) ? [n, i] = [a, void 0] : i = a;
|
|
266
266
|
const s = new G({ path: t, size: r, lastModified: e });
|
|
267
267
|
return i || (i = s.name), new V([s], i, {
|
|
268
268
|
...n,
|
|
@@ -270,90 +270,101 @@ function K(t, { mtimeMs: e, size: r }, a, n = {}) {
|
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
272
|
async function X(t, e, r) {
|
|
273
|
-
const a = await
|
|
273
|
+
const a = await B(t);
|
|
274
274
|
return K(t, a, e, r);
|
|
275
275
|
}
|
|
276
276
|
/*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */
|
|
277
277
|
const Z = "https://api.weixin.qq.com/cgi-bin/token", Q = "https://api.weixin.qq.com/cgi-bin/draft/add", Y = "https://api.weixin.qq.com/cgi-bin/material/add_material", ee = process.env.WECHAT_APP_ID || "", te = process.env.WECHAT_APP_SECRET || "";
|
|
278
278
|
async function re() {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
throw e.errcode ? new Error(`获取 Access Token 失败,错误码:${e.errcode},${e.errmsg}`) : new Error(`获取 Access Token 失败: ${e}`);
|
|
284
|
-
} catch (t) {
|
|
285
|
-
throw t;
|
|
279
|
+
const t = await fetch(`${Z}?grant_type=client_credential&appid=${ee}&secret=${te}`);
|
|
280
|
+
if (!t.ok) {
|
|
281
|
+
const e = await t.text();
|
|
282
|
+
throw new Error(`获取AccessToken失败: ${t.status} ${e}`);
|
|
286
283
|
}
|
|
284
|
+
return await t.json();
|
|
287
285
|
}
|
|
288
|
-
async function
|
|
289
|
-
const n = new
|
|
286
|
+
async function ae(t, e, r, a) {
|
|
287
|
+
const n = new N();
|
|
290
288
|
n.append("media", e, r);
|
|
291
289
|
const i = await fetch(`${Y}?access_token=${a}&type=${t}`, {
|
|
292
290
|
method: "POST",
|
|
293
291
|
body: n
|
|
294
292
|
});
|
|
295
293
|
if (!i.ok) {
|
|
296
|
-
const
|
|
297
|
-
throw new Error(
|
|
294
|
+
const o = await i.text();
|
|
295
|
+
throw new Error(`上传素材失败: ${i.status} ${o}`);
|
|
298
296
|
}
|
|
299
297
|
const s = await i.json();
|
|
300
|
-
|
|
301
|
-
throw new Error(`上传失败,错误码:${s.errcode},错误信息:${s.errmsg}`);
|
|
302
|
-
const o = s.url.replace("http://", "https://");
|
|
303
|
-
return s.url = o, s;
|
|
298
|
+
return s.url && s.url.startsWith("http://") && (s.url = s.url.replace("http://", "https://")), s;
|
|
304
299
|
}
|
|
305
|
-
async function
|
|
300
|
+
async function ie(t, e, r, a) {
|
|
301
|
+
const n = await fetch(`${Q}?access_token=${a}`, {
|
|
302
|
+
method: "POST",
|
|
303
|
+
body: JSON.stringify({
|
|
304
|
+
articles: [
|
|
305
|
+
{
|
|
306
|
+
title: t,
|
|
307
|
+
content: e,
|
|
308
|
+
thumb_media_id: r
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
})
|
|
312
|
+
});
|
|
313
|
+
if (!n.ok) {
|
|
314
|
+
const i = await n.text();
|
|
315
|
+
throw new Error(`发布失败: ${n.status} ${i}`);
|
|
316
|
+
}
|
|
317
|
+
return await n.json();
|
|
318
|
+
}
|
|
319
|
+
async function $(t, e, r) {
|
|
320
|
+
let a, n;
|
|
306
321
|
if (t.startsWith("http")) {
|
|
307
|
-
const
|
|
308
|
-
if (!
|
|
322
|
+
const s = await fetch(t);
|
|
323
|
+
if (!s.ok || !s.body)
|
|
309
324
|
throw new Error(`Failed to download image from URL: ${t}`);
|
|
310
|
-
const
|
|
311
|
-
|
|
325
|
+
const o = b.basename(t.split("?")[0]), l = b.extname(o);
|
|
326
|
+
n = r ?? (l === "" ? `${o}.jpg` : o);
|
|
327
|
+
const f = await s.arrayBuffer();
|
|
328
|
+
a = new j([f]);
|
|
312
329
|
} else {
|
|
313
|
-
const
|
|
314
|
-
|
|
330
|
+
const s = b.basename(t), o = b.extname(s);
|
|
331
|
+
n = r ?? (o === "" ? `${s}.jpg` : s), a = await X(t);
|
|
315
332
|
}
|
|
333
|
+
const i = await ae("image", a, n, e);
|
|
334
|
+
if (i.errcode)
|
|
335
|
+
throw new Error(`上传失败,错误码:${i.errcode},错误信息:${i.errmsg}`);
|
|
336
|
+
return i;
|
|
316
337
|
}
|
|
317
|
-
async function
|
|
338
|
+
async function se(t, e) {
|
|
318
339
|
if (!t.includes("<img"))
|
|
319
340
|
return { html: t, firstImageId: "" };
|
|
320
|
-
const r = new
|
|
321
|
-
const
|
|
322
|
-
if (
|
|
323
|
-
if (
|
|
324
|
-
return
|
|
341
|
+
const r = new P(t), a = r.window.document, i = Array.from(a.querySelectorAll("img")).map(async (f) => {
|
|
342
|
+
const d = f.getAttribute("src");
|
|
343
|
+
if (d) {
|
|
344
|
+
if (d.startsWith("https://mmbiz.qpic.cn"))
|
|
345
|
+
return d;
|
|
325
346
|
{
|
|
326
|
-
const
|
|
327
|
-
return
|
|
347
|
+
const E = await $(d, e);
|
|
348
|
+
return f.setAttribute("src", E.url), E.media_id;
|
|
328
349
|
}
|
|
329
350
|
}
|
|
330
351
|
return null;
|
|
331
352
|
}), o = (await Promise.all(i)).filter(Boolean)[0] || "";
|
|
332
353
|
return { html: r.serialize(), firstImageId: o };
|
|
333
354
|
}
|
|
334
|
-
async function
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
thumb_media_id: o
|
|
347
|
-
}]
|
|
348
|
-
})
|
|
349
|
-
})).json();
|
|
350
|
-
if (l.media_id)
|
|
351
|
-
return l;
|
|
352
|
-
throw l.errcode ? new Error(`上传到公众号草稿失败,错误码:${l.errcode},${l.errmsg}`) : new Error(`上传到公众号草稿失败: ${l}`);
|
|
353
|
-
} catch (a) {
|
|
354
|
-
throw a;
|
|
355
|
-
}
|
|
355
|
+
async function de(t, e, r) {
|
|
356
|
+
const a = await re();
|
|
357
|
+
if (!a.access_token)
|
|
358
|
+
throw a.errcode ? new Error(`获取 Access Token 失败,错误码:${a.errcode},${a.errmsg}`) : new Error(`获取 Access Token 失败: ${a}`);
|
|
359
|
+
const n = e.replace(/\n<li/g, "<li").replace(/<\/li>\n/g, "</li>"), { html: i, firstImageId: s } = await se(n, a.access_token);
|
|
360
|
+
let o = "";
|
|
361
|
+
if (r ? o = (await $(r, a.access_token, "cover.jpg")).media_id : s.startsWith("https://mmbiz.qpic.cn") ? o = (await $(s, a.access_token, "cover.jpg")).media_id : o = s, !o)
|
|
362
|
+
throw new Error("你必须指定一张封面图或者在正文中至少出现一张图片。");
|
|
363
|
+
const l = await ie(t, i, o, a.access_token);
|
|
364
|
+
if (l.media_id)
|
|
365
|
+
return l;
|
|
366
|
+
throw l.errcode ? new Error(`上传到公众号草稿失败,错误码:${l.errcode},${l.errmsg}`) : new Error(`上传到公众号草稿失败: ${l}`);
|
|
356
367
|
}
|
|
357
368
|
export {
|
|
358
|
-
|
|
369
|
+
de as publishToDraft
|
|
359
370
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { File, Blob } from "formdata-node";
|
|
2
|
+
export type UploadResponse = {
|
|
3
|
+
media_id: string;
|
|
4
|
+
url: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function fetchAccessToken(): Promise<any>;
|
|
7
|
+
export declare function uploadMaterial(type: string, fileData: Blob | File, fileName: string, accessToken: string): Promise<any>;
|
|
8
|
+
export declare function publishArticle(title: string, content: string, thumbMediaId: string, accessToken: string): Promise<any>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wenyan-md/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Core library for Wenyan markdown rendering & publishing",
|
|
5
5
|
"author": "Lei <caol64@gmail.com> (https://github.com/caol64)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"build:all": "pnpm build && pnpm build:browser && pnpm build:styles && pnpm build:math",
|
|
75
75
|
"test:main": "pnpm build && vitest run main.test.js",
|
|
76
76
|
"test:wrapper": "pnpm build && vitest run wrapper.test.js",
|
|
77
|
-
"test:publish": "pnpm build && vitest run publish.test.js"
|
|
77
|
+
"test:publish": "pnpm build && vitest run test/publish.test.js",
|
|
78
|
+
"test:realPublish": "pnpm build && vitest run test/realPublish.test.js"
|
|
78
79
|
}
|
|
79
80
|
}
|