@waline/vercel 1.31.7 → 1.31.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/index.js +2 -2
  2. package/package.json +15 -13
  3. package/src/config/config.js +2 -0
  4. package/src/config/middleware.js +1 -1
  5. package/src/config/netlify.js +1 -2
  6. package/src/controller/article.js +1 -1
  7. package/src/controller/comment.js +3 -3
  8. package/src/controller/db.js +1 -1
  9. package/src/controller/index.js +5 -4
  10. package/src/controller/rest.js +1 -1
  11. package/src/controller/token/2fa.js +1 -1
  12. package/src/controller/token.js +1 -1
  13. package/src/controller/user/password.js +1 -1
  14. package/src/controller/user.js +1 -1
  15. package/src/controller/verification.js +1 -1
  16. package/src/extend/controller.js +1 -1
  17. package/src/logic/article.js +1 -1
  18. package/src/logic/base.js +2 -2
  19. package/src/logic/comment.js +1 -1
  20. package/src/logic/db.js +1 -1
  21. package/src/logic/oauth.js +1 -1
  22. package/src/logic/token/2fa.js +1 -1
  23. package/src/logic/token.js +1 -1
  24. package/src/logic/user/password.js +1 -1
  25. package/src/logic/user.js +1 -1
  26. package/src/service/markdown/index.js +13 -7
  27. package/src/service/markdown/katex.js +2 -2
  28. package/src/service/markdown/xss.js +1 -1
  29. package/src/service/notify.js +17 -5
  30. package/src/service/storage/cloudbase.js +1 -1
  31. package/src/service/storage/deta.js +1 -1
  32. package/src/service/storage/github.js +2 -2
  33. package/src/service/storage/leancloud.js +5 -3
  34. package/src/service/storage/mongodb.js +1 -1
  35. package/src/service/storage/mysql.js +1 -1
  36. package/src/service/storage/postgresql.js +1 -1
  37. package/src/service/storage/sqlite.js +1 -1
  38. package/src/service/storage/tidb.js +1 -1
  39. package/vanilla.js +1 -1
  40. package/__tests__/__snapshots__/mathjax.spec.js.snap +0 -16
  41. package/__tests__/katex.spec.js +0 -140
  42. package/__tests__/mathjax.spec.js +0 -94
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
- const os = require('os');
2
- const path = require('path');
1
+ const os = require('node:os');
2
+ const path = require('node:path');
3
3
 
4
4
  const Application = require('thinkjs');
5
5
  const Loader = require('thinkjs/lib/loader');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/vercel",
3
- "version": "1.31.7",
3
+ "version": "1.31.8",
4
4
  "description": "vercel server for waline comment system",
5
5
  "keywords": [
6
6
  "waline",
@@ -16,25 +16,27 @@
16
16
  "author": "lizheming <i@imnerd.org>",
17
17
  "dependencies": {
18
18
  "@cloudbase/node-sdk": "^2.11.0",
19
- "@koa/cors": "^4.0.0",
19
+ "@koa/cors": "^5.0.0",
20
+ "@mdit/plugin-katex": "^0.8.0",
21
+ "@mdit/plugin-mathjax": "^0.8.0",
22
+ "@mdit/plugin-sub": "^0.8.0",
23
+ "@mdit/plugin-sup": "^0.8.0",
20
24
  "akismet": "^2.0.7",
21
25
  "deta": "^2.0.0",
22
- "dompurify": "^3.0.6",
26
+ "dompurify": "^3.0.8",
23
27
  "dy-node-ip2region": "^1.0.1",
24
- "fast-csv": "^4.3.6",
28
+ "fast-csv": "^5.0.0",
25
29
  "form-data": "^4.0.0",
26
- "jsdom": "^22.1.0",
30
+ "jsdom": "^24.0.0",
27
31
  "jsonwebtoken": "^9.0.2",
28
32
  "katex": "^0.16.9",
29
33
  "koa-compose": "^4.1.0",
30
- "leancloud-storage": "^4.15.1",
31
- "markdown-it": "^13.0.2",
32
- "markdown-it-emoji": "^2.0.2",
33
- "markdown-it-sub": "^1.0.0",
34
- "markdown-it-sup": "^1.0.0",
34
+ "leancloud-storage": "^4.15.2",
35
+ "markdown-it": "^14.0.0",
36
+ "markdown-it-emoji": "^3.0.0",
35
37
  "mathjax-full": "^3.2.2",
36
38
  "node-fetch": "^2.7.0",
37
- "nodemailer": "^6.9.6",
39
+ "nodemailer": "^6.9.9",
38
40
  "nunjucks": "^3.2.4",
39
41
  "phpass": "^0.1.1",
40
42
  "prismjs": "^1.29.0",
@@ -49,10 +51,10 @@
49
51
  "think-mongo": "^2.2.1",
50
52
  "think-router-rest": "^1.0.5",
51
53
  "thinkjs": "^3.2.15",
52
- "ua-parser-js": "^1.0.36"
54
+ "ua-parser-js": "^1.0.37"
53
55
  },
54
56
  "engines": {
55
- "node": ">=14"
57
+ "node": ">=18"
56
58
  },
57
59
  "publishConfig": {
58
60
  "provenance": true
@@ -41,6 +41,7 @@ const {
41
41
  QQ_TEMPLATE,
42
42
  TG_TEMPLATE,
43
43
  WX_TEMPLATE,
44
+ SC_TEMPLATE,
44
45
  DISCORD_TEMPLATE,
45
46
  LARK_TEMPLATE,
46
47
 
@@ -134,6 +135,7 @@ module.exports = {
134
135
  QQTemplate: QQ_TEMPLATE,
135
136
  TGTemplate: TG_TEMPLATE,
136
137
  WXTemplate: WX_TEMPLATE,
138
+ SCTemplate: SC_TEMPLATE,
137
139
  DiscordTemplate: DISCORD_TEMPLATE,
138
140
  LarkTemplate: LARK_TEMPLATE,
139
141
  };
@@ -1,7 +1,7 @@
1
1
  const cors = require('@koa/cors');
2
2
  const routerREST = require('think-router-rest');
3
3
 
4
- const { isNetlify, netlifyFunctionPrefix } = require('./netlify');
4
+ const { isNetlify, netlifyFunctionPrefix } = require('./netlify.js');
5
5
 
6
6
  const isDev = think.env === 'development';
7
7
  const isTcb = think.env === 'cloudbase';
@@ -1,5 +1,4 @@
1
- exports.isNetlify =
2
- process.env.NETLIFY_IMAGES_CDN_DOMAIN && process.env._HANDLER;
1
+ exports.isNetlify = think.env === 'netlify';
3
2
  exports.netlifyFunctionPrefix = `/.netlify/functions/${process.env?._HANDLER?.replace(
4
3
  /\.handler$/,
5
4
  '',
@@ -1,4 +1,4 @@
1
- const BaseRest = require('./rest');
1
+ const BaseRest = require('./rest.js');
2
2
 
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(ctx) {
@@ -1,6 +1,6 @@
1
- const BaseRest = require('./rest');
2
- const akismet = require('../service/akismet');
3
- const { getMarkdownParser } = require('../service/markdown');
1
+ const BaseRest = require('./rest.js');
2
+ const akismet = require('../service/akismet.js');
3
+ const { getMarkdownParser } = require('../service/markdown/index.js');
4
4
 
5
5
  const markdownParser = getMarkdownParser();
6
6
 
@@ -1,4 +1,4 @@
1
- const BaseRest = require('./rest');
1
+ const BaseRest = require('./rest.js');
2
2
 
3
3
  module.exports = class extends BaseRest {
4
4
  async getAction() {
@@ -13,16 +13,17 @@ module.exports = class extends think.Controller {
13
13
  </head>
14
14
  <body>
15
15
  <div id="waline" style="max-width: 800px;margin: 0 auto;"></div>
16
- <script src="https://unpkg.com/@waline/client@v2/dist/waline.js"></script>
17
- <link href='//unpkg.com/@waline/client@v2/dist/waline.css' rel='stylesheet' />
18
- <script>
16
+ <link href='//unpkg.com/@waline/client@v3/dist/waline.css' rel='stylesheet' />
17
+ <script type="module">
18
+ import { init } from 'https://unpkg.com/@waline/client@v3/dist/waline.js';
19
+
19
20
  console.log(
20
21
  '%c @waline/server %c v${version} ',
21
22
  'color: white; background: #0078E7; padding:5px 0;',
22
23
  'padding:4px;border:1px solid #0078E7;'
23
24
  );
24
25
  const params = new URLSearchParams(location.search.slice(1));
25
- const waline = Waline.init({
26
+ const waline = init({
26
27
  el: '#waline',
27
28
  path: params.get('path') || '/',
28
29
  lang: params.get('lng'),
@@ -1,4 +1,4 @@
1
- const path = require('path');
1
+ const path = require('node:path');
2
2
 
3
3
  module.exports = class extends think.Controller {
4
4
  static get _REST() {
@@ -1,6 +1,6 @@
1
1
  const speakeasy = require('speakeasy');
2
2
 
3
- const BaseRest = require('../rest');
3
+ const BaseRest = require('../rest.js');
4
4
 
5
5
  module.exports = class extends BaseRest {
6
6
  async getAction() {
@@ -2,7 +2,7 @@ const jwt = require('jsonwebtoken');
2
2
  const speakeasy = require('speakeasy');
3
3
  const helper = require('think-helper');
4
4
 
5
- const BaseRest = require('./rest');
5
+ const BaseRest = require('./rest.js');
6
6
 
7
7
  module.exports = class extends BaseRest {
8
8
  constructor(...args) {
@@ -1,6 +1,6 @@
1
1
  const jwt = require('jsonwebtoken');
2
2
 
3
- const BaseRest = require('../rest');
3
+ const BaseRest = require('../rest.js');
4
4
 
5
5
  module.exports = class extends BaseRest {
6
6
  async putAction() {
@@ -1,4 +1,4 @@
1
- const BaseRest = require('./rest');
1
+ const BaseRest = require('./rest.js');
2
2
 
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(...args) {
@@ -1,4 +1,4 @@
1
- const BaseRest = require('./rest');
1
+ const BaseRest = require('./rest.js');
2
2
 
3
3
  module.exports = class extends BaseRest {
4
4
  constructor(...args) {
@@ -1,7 +1,7 @@
1
1
  const nunjucks = require('nunjucks');
2
2
  const { PasswordHash } = require('phpass');
3
3
 
4
- const locales = require('../locales');
4
+ const locales = require('../locales/index.js');
5
5
 
6
6
  module.exports = {
7
7
  success(...args) {
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  getAction() {
package/src/logic/base.js CHANGED
@@ -1,5 +1,5 @@
1
- const path = require('path');
2
- const qs = require('querystring');
1
+ const path = require('node:path');
2
+ const qs = require('node:querystring');
3
3
 
4
4
  const jwt = require('jsonwebtoken');
5
5
  const fetch = require('node-fetch');
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  checkAdmin() {
package/src/logic/db.js CHANGED
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  async __before(...args) {
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  /**
@@ -1,4 +1,4 @@
1
- const Base = require('../base');
1
+ const Base = require('../base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  async getAction() {
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  /**
@@ -1,4 +1,4 @@
1
- const Base = require('../base');
1
+ const Base = require('../base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  async putAction() {
package/src/logic/user.js CHANGED
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  /**
@@ -1,12 +1,15 @@
1
+ const { katex: katexPlugin } = require('@mdit/plugin-katex');
2
+ const {
3
+ createMathjaxInstance,
4
+ mathjax: mathjaxPlugin,
5
+ } = require('@mdit/plugin-mathjax');
6
+ const { sub: subPlugin } = require('@mdit/plugin-sub');
7
+ const { sup: supPlugin } = require('@mdit/plugin-sup');
1
8
  const MarkdownIt = require('markdown-it');
2
9
  const emojiPlugin = require('markdown-it-emoji');
3
- const subPlugin = require('markdown-it-sub');
4
- const supPlugin = require('markdown-it-sup');
5
10
 
6
- const { resolveHighlighter } = require('./highlight');
7
- const { katexPlugin } = require('./katex');
8
- const { mathjaxPlugin } = require('./mathjax');
9
- const { sanitize } = require('./xss');
11
+ const { resolveHighlighter } = require('./highlight.js');
12
+ const { sanitize } = require('./xss.js');
10
13
 
11
14
  const getMarkdownParser = () => {
12
15
  const { markdown = {} } = think.config();
@@ -55,7 +58,10 @@ const getMarkdownParser = () => {
55
58
  output: 'mathml',
56
59
  });
57
60
  } else if (tex !== false) {
58
- markdownIt.use(mathjaxPlugin, mathjax);
61
+ markdownIt.use(
62
+ mathjaxPlugin,
63
+ createMathjaxInstance({ ...mathjax, output: 'svg' }),
64
+ );
59
65
  }
60
66
 
61
67
  return (content) => sanitize(markdownIt.render(content));
@@ -1,7 +1,7 @@
1
1
  const katex = require('katex');
2
2
 
3
- const { inlineTeX, blockTeX } = require('./mathCommon');
4
- const { escapeHtml } = require('./utils');
3
+ const { inlineTeX, blockTeX } = require('./mathCommon.js');
4
+ const { escapeHtml } = require('./utils.js');
5
5
 
6
6
  // set KaTeX as the renderer for markdown-it-simplemath
7
7
  const katexInline = (tex, options) => {
@@ -7,7 +7,7 @@ const DOMPurify = createDOMPurify(new JSDOM('').window);
7
7
  * Add a hook to make all links open a new window
8
8
  * and force their rel to be 'nofollow noreferrer noopener'
9
9
  */
10
- DOMPurify.addHook('afterSanitizeAttributes', function (node) {
10
+ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
11
11
  // set all elements owning target to target=_blank
12
12
  if ('target' in node && node.href && !node.href.startsWith('about:blank#')) {
13
13
  node.setAttribute('target', '_blank');
@@ -1,4 +1,4 @@
1
- const crypto = require('crypto');
1
+ const crypto = require('node:crypto');
2
2
 
3
3
  const FormData = require('form-data');
4
4
  const fetch = require('node-fetch');
@@ -87,8 +87,16 @@ module.exports = class extends think.Service {
87
87
  },
88
88
  };
89
89
 
90
+ const contentWechat =
91
+ think.config('SCTemplate') ||
92
+ `{{site.name|safe}} 有新评论啦
93
+ 【评论者昵称】:{{self.nick}}
94
+ 【评论者邮箱】:{{self.mail}}
95
+ 【内容】:{{self.comment}}
96
+ 【地址】:{{site.postUrl}}`;
97
+
90
98
  title = this.ctx.locale(title, data);
91
- content = this.ctx.locale(content, data);
99
+ content = this.ctx.locale(contentWechat, data);
92
100
 
93
101
  const form = new FormData();
94
102
 
@@ -219,7 +227,9 @@ module.exports = class extends think.Service {
219
227
  form.append('msg', this.ctx.locale(contentQQ, data));
220
228
  form.append('qq', QQ_ID);
221
229
 
222
- const qmsgHost = QMSG_HOST ? QMSG_HOST.replace(/\/$/, '') : 'https://qmsg.zendee.cn';
230
+ const qmsgHost = QMSG_HOST
231
+ ? QMSG_HOST.replace(/\/$/, '')
232
+ : 'https://qmsg.zendee.cn';
223
233
 
224
234
  return fetch(`${qmsgHost}/send/${QMSG_KEY}`, {
225
235
  method: 'POST',
@@ -239,7 +249,7 @@ module.exports = class extends think.Service {
239
249
  const href = self.comment.match(/<a href="(.*?)">(.*?)<\/a>/g);
240
250
 
241
251
  if (href !== null) {
242
- for (var i = 0; i < href.length; i++) {
252
+ for (let i = 0; i < href.length; i++) {
243
253
  href[i] =
244
254
  '[Link: ' +
245
255
  href[i].replace(/<a href="(.*?)">(.*?)<\/a>/g, '$2') +
@@ -387,7 +397,9 @@ module.exports = class extends think.Service {
387
397
  method: 'POST',
388
398
  header: form.getHeaders(),
389
399
  body: form,
390
- }).then((resp) => resp.json());
400
+ }).then((resp) => resp.statusText);
401
+ // Expected return value: No Content
402
+ // Since Discord doesn't return any response body on success, we just return the status text.
391
403
  }
392
404
 
393
405
  async lark({ title, content }, self, parent) {
@@ -1,6 +1,6 @@
1
1
  const cloudbase = require('@cloudbase/node-sdk');
2
2
 
3
- const Base = require('./base');
3
+ const Base = require('./base.js');
4
4
 
5
5
  const { TCB_ENV, TCB_ID, TCB_KEY } = process.env;
6
6
  const app = cloudbase.init({
@@ -2,7 +2,7 @@ const { performance } = require('perf_hooks');
2
2
 
3
3
  const { Deta } = require('deta');
4
4
 
5
- const Base = require('./base');
5
+ const Base = require('./base.js');
6
6
 
7
7
  module.exports = class extends Base {
8
8
  constructor(tableName) {
@@ -1,9 +1,9 @@
1
- const path = require('path');
1
+ const path = require('node:path');
2
2
 
3
3
  const { parseString, writeToString } = require('fast-csv');
4
4
  const fetch = require('node-fetch');
5
5
 
6
- const Base = require('./base');
6
+ const Base = require('./base.js');
7
7
 
8
8
  const CSV_HEADERS = {
9
9
  Comment: [
@@ -1,6 +1,6 @@
1
1
  const AV = require('leancloud-storage');
2
2
 
3
- const Base = require('./base');
3
+ const Base = require('./base.js');
4
4
 
5
5
  const { LEAN_ID, LEAN_KEY, LEAN_MASTER_KEY, LEAN_SERVER } = process.env;
6
6
 
@@ -405,9 +405,11 @@ module.exports = class extends Base {
405
405
  ret.map(async (item) => {
406
406
  const _oldStatus = item.get('status');
407
407
 
408
- var updateData = typeof data === 'function' ? data(item.toJSON()) : data;
409
-
408
+ const updateData =
409
+ typeof data === 'function' ? data(item.toJSON()) : data;
410
+
410
411
  const REVERSED_KEYS = ['createdAt', 'updatedAt'];
412
+
411
413
  for (const k in updateData) {
412
414
  if (REVERSED_KEYS.includes(k)) {
413
415
  continue;
@@ -1,6 +1,6 @@
1
1
  const { ObjectID: ObjectId } = require('think-mongo/lib/model');
2
2
 
3
- const Base = require('./base');
3
+ const Base = require('./base.js');
4
4
 
5
5
  module.exports = class extends Base {
6
6
  parseWhere(where) {
@@ -1,4 +1,4 @@
1
- const Base = require('./base');
1
+ const Base = require('./base.js');
2
2
 
3
3
  module.exports = class extends Base {
4
4
  parseWhere(filter) {
@@ -1,4 +1,4 @@
1
- const MySQL = require('./mysql');
1
+ const MySQL = require('./mysql.js');
2
2
 
3
3
  module.exports = class extends MySQL {
4
4
  model(tableName) {
@@ -1,4 +1,4 @@
1
- const MySQL = require('./mysql');
1
+ const MySQL = require('./mysql.js');
2
2
 
3
3
  module.exports = class extends MySQL {
4
4
  async setSeqId(id) {
@@ -1,3 +1,3 @@
1
- const MySQL = require('./mysql');
1
+ const MySQL = require('./mysql.js');
2
2
 
3
3
  module.exports = class extends MySQL {};
package/vanilla.js CHANGED
@@ -1,4 +1,4 @@
1
- const path = require('path');
1
+ const path = require('node:path');
2
2
 
3
3
  const Application = require('thinkjs');
4
4
 
@@ -1,16 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`inline mathjax > Should not render error msg when content is wrong 1`] = `
4
- "<p><svg style=\\"vertical-align: -0.566ex;\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"6.009ex\\" height=\\"2.262ex\\" role=\\"img\\" focusable=\\"false\\" viewBox=\\"0 -750 2656 1000\\"><g stroke=\\"currentColor\\" fill=\\"currentColor\\" stroke-width=\\"0\\" transform=\\"scale(1,-1)\\"><g data-mml-node=\\"math\\"><g data-mml-node=\\"mtext\\" fill=\\"red\\" stroke=\\"red\\"><path data-c=\\"5C\\" d=\\"M56 731Q56 740 62 745T75 750Q85 750 92 740Q96 733 270 255T444 -231Q444 -239 438 -244T424 -250Q414 -250 407 -240Q404 -236 230 242T56 731Z\\"></path><path data-c=\\"66\\" d=\\"M273 0Q255 3 146 3Q43 3 34 0H26V46H42Q70 46 91 49Q99 52 103 60Q104 62 104 224V385H33V431H104V497L105 564L107 574Q126 639 171 668T266 704Q267 704 275 704T289 705Q330 702 351 679T372 627Q372 604 358 590T321 576T284 590T270 627Q270 647 288 667H284Q280 668 273 668Q245 668 223 647T189 592Q183 572 182 497V431H293V385H185V225Q185 63 186 61T189 57T194 54T199 51T206 49T213 48T222 47T231 47T241 46T251 46H282V0H273Z\\" transform=\\"translate(500,0)\\"></path><path data-c=\\"72\\" d=\\"M36 46H50Q89 46 97 60V68Q97 77 97 91T98 122T98 161T98 203Q98 234 98 269T98 328L97 351Q94 370 83 376T38 385H20V408Q20 431 22 431L32 432Q42 433 60 434T96 436Q112 437 131 438T160 441T171 442H174V373Q213 441 271 441H277Q322 441 343 419T364 373Q364 352 351 337T313 322Q288 322 276 338T263 372Q263 381 265 388T270 400T273 405Q271 407 250 401Q234 393 226 386Q179 341 179 207V154Q179 141 179 127T179 101T180 81T180 66V61Q181 59 183 57T188 54T193 51T200 49T207 48T216 47T225 47T235 46T245 46H276V0H267Q249 3 140 3Q37 3 28 0H20V46H36Z\\" transform=\\"translate(806,0)\\"></path><path data-c=\\"61\\" d=\\"M137 305T115 305T78 320T63 359Q63 394 97 421T218 448Q291 448 336 416T396 340Q401 326 401 309T402 194V124Q402 76 407 58T428 40Q443 40 448 56T453 109V145H493V106Q492 66 490 59Q481 29 455 12T400 -6T353 12T329 54V58L327 55Q325 52 322 49T314 40T302 29T287 17T269 6T247 -2T221 -8T190 -11Q130 -11 82 20T34 107Q34 128 41 147T68 188T116 225T194 253T304 268H318V290Q318 324 312 340Q290 411 215 411Q197 411 181 410T156 406T148 403Q170 388 170 359Q170 334 154 320ZM126 106Q126 75 150 51T209 26Q247 26 276 49T315 109Q317 116 318 175Q318 233 317 233Q309 233 296 232T251 223T193 203T147 166T126 106Z\\" transform=\\"translate(1198,0)\\"></path></g><g data-mml-node=\\"TeXAtom\\" data-mjx-texclass=\\"ORD\\" transform=\\"translate(1698,0)\\"><g data-mml-node=\\"mi\\"><path data-c=\\"1D44E\\" d=\\"M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z\\"></path></g></g><g data-mml-node=\\"TeXAtom\\" data-mjx-texclass=\\"ORD\\" transform=\\"translate(2227,0)\\"><g data-mml-node=\\"mi\\"><path data-c=\\"1D44F\\" d=\\"M73 647Q73 657 77 670T89 683Q90 683 161 688T234 694Q246 694 246 685T212 542Q204 508 195 472T180 418L176 399Q176 396 182 402Q231 442 283 442Q345 442 383 396T422 280Q422 169 343 79T173 -11Q123 -11 82 27T40 150V159Q40 180 48 217T97 414Q147 611 147 623T109 637Q104 637 101 637H96Q86 637 83 637T76 640T73 647ZM336 325V331Q336 405 275 405Q258 405 240 397T207 376T181 352T163 330L157 322L136 236Q114 150 114 114Q114 66 138 42Q154 26 178 26Q211 26 245 58Q270 81 285 114T318 219Q336 291 336 325Z\\"></path></g></g></g></g></svg></p>
5
- "
6
- `;
7
-
8
- exports[`inline mathjax > Should render 1`] = `
9
- "<p><svg style=\\"vertical-align: -0.186ex;\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"5.345ex\\" height=\\"1.692ex\\" role=\\"img\\" focusable=\\"false\\" viewBox=\\"0 -666 2362.6 748\\"><g stroke=\\"currentColor\\" fill=\\"currentColor\\" stroke-width=\\"0\\" transform=\\"scale(1,-1)\\"><g data-mml-node=\\"math\\"><g data-mml-node=\\"mi\\"><path data-c=\\"1D44E\\" d=\\"M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z\\"></path></g><g data-mml-node=\\"mo\\" transform=\\"translate(806.8,0)\\"><path data-c=\\"3D\\" d=\\"M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z\\"></path></g><g data-mml-node=\\"mn\\" transform=\\"translate(1862.6,0)\\"><path data-c=\\"31\\" d=\\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\\"></path></g></g></g></svg></p>
10
- "
11
- `;
12
-
13
- exports[`inline mathjax > Should render when the first one is after a charater 1`] = `
14
- "<p>The next<svg style=\\"vertical-align: -0.186ex;\\" xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"5.345ex\\" height=\\"1.692ex\\" role=\\"img\\" focusable=\\"false\\" viewBox=\\"0 -666 2362.6 748\\"><g stroke=\\"currentColor\\" fill=\\"currentColor\\" stroke-width=\\"0\\" transform=\\"scale(1,-1)\\"><g data-mml-node=\\"math\\"><g data-mml-node=\\"mi\\"><path data-c=\\"1D44E\\" d=\\"M33 157Q33 258 109 349T280 441Q331 441 370 392Q386 422 416 422Q429 422 439 414T449 394Q449 381 412 234T374 68Q374 43 381 35T402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487Q506 153 506 144Q506 138 501 117T481 63T449 13Q436 0 417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157ZM351 328Q351 334 346 350T323 385T277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q217 26 254 59T298 110Q300 114 325 217T351 328Z\\"></path></g><g data-mml-node=\\"mo\\" transform=\\"translate(806.8,0)\\"><path data-c=\\"3D\\" d=\\"M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z\\"></path></g><g data-mml-node=\\"mn\\" transform=\\"translate(1862.6,0)\\"><path data-c=\\"31\\" d=\\"M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z\\"></path></g></g></g></svg> won't work</p>
15
- "
16
- `;
@@ -1,140 +0,0 @@
1
- /* eslint-disable @typescript-eslint/unbound-method */
2
- import MarkdownIt from 'markdown-it';
3
- import { describe, expect, it, vi } from 'vitest';
4
-
5
- import { katexPlugin } from '../src/service/markdown/katex';
6
-
7
- const markdownIt = MarkdownIt({ linkify: true }).use(katexPlugin, {
8
- output: 'mathml',
9
- });
10
- const markdownItWithError = MarkdownIt({ linkify: true }).use(katexPlugin, {
11
- output: 'mathml',
12
- throwOnError: true,
13
- });
14
-
15
- describe('inline katex', () => {
16
- it('Should render', () => {
17
- expect(markdownIt.render(`$a=1$`)).toEqual(
18
- `<p><span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a=1</annotation></semantics></math></span></p>\n`,
19
- );
20
- });
21
-
22
- it('Should not render when escape', () => {
23
- expect(markdownIt.render('$a = 1\\$')).toEqual('<p>$a = 1$</p>\n');
24
- expect(markdownIt.render('\\$a = 1$')).toEqual('<p>$a = 1$</p>\n');
25
- });
26
-
27
- it('Should not render when having spaces', () => {
28
- expect(markdownIt.render(`$ a = 1 $`)).toEqual('<p>$ a = 1 $</p>\n');
29
- });
30
-
31
- it('Should not render when the ending tag is followed by number', () => {
32
- expect(markdownIt.render(`Of course $1 = $1`)).toEqual(
33
- '<p>Of course $1 = $1</p>\n',
34
- );
35
- });
36
-
37
- it('Should render when the first one is after a character', () => {
38
- expect(markdownIt.render(`The next$a = 1$ won't work`)).toEqual(
39
- `<p>The next<span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a = 1</annotation></semantics></math></span> won't work</p>\n`,
40
- );
41
- });
42
-
43
- it('Should not render error msg when content is wrong', () => {
44
- expect(markdownIt.render('$\\fra{a}{b}$')).toEqual(
45
- `<p><span class='katex-error' title='ParseError: KaTeX parse error: Undefined control sequence: \\fra at position 1: \\̲f̲r̲a̲{a}{b}'>\\fra{a}{b}</span></p>\n`,
46
- );
47
- });
48
-
49
- it('Should render error msg when content is wrong', () => {
50
- const originalWarn = global.console.warn;
51
-
52
- global.console.warn = vi.fn();
53
-
54
- expect(markdownItWithError.render('$\\fra{a}{b}$')).toEqual(
55
- "<p><span class='katex-error' title='ParseError: KaTeX parse error: Undefined control sequence: \\fra at position 1: \\̲f̲r̲a̲{a}{b}'>\\fra{a}{b}</span></p>\n",
56
- );
57
-
58
- expect(global.console.warn).toHaveBeenCalledTimes(1);
59
- global.console.warn = originalWarn;
60
- });
61
- });
62
-
63
- describe('block katex', () => {
64
- it('Should render', () => {
65
- expect(markdownIt.render(`$$a=1$$`)).toEqual(
66
- `<p class='katex-block'><span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a=1\n</annotation></semantics></math></span></p>\n`,
67
- );
68
-
69
- expect(
70
- markdownIt.render(`
71
- $$
72
- a = 1
73
- $$
74
- `),
75
- ).toEqual(
76
- `<p class='katex-block'><span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a = 1\n</annotation></semantics></math></span></p>\n`,
77
- );
78
- });
79
-
80
- it('Should not render when escape', () => {
81
- expect(markdownIt.render('\\$\\$a = 1$$')).toEqual('<p>$$a = 1$$</p>\n');
82
- expect(
83
- markdownIt.render(`
84
- \\$\\$
85
- a = 1
86
- \\$\\$
87
- `),
88
- ).toEqual(`<p>$$
89
- a = 1
90
- $$</p>\n`);
91
- });
92
-
93
- it('Should render when having spaces', () => {
94
- expect(markdownIt.render(`$$ a = 1 $$`)).toEqual(
95
- `<p class='katex-block'><span class="katex"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a = 1 \n</annotation></semantics></math></span></p>\n`,
96
- );
97
-
98
- expect(markdownIt.render(`All $$ a = 1 $$ is true.`)).toEqual(
99
- '<p>All $$ a = 1 $$ is true.</p>\n',
100
- );
101
- });
102
-
103
- it('Should not render error msg when content is wrong', () => {
104
- expect(markdownIt.render('$$\\fra{a}{b}$$')).toEqual(
105
- `<p class='katex-block katex-error' title='ParseError: KaTeX parse error: Undefined control sequence: \\fra at position 1: \\̲f̲r̲a̲{a}{b}\n'>\\fra{a}{b}\n</p>\n`,
106
- );
107
-
108
- expect(
109
- markdownIt.render(`
110
- $$
111
- \\fra{a}{b}
112
- $$
113
- `),
114
- ).toEqual(
115
- `<p class='katex-block katex-error' title='ParseError: KaTeX parse error: Undefined control sequence: \\fra at position 1: \\̲f̲r̲a̲{a}{b}\n'>\\fra{a}{b}\n</p>\n`,
116
- );
117
- });
118
-
119
- it('Should render error msg when content is wrong', () => {
120
- const originalWarn = global.console.warn;
121
-
122
- global.console.warn = vi.fn();
123
- expect(markdownItWithError.render('$$\\fra{a}{b}$$')).toMatch(
124
- /<p class='katex-block katex-error' title='[\s\S]*?'>[\s\S]*?<\/p>/,
125
- );
126
-
127
- expect(
128
- markdownItWithError.render(`
129
- $$
130
- \\fra{a}{b}
131
- $$
132
- `),
133
- ).toMatch(
134
- /<p class='katex-block katex-error' title='[\s\S]*?'>[\s\S]*?<\/p>/,
135
- );
136
-
137
- expect(global.console.warn).toHaveBeenCalledTimes(2);
138
- global.console.warn = originalWarn;
139
- });
140
- });
@@ -1,94 +0,0 @@
1
- import MarkdownIt from 'markdown-it';
2
- import { describe, expect, it } from 'vitest';
3
-
4
- import { mathjaxPlugin } from '../src/service/markdown/mathjax';
5
-
6
- const markdownIt = MarkdownIt({ linkify: true }).use(mathjaxPlugin);
7
-
8
- describe('inline mathjax', () => {
9
- it('Should render', () => {
10
- expect(markdownIt.render(`$a=1$`)).toMatchSnapshot();
11
- });
12
-
13
- it('Should not render when escape', () => {
14
- expect(markdownIt.render('$a = 1\\$')).toEqual('<p>$a = 1$</p>\n');
15
- expect(markdownIt.render('\\$a = 1$')).toEqual('<p>$a = 1$</p>\n');
16
- });
17
-
18
- it('Should not render when having spaces', () => {
19
- expect(markdownIt.render(`$ a = 1 $`)).toEqual('<p>$ a = 1 $</p>\n');
20
- });
21
-
22
- it('Should not render when the ending tag is followed by number', () => {
23
- expect(markdownIt.render(`Of course $1 = $1`)).toEqual(
24
- '<p>Of course $1 = $1</p>\n',
25
- );
26
- });
27
-
28
- it('Should render when the first one is after a charater', () => {
29
- expect(markdownIt.render(`The next$a = 1$ won't work`)).toMatchSnapshot();
30
- });
31
-
32
- it('Should not render error msg when content is wrong', () => {
33
- expect(markdownIt.render('$\\fra{a}{b}$')).toMatchSnapshot();
34
- });
35
- });
36
-
37
- describe('block mathjax', () => {
38
- it('Should render', () => {
39
- const result1 = markdownIt.render(`$$a=1$$`);
40
- const result2 = markdownIt.render(`
41
- $$
42
- a = 1
43
- $$
44
- `);
45
-
46
- expect(result1).toMatch(/^<svg/);
47
- expect(result1).toMatch(/<\/svg>$/);
48
- expect(result1).toMatchSnapshot();
49
- expect(result2).toMatch(/^<svg/);
50
- expect(result2).toMatch(/<\/svg>$/);
51
- expect(result2).toMatchSnapshot();
52
- });
53
-
54
- it('Should not render when escape', () => {
55
- expect(markdownIt.render('\\$\\$a = 1$$')).toEqual('<p>$$a = 1$$</p>\n');
56
- expect(
57
- markdownIt.render(`
58
- \\$\\$
59
- a = 1
60
- \\$\\$
61
- `),
62
- ).toEqual(`<p>$$
63
- a = 1
64
- $$</p>\n`);
65
- });
66
-
67
- it('Should render when having spaces', () => {
68
- const result1 = markdownIt.render(`$$ a = 1 $$`);
69
-
70
- expect(result1).toMatch(/^<svg/);
71
- expect(result1).toMatch(/<\/svg>$/);
72
- expect(result1).toMatchSnapshot();
73
-
74
- expect(markdownIt.render(`All $$ a = 1 $$ is true.`)).toEqual(
75
- '<p>All $$ a = 1 $$ is true.</p>\n',
76
- );
77
- });
78
-
79
- it('Should not render error msg when content is wrong', () => {
80
- const result1 = markdownIt.render('$$\\fra{a}{b}$$');
81
- const result2 = markdownIt.render(`
82
- $$
83
- \\fra{a}{b}
84
- $$
85
- `);
86
-
87
- expect(result1).toMatch(/^<svg/);
88
- expect(result1).toMatch(/<\/svg>$/);
89
- expect(result1).toMatchSnapshot();
90
- expect(result2).toMatch(/^<svg/);
91
- expect(result2).toMatch(/<\/svg>$/);
92
- expect(result2).toMatchSnapshot();
93
- });
94
- });