marked-cjk-friendly 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2024 Tatsunori Uchino, and authors and contributors of original packages
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # marked-cjk-friendly
2
+
3
+ A [Marked.js](https://github.com/markedjs/marked) extension to make Markdown emphasis (`**`) in CommonMark compatible with Chinese, Japanese, and Korean (CJK).
4
+
5
+ <span lang="ja">CommonMarkの強調記号(`**`)を日本語・中国語・韓国語にきちんと対応させるための[Marked.js](https://github.com/markedjs/marked)拡張</span>
6
+
7
+ <span lang="zh-Hans-CN">一个 [Marked.js](https://github.com/markedjs/marked) 扩展,用于使 CommonMark 的强调标记(`**`)能够正确支持中文、日语和韩语文本。</span>
8
+
9
+ <span lang="ko">CommonMark의 강조 표시(`**`) 를 한국어, 일본어, 중국어와 호환되도록 만드는 [Marked.js](https://github.com/markedjs/marked) 확장</span>
10
+
11
+ ## Problem / <span lang="ja">問題</span> / <span lang="zh-Hans-CN">问题</span> / <span lang="ko">문제</span>
12
+
13
+ CommonMark has a problem that the following emphasis marks `**` are not recognized as emphasis marks in Japanese, Chinese, and Korean.
14
+
15
+ <span lang="ja">CommonMarkには、日本語・中国語・韓国語内の次のような強調記号(`**`)が強調記号として認識されない問題があります。</span>
16
+
17
+ <span lang="zh-Hans-CN">CommonMark存在以下问题:在中文、日语和韩语文本中,强调标记`**`不会被识别为强调标记。</span>
18
+
19
+ <span lang="ko">CommonMark는 한국어, 일본어, 중국어에서 다음과 같은 강조 표시 `**`가 강조 표시로 인식되지 않는 문제가 있습니다.</span>
20
+
21
+ ```md
22
+ **このアスタリスクは強調記号として認識されず、そのまま表示されます。**この文のせいで。
23
+
24
+ **该星号不会被识别,而是直接显示。**这是因为它没有被识别为强调符号。
25
+
26
+ **이 별표는 강조 표시로 인식되지 않고 그대로 표시됩니다(이 괄호 때문에)**이 문장 때문에.
27
+ ```
28
+
29
+ CommonMark issue: https://github.com/commonmark/commonmark-spec/issues/650
30
+
31
+ ## Runtime Requirements / <span lang="ja">実行環境の要件</span> / <span lang="zh-Hans-CN">运行环境要求</span> / <span lang="ko">런타임 요구 사항</span>
32
+
33
+ This package is ESM-only. It requires Node.js 18 or later.
34
+
35
+ <span lang="ja">本パッケージはESM専用です。Node.js 18以上が必要です。</span>
36
+
37
+ <span lang="zh-Hans-CN">此包仅支持ESM。需要Node.js 18或更高版本。</span>
38
+
39
+ <span lang="ko">본 패키지는 ESM 전용입니다. Node.js 18 이상이 필요합니다.</span>
40
+
41
+ ## Installation / <span lang="ja">インストール</span> / <span lang="zh-Hans-CN">安装</span> / <span lang="ko">설치</span>
42
+
43
+ Install `marked-cjk-friendly` via [npm](https://www.npmjs.com/):
44
+
45
+ ```bash
46
+ npm install marked-cjk-friendly
47
+ ```
48
+
49
+ If you use another package manager, please replace `npm install` with the command of the package manager you use (e.g. `pnpm add` or `yarn add`).
50
+
51
+ ## Usage / <span lang="ja">使い方</span> / <span lang="zh-Hans-CN">用法</span> / <span lang="ko">사용법</span>
52
+
53
+ Import `marked` and `marked-cjk-friendly`, and use the extension as follows:
54
+
55
+ ```js
56
+ import { Marked } from "marked";
57
+ import markedCjkFriendly from "marked-cjk-friendly";
58
+
59
+ const marked = new Marked(markedCjkFriendly());
60
+ const html = marked.parse("**この文は太字になりますか?**即便加入这句也可以吗?");
61
+ ```
62
+
63
+ Or using the `use` method:
64
+
65
+ ```js
66
+ import { marked } from "marked";
67
+ import markedCjkFriendly from "marked-cjk-friendly";
68
+
69
+ marked.use(markedCjkFriendly());
70
+ const html = marked("**この文は太字になりますか?**即便加入这句也可以吗?");
71
+ ```
72
+
73
+ ## Compatibility with the other languages / <span lang="ja">他言語との互換性</span> / <span lang="zh-Hans-CN">与其他语言的兼容性</span> / <span lang="ko">다른 언어와의 호환성</span>
74
+
75
+ This modification of the specification does not affect the other languages than Chinese, Japanese, and Korean. Even if your application or document has translations or content in other languages, it will not be affected, so please feel free to use this package.
76
+
77
+ <span lang="ja">この仕様変更提案は、日本語・中国語・韓国語以外の言語には影響しません。アプリケーションやドキュメントに他言語の翻訳やコンテンツが含まれていても影響はありませんので、安心して本パッケージをご利用ください。</span>
78
+
79
+ <span lang="zh-Hans-CN">除中文、日文和韩文外,建议的规范变更不会影响其他语言。请放心使用此软件包。</span>
80
+
81
+ <span lang="ko">이 사양 변경 제안은 한국어, 일본어, 중국어 이외의 언어에는 영향을 미치지 않습니다. 애플리케이션이나 문서에 다른 언어의 번역이나 콘텐츠가 포함되어 있어도 영향을 받지 않으므로 안심하고 본 패키지를 사용하시기 바랍니다.</span>
82
+
83
+ ## Specification / <span lang="ja">規格書</span> / <span lang="zh-Hans-CN">规范</span> / <span lang="ko">설명서</span>
84
+
85
+ https://github.com/tats-u/markdown-cjk-friendly/blob/main/specification.md (English)
86
+
87
+ ## Related packages / <span lang="ja">関連パッケージ</span> / <span lang="zh-Hans-CN">相关包</span> / <span lang="ko">관련 패키지</span>
88
+
89
+ - [markdown-it-cjk-friendly](https://npmjs.com/package/markdown-it-cjk-friendly) — markdown-it plugin
90
+ - [remark-cjk-friendly](https://npmjs.com/package/remark-cjk-friendly) — remark plugin
91
+ - [micromark-extension-cjk-friendly](https://npmjs.com/package/micromark-extension-cjk-friendly) — micromark extension
@@ -0,0 +1,18 @@
1
+ import { MarkedExtension } from "marked";
2
+
3
+ //#region src/index.d.ts
4
+
5
+ /**
6
+ * Creates a marked extension that makes emphasis markers CJK-friendly.
7
+ *
8
+ * This extension modifies how `*` and `_` emphasis delimiters are detected
9
+ * so that they work correctly adjacent to CJK (Chinese, Japanese, Korean) characters.
10
+ *
11
+ * In standard CommonMark, emphasis delimiters like `**` may not be recognized
12
+ * when adjacent to CJK punctuation, because CJK characters are not classified
13
+ * as Unicode punctuation or whitespace. This extension treats CJK characters
14
+ * as equivalent to punctuation for flanking delimiter detection.
15
+ */
16
+ declare function markedCjkFriendly(): MarkedExtension;
17
+ //#endregion
18
+ export { markedCjkFriendly as default };
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
1
+ //#region src/index.ts
2
+ const CJK = "\\u1100-\\u11ff\\u20a9\\u2329-\\u232a\\u2630-\\u2637\\u268a-\\u268f\\u2e80-\\u2e99\\u2e9b-\\u2ef3\\u2f00-\\u2fd5\\u2ff0-\\u303e\\u3041-\\u3096\\u3099-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u3190-\\u31e5\\u31ef-\\u321e\\u3220-\\u3247\\u3250-\\ua48c\\ua490-\\ua4c6\\ua960-\\ua97c\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufaff\\ufe10-\\ufe19\\ufe30-\\ufe52\\ufe54-\\ufe66\\ufe68-\\ufe6b\\uff01-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc\\uffe0-\\uffe6\\uffe8-\\uffee\\u{16fe0}-\\u{16fe4}\\u{16ff0}-\\u{16ff6}\\u{17000}-\\u{18cd5}\\u{18cff}-\\u{18d1e}\\u{18d80}-\\u{18df2}\\u{1aff0}-\\u{1aff3}\\u{1aff5}-\\u{1affb}\\u{1affd}-\\u{1affe}\\u{1b000}-\\u{1b122}\\u{1b132}\\u{1b150}-\\u{1b152}\\u{1b155}\\u{1b164}-\\u{1b167}\\u{1b170}-\\u{1b2fb}\\u{1d300}-\\u{1d356}\\u{1d360}-\\u{1d376}\\u{1f200}\\u{1f202}\\u{1f210}-\\u{1f219}\\u{1f21b}-\\u{1f22e}\\u{1f230}-\\u{1f231}\\u{1f237}\\u{1f23b}\\u{1f240}-\\u{1f248}\\u{1f260}-\\u{1f265}\\u{20000}-\\u{3fffd}";
3
+ const cjkTest = new RegExp(`[${CJK}]`, "u");
4
+ const punctuationCjk = new RegExp(`^((?![*_])[\\s\\p{P}\\p{S}${CJK}])`, "u");
5
+ function buildRDelimAst(punct, punctSpace, notPunctSpace) {
6
+ return new RegExp(`^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)${punct}(\\*+)(?=[\\s]|$)|${notPunctSpace}(\\*+)(?!\\*)(?=${punctSpace}|$)|(?!\\*)${punctSpace}(\\*+)(?=${notPunctSpace})|[\\s](\\*+)(?!\\*)(?=${punct})|(?!\\*)${punct}(\\*+)(?!\\*)(?=${punct})|${notPunctSpace}(\\*+)(?=${notPunctSpace})`, "gu");
7
+ }
8
+ function buildRDelimUnd(punct, punctSpace, notPunctSpace) {
9
+ return new RegExp(`^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)${punct}(_+)(?=[\\s]|$)|${notPunctSpace}(_+)(?!_)(?=${punctSpace}|$)|(?!_)${punctSpace}(_+)(?=${notPunctSpace})|[\\s](_+)(?!_)(?=${punct})|(?!_)${punct}(_+)(?!_)(?=${punct})`, "gu");
10
+ }
11
+ function buildRDelimDel(punct, punctSpace, notPunctSpace) {
12
+ return new RegExp(`^[^~]+(?=[^~])|(?!~)${punct}(~~?)(?=[\\s]|$)|${notPunctSpace}(~~?)(?!~)(?=${punctSpace}|$)|(?!~)${punctSpace}(~~?)(?=${notPunctSpace})|[\\s](~~?)(?!~)(?=${punct})|(?!~)${punct}(~~?)(?!~)(?=${punct})|${notPunctSpace}(~~?)(?=${notPunctSpace})`, "gu");
13
+ }
14
+ const cjkPunct = `[\\p{P}\\p{S}${CJK}]`;
15
+ const cjkPunctSpace = `[\\s\\p{P}\\p{S}${CJK}]`;
16
+ const cjkNotPunctSpace = `[^\\s\\p{P}\\p{S}${CJK}]`;
17
+ const cjkDelPunct = `(?![*_])[\\p{P}\\p{S}${CJK}]`;
18
+ const cjkDelPunctSpace = `(?![*_])[\\s\\p{P}\\p{S}${CJK}]`;
19
+ const cjkDelNotPunctSpace = `(?:[^\\s\\p{P}\\p{S}${CJK}]|[*_])`;
20
+ const cjkPunctGfm = `(?!~)[\\p{P}\\p{S}${CJK}]`;
21
+ const cjkPunctSpaceGfm = `(?!~)[\\s\\p{P}\\p{S}${CJK}]`;
22
+ const cjkNotPunctSpaceGfm = `(?:[^\\s\\p{P}\\p{S}${CJK}]|~)`;
23
+ const emStrongRDelimAstCjk = buildRDelimAst(cjkPunct, cjkPunctSpace, cjkNotPunctSpace);
24
+ const emStrongRDelimAstCjkGfm = buildRDelimAst(cjkPunctGfm, cjkPunctSpaceGfm, cjkNotPunctSpaceGfm);
25
+ const emStrongRDelimUndCjk = buildRDelimUnd(cjkPunct, cjkPunctSpace, cjkNotPunctSpace);
26
+ const delRDelimCjk = buildRDelimDel(cjkDelPunct, cjkDelPunctSpace, cjkDelNotPunctSpace);
27
+ /**
28
+ * Checks whether the character immediately before `src` should be treated as CJK.
29
+ *
30
+ * Marked passes `prevChar` as a single UTF-16 code unit, so supplementary-plane
31
+ * characters may arrive as a lone surrogate and variation sequences may point at
32
+ * the variation selector instead of the base character. Recover from `maskedSrc`
33
+ * when needed so CJK-aware flanking checks see the actual preceding code point.
34
+ */
35
+ function isPrevCharCjk(prevChar, maskedSrc, src) {
36
+ let prevIsCjk = punctuationCjk.test(prevChar);
37
+ if (!prevIsCjk && prevChar) {
38
+ const prevIdx = maskedSrc.length - src.length;
39
+ if (prevIdx >= 1) {
40
+ let idx = prevIdx - 1;
41
+ let code = maskedSrc.charCodeAt(idx);
42
+ if (code >= 65024 && code <= 65038 && idx >= 1) {
43
+ idx--;
44
+ code = maskedSrc.charCodeAt(idx);
45
+ }
46
+ if ((code & 64512) === 56320 && idx >= 1) {
47
+ const cp = maskedSrc.codePointAt(idx - 1);
48
+ if (cp !== void 0 && cp > 65535) if (cp >= 917760 && cp <= 917999) prevIsCjk = true;
49
+ else prevIsCjk = cjkTest.test(String.fromCodePoint(cp));
50
+ } else prevIsCjk = cjkTest.test(String.fromCharCode(code));
51
+ }
52
+ }
53
+ return prevIsCjk;
54
+ }
55
+ /**
56
+ * Checks whether a matched right delimiter is immediately adjacent to CJK text.
57
+ *
58
+ * Marked classifies these matches as left-only, right-only, or both using regex
59
+ * groups. When CJK sits next to the delimiter, we treat the delimiter as "both"
60
+ * so GFM emphasis/strikethrough can close across CJK punctuation boundaries.
61
+ */
62
+ function isCjkAdjacentToDelimiter(rightMatch, clippedMaskedSrc) {
63
+ if (!(rightMatch[1] || rightMatch[2] || rightMatch[3] || rightMatch[4])) return false;
64
+ const charBefore = String.fromCodePoint(rightMatch[0].codePointAt(0));
65
+ const afterPos = rightMatch.index + rightMatch[0].length;
66
+ const charAfter = afterPos < clippedMaskedSrc.length ? String.fromCodePoint(clippedMaskedSrc.codePointAt(afterPos)) : "";
67
+ return cjkTest.test(charBefore) || cjkTest.test(charAfter);
68
+ }
69
+ /**
70
+ * Creates a marked extension that makes emphasis markers CJK-friendly.
71
+ *
72
+ * This extension modifies how `*` and `_` emphasis delimiters are detected
73
+ * so that they work correctly adjacent to CJK (Chinese, Japanese, Korean) characters.
74
+ *
75
+ * In standard CommonMark, emphasis delimiters like `**` may not be recognized
76
+ * when adjacent to CJK punctuation, because CJK characters are not classified
77
+ * as Unicode punctuation or whitespace. This extension treats CJK characters
78
+ * as equivalent to punctuation for flanking delimiter detection.
79
+ */
80
+ function markedCjkFriendly() {
81
+ return { tokenizer: {
82
+ emStrong(src, maskedSrc, prevChar = "") {
83
+ const { rules } = this;
84
+ const match = rules.inline.emStrongLDelim.exec(src);
85
+ if (!match) return false;
86
+ if (match[3] && prevChar.match(rules.other.unicodeAlphaNumeric)) return false;
87
+ const nextChar = match[1] || match[2] || "";
88
+ const prevIsCjk = isPrevCharCjk(prevChar, maskedSrc, src);
89
+ if (!nextChar || !prevChar || rules.inline.punctuation.exec(prevChar) || prevIsCjk || cjkTest.test(nextChar)) {
90
+ const lLength = [...match[0]].length - 1;
91
+ let rDelim;
92
+ let rLength;
93
+ let delimTotal = lLength;
94
+ let midDelimTotal = 0;
95
+ const isGfm = rules.inline.emStrongRDelimAst.source.includes("(?!~)");
96
+ let endReg;
97
+ if (match[0][0] === "*") endReg = isGfm ? emStrongRDelimAstCjkGfm : emStrongRDelimAstCjk;
98
+ else endReg = emStrongRDelimUndCjk;
99
+ endReg.lastIndex = 0;
100
+ const clippedMaskedSrc = maskedSrc.slice(-1 * src.length + lLength);
101
+ let rMatch;
102
+ while ((rMatch = endReg.exec(clippedMaskedSrc)) != null) {
103
+ rDelim = rMatch[1] || rMatch[2] || rMatch[3] || rMatch[4] || rMatch[5] || rMatch[6];
104
+ if (!rDelim) continue;
105
+ rLength = [...rDelim].length;
106
+ const isCjkAdjacent = isCjkAdjacentToDelimiter(rMatch, clippedMaskedSrc);
107
+ if ((rMatch[3] || rMatch[4]) && !isCjkAdjacent) {
108
+ delimTotal += rLength;
109
+ continue;
110
+ }
111
+ if (rMatch[5] || rMatch[6] || isCjkAdjacent) {
112
+ if (lLength % 3 && !((lLength + rLength) % 3)) {
113
+ midDelimTotal += rLength;
114
+ continue;
115
+ }
116
+ }
117
+ delimTotal -= rLength;
118
+ if (delimTotal > 0) continue;
119
+ rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
120
+ const lastCharLength = rMatch[0].codePointAt(0) > 65535 ? 2 : 1;
121
+ const raw = src.slice(0, lLength + rMatch.index + lastCharLength + rLength);
122
+ if (Math.min(lLength, rLength) % 2) {
123
+ const text$1 = raw.slice(1, -1);
124
+ return {
125
+ type: "em",
126
+ raw,
127
+ text: text$1,
128
+ tokens: this.lexer.inlineTokens(text$1)
129
+ };
130
+ }
131
+ const text = raw.slice(2, -2);
132
+ return {
133
+ type: "strong",
134
+ raw,
135
+ text,
136
+ tokens: this.lexer.inlineTokens(text)
137
+ };
138
+ }
139
+ }
140
+ },
141
+ del(src, maskedSrc, prevChar = "") {
142
+ const { rules } = this;
143
+ const match = rules.inline.delLDelim.exec(src);
144
+ if (!match) return false;
145
+ const nextChar = match[1] || "";
146
+ const prevIsCjk = isPrevCharCjk(prevChar, maskedSrc, src);
147
+ if (!nextChar || !prevChar || rules.inline.punctuation.exec(prevChar) || prevIsCjk || cjkTest.test(nextChar)) {
148
+ const lLength = [...match[0]].length - 1;
149
+ let rDelim;
150
+ let rLength;
151
+ let delimTotal = lLength;
152
+ delRDelimCjk.lastIndex = 0;
153
+ const clippedMaskedSrc = maskedSrc.slice(-1 * src.length + lLength);
154
+ let rMatch;
155
+ while ((rMatch = delRDelimCjk.exec(clippedMaskedSrc)) != null) {
156
+ rDelim = rMatch[1] || rMatch[2] || rMatch[3] || rMatch[4] || rMatch[5] || rMatch[6];
157
+ if (!rDelim) continue;
158
+ rLength = [...rDelim].length;
159
+ if (rLength !== lLength) continue;
160
+ const isCjkAdjacent = isCjkAdjacentToDelimiter(rMatch, clippedMaskedSrc);
161
+ if ((rMatch[3] || rMatch[4]) && !isCjkAdjacent) {
162
+ delimTotal += rLength;
163
+ continue;
164
+ }
165
+ delimTotal -= rLength;
166
+ if (delimTotal > 0) continue;
167
+ rLength = Math.min(rLength, rLength + delimTotal);
168
+ const lastCharLength = rMatch[0].codePointAt(0) > 65535 ? 2 : 1;
169
+ const raw = src.slice(0, lLength + rMatch.index + lastCharLength + rLength);
170
+ const text = raw.slice(lLength, -lLength);
171
+ return {
172
+ type: "del",
173
+ raw,
174
+ text,
175
+ tokens: this.lexer.inlineTokens(text)
176
+ };
177
+ }
178
+ }
179
+ }
180
+ } };
181
+ }
182
+
183
+ //#endregion
184
+ export { markedCjkFriendly as default };
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "marked-cjk-friendly",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ },
10
+ "./package.json": "./package.json"
11
+ },
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "files": [
15
+ "dist",
16
+ "LICENSE",
17
+ "README.md"
18
+ ],
19
+ "repository": {
20
+ "url": "https://github.com/tats-u/markdown-cjk-friendly"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Tatsunori Uchino <tats.u@live.jp> (https://github.com/tats-u)",
24
+ "bugs": "https://github.com/tats-u/markdown-cjk-friendly/issues",
25
+ "keywords": [
26
+ "marked",
27
+ "marked-extension",
28
+ "markdown",
29
+ "japanese",
30
+ "chinese",
31
+ "korean",
32
+ "cjk"
33
+ ],
34
+ "description": "Marked.js extension to make Markdown emphasis (`**`) in CommonMark more friendly with Chinese, Japanese, and Korean (CJK)",
35
+ "sideEffects": false,
36
+ "devDependencies": {
37
+ "marked": "^17.0.0"
38
+ },
39
+ "peerDependencies": {
40
+ "marked": ">=15.0.0"
41
+ },
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "scripts": {
46
+ "build": "tsdown",
47
+ "build:lib": "tsdown",
48
+ "dev": "tsdown --watch --sourcemaps",
49
+ "dev:lib": "tsdown --watch --sourcemaps",
50
+ "test": "vitest run",
51
+ "test:lib": "vitest run",
52
+ "test:up": "vitest -u",
53
+ "test:watch": "vitest watch",
54
+ "test:lib:watch": "vitest watch",
55
+ "bench": "vitest bench --run",
56
+ "bench:watch": "vitest bench",
57
+ "lint:type": "tsc --noEmit"
58
+ }
59
+ }