@xihe-lab/tapd-core 2.0.0-rc.1 → 2.0.0-rc.2
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 +22 -0
- package/dist/registry/richtext-manifests.generated.d.ts +1 -1
- package/dist/registry/richtext-manifests.generated.d.ts.map +1 -1
- package/dist/registry/richtext-manifests.generated.js +1 -1
- package/dist/registry/richtext-manifests.generated.js.map +1 -1
- package/dist/registry/richtext.d.ts +9 -0
- package/dist/registry/richtext.d.ts.map +1 -1
- package/dist/registry/richtext.js +33 -15
- package/dist/registry/richtext.js.map +1 -1
- package/dist/registry/richtext.test.js +70 -7
- package/dist/registry/richtext.test.js.map +1 -1
- package/dist/richtext/attachment-anchor.d.ts +58 -0
- package/dist/richtext/attachment-anchor.d.ts.map +1 -0
- package/dist/richtext/attachment-anchor.js +221 -0
- package/dist/richtext/attachment-anchor.js.map +1 -0
- package/dist/richtext/attachment-anchor.test.d.ts +2 -0
- package/dist/richtext/attachment-anchor.test.d.ts.map +1 -0
- package/dist/richtext/attachment-anchor.test.js +149 -0
- package/dist/richtext/attachment-anchor.test.js.map +1 -0
- package/dist/richtext/escape.d.ts +7 -0
- package/dist/richtext/escape.d.ts.map +1 -0
- package/dist/richtext/escape.js +60 -0
- package/dist/richtext/escape.js.map +1 -0
- package/dist/richtext/index.d.ts +15 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +35 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/mention.d.ts +49 -0
- package/dist/richtext/mention.d.ts.map +1 -0
- package/dist/richtext/mention.js +179 -0
- package/dist/richtext/mention.js.map +1 -0
- package/dist/richtext/mention.test.d.ts +2 -0
- package/dist/richtext/mention.test.d.ts.map +1 -0
- package/dist/richtext/mention.test.js +123 -0
- package/dist/richtext/mention.test.js.map +1 -0
- package/dist/richtext/pipeline.d.ts +5 -0
- package/dist/richtext/pipeline.d.ts.map +1 -0
- package/dist/richtext/pipeline.js +199 -0
- package/dist/richtext/pipeline.js.map +1 -0
- package/dist/richtext/round-trip.test.d.ts +2 -0
- package/dist/richtext/round-trip.test.d.ts.map +1 -0
- package/dist/richtext/round-trip.test.js +105 -0
- package/dist/richtext/round-trip.test.js.map +1 -0
- package/dist/sdk-routes.d.ts.map +1 -1
- package/dist/sdk-routes.js +4 -0
- package/dist/sdk-routes.js.map +1 -1
- package/dist/tapd-client.d.ts +45 -0
- package/dist/tapd-client.d.ts.map +1 -1
- package/dist/tapd-client.js +74 -0
- package/dist/tapd-client.js.map +1 -1
- package/dist/tools/attachment.d.ts +47 -0
- package/dist/tools/attachment.d.ts.map +1 -1
- package/dist/tools/attachment.js +247 -1
- package/dist/tools/attachment.js.map +1 -1
- package/dist/tools/attachment.test.d.ts +2 -0
- package/dist/tools/attachment.test.d.ts.map +1 -0
- package/dist/tools/attachment.test.js +432 -0
- package/dist/tools/attachment.test.js.map +1 -0
- package/dist/tools/bug.d.ts.map +1 -1
- package/dist/tools/bug.js +3 -0
- package/dist/tools/bug.js.map +1 -1
- package/dist/tools/comment.d.ts.map +1 -1
- package/dist/tools/comment.js +3 -0
- package/dist/tools/comment.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/media.d.ts +9 -0
- package/dist/tools/media.d.ts.map +1 -0
- package/dist/tools/media.js +45 -0
- package/dist/tools/media.js.map +1 -0
- package/dist/tools/richtext-wiring.test.d.ts +2 -0
- package/dist/tools/richtext-wiring.test.d.ts.map +1 -0
- package/dist/tools/richtext-wiring.test.js +302 -0
- package/dist/tools/richtext-wiring.test.js.map +1 -0
- package/dist/tools/story.d.ts.map +1 -1
- package/dist/tools/story.js +3 -0
- package/dist/tools/story.js.map +1 -1
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +3 -0
- package/dist/tools/task.js.map +1 -1
- package/dist/tools/utility.d.ts.map +1 -1
- package/dist/tools/utility.js +133 -12
- package/dist/tools/utility.js.map +1 -1
- package/dist/tools/wiki.d.ts.map +1 -1
- package/dist/tools/wiki.js +20 -5
- package/dist/tools/wiki.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -5
- package/dist/tools/zz-acceptance-echo.d.ts +0 -3
- package/dist/tools/zz-acceptance-echo.d.ts.map +0 -1
- package/dist/tools/zz-acceptance-echo.js +0 -9
- package/dist/tools/zz-acceptance-echo.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @xihe-lab/tapd-core
|
|
2
|
+
|
|
3
|
+
TAPD 研发协作工具的**共享内核**:沉淀 TAPD 全部工具定义、HTTP 客户端与工具注册表,供 `@xihe-lab/tapd-cli` 与 `@xihe-lab/tapd-mcp-server` 复用。单独安装本包通常没有直接用途。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @xihe-lab/tapd-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 能力概览
|
|
12
|
+
|
|
13
|
+
- **工具定义**:`src/tools/` 按 TAPD 领域组织——需求(story)、缺陷(bug)、任务(task)、迭代(iteration)、Wiki、附件、评论、用户、工作区、发布、看板、工时、报表等,统一收敛为 `allTools`
|
|
14
|
+
- **HTTP 客户端**:`TapdClient`,支持 Bearer Token(`fromAccessToken`)与 Basic Auth(`fromBasicAuth`)两种认证
|
|
15
|
+
- **工具注册表**:`ToolRegistry`,负责工具注册、执行、审计(`AuditEvent`)与写策略裁决(`resolveWrite`)
|
|
16
|
+
- **配置**:`config.ts` 提供配置加载/保存与注入环境变量
|
|
17
|
+
- **富文本**:`richtext/` 语义库,md ↔ html 双向转换与 `@`/附件锚点处理
|
|
18
|
+
- **Schema 导出**:`exportSchemas` 导出工具 JSON Schema
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Apache-2.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext-manifests.generated.d.ts","sourceRoot":"","sources":["../../src/registry/richtext-manifests.generated.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"richtext-manifests.generated.d.ts","sourceRoot":"","sources":["../../src/registry/richtext-manifests.generated.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA4C,CAAC;AAE3F,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CA6F3E,CACA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// AUTO-GENERATED by scripts/generate-richtext-manifests.ts - do not edit manually.
|
|
2
2
|
// write tools with richtext params: 30, total tools scanned: 212
|
|
3
|
-
export const
|
|
3
|
+
export const DUAL_WRITE_TOOLS = ["tapd_create_wiki", "tapd_update_wiki"];
|
|
4
4
|
export const WRITE_RICHTEXT_FIELDS_BY_TOOL = {
|
|
5
5
|
'tapd_create_iteration': [
|
|
6
6
|
'description'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext-manifests.generated.js","sourceRoot":"","sources":["../../src/registry/richtext-manifests.generated.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,iEAAiE;AACjE,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"richtext-manifests.generated.js","sourceRoot":"","sources":["../../src/registry/richtext-manifests.generated.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,iEAAiE;AACjE,MAAM,CAAC,MAAM,gBAAgB,GAAsB,CAAC,kBAAkB,EAAC,kBAAkB,CAAC,CAAC;AAE3F,MAAM,CAAC,MAAM,6BAA6B,GAAsC;IAC9E,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,mBAAmB,EAAE;QACnB,aAAa;KACd;IACD,mBAAmB,EAAE;QACnB,aAAa;KACd;IACD,iBAAiB,EAAE;QACjB,aAAa;KACd;IACD,iBAAiB,EAAE;QACjB,aAAa;KACd;IACD,kBAAkB,EAAE;QAClB,aAAa;KACd;IACD,kBAAkB,EAAE;QAClB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,iBAAiB,EAAE;QACjB,aAAa;KACd;IACD,oBAAoB,EAAE;QACpB,aAAa;KACd;IACD,kBAAkB,EAAE;QAClB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,kBAAkB,EAAE;QAClB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,mBAAmB,EAAE;QACnB,aAAa;KACd;IACD,sBAAsB,EAAE;QACtB,aAAa;KACd;IACD,8BAA8B,EAAE;QAC9B,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,aAAa;KACd;IACD,kBAAkB,EAAE;QAClB,aAAa;QACb,sBAAsB;KACvB;IACD,kBAAkB,EAAE;QAClB,aAAa;QACb,sBAAsB;KACvB;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,sBAAsB,EAAE;QACtB,aAAa;KACd;IACD,qBAAqB,EAAE;QACrB,aAAa;KACd;IACD,wBAAwB,EAAE;QACxB,aAAa;KACd;CACF,CACA"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* raw_html 直发通道(P3,FSD §3.5,需求 1139814312001001548)。
|
|
4
|
+
* 富文本写工具(comment/story/task/bug/wiki 的 create/update)共享的 schema 字段:
|
|
5
|
+
* true 时 description 原样透传(绕过 md→html 自动转换,R7 服务端保真),适用于已含
|
|
6
|
+
* TAPD 附件锚点 / at-who 标记的富文本或需要确定性透传的场景。默认 false 走 md 管道。
|
|
7
|
+
* 参数在 transformWriteArgs 内消费并摘除,不会透传给 TAPD API。
|
|
8
|
+
*/
|
|
9
|
+
export declare const RAW_HTML_FIELD: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1
10
|
export declare const READ_RICHTEXT_FIELDS: ReadonlySet<string>;
|
|
2
11
|
export declare function isRichtextAutoEnabled(): boolean;
|
|
3
12
|
export declare function looksLikeHtml(value: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext.d.ts","sourceRoot":"","sources":["../../src/registry/richtext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"richtext.d.ts","sourceRoot":"","sources":["../../src/registry/richtext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,2CAE1B,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAA4B,CAAC;AAElF,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB3G;AAGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAGxD"}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const turndown = new TurndownService({ headingStyle: 'atx', codeBlockStyle: 'fenced' });
|
|
7
|
-
turndown.use(gfm);
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { DUAL_WRITE_TOOLS, WRITE_RICHTEXT_FIELDS_BY_TOOL } from './richtext-manifests.generated.js';
|
|
3
|
+
// rc.2 P3 接线(1139814312001001548):写/读管道与 md_to_html/html_to_md 工具共用同一条
|
|
4
|
+
// 保真转换管道(richtext/pipeline.ts,token/规则级 @ + 附件锚点接线)——FSD §3.7。
|
|
5
|
+
import { htmlToMd, mdToHtml } from '../richtext/pipeline.js';
|
|
8
6
|
const BLOCK_HTML_RE = /<(p|div|ul|ol|li|table|thead|tbody|tr|td|th|strong|em|h[1-6]|blockquote|pre|br|a|span|code|img|hr|s|del|u|font|b|i)\b[^>]*>/i;
|
|
7
|
+
/**
|
|
8
|
+
* raw_html 直发通道(P3,FSD §3.5,需求 1139814312001001548)。
|
|
9
|
+
* 富文本写工具(comment/story/task/bug/wiki 的 create/update)共享的 schema 字段:
|
|
10
|
+
* true 时 description 原样透传(绕过 md→html 自动转换,R7 服务端保真),适用于已含
|
|
11
|
+
* TAPD 附件锚点 / at-who 标记的富文本或需要确定性透传的场景。默认 false 走 md 管道。
|
|
12
|
+
* 参数在 transformWriteArgs 内消费并摘除,不会透传给 TAPD API。
|
|
13
|
+
*/
|
|
14
|
+
export const RAW_HTML_FIELD = z.boolean().optional().default(false).describe('raw HTML 直发通道:true 时 description 原样透传(绕过 md→html 自动转换,服务端保真),适用于已含 TAPD 附件锚点/at-who 标记的富文本;默认 false 走 md 管道(@昵称/附件引用自动转换)');
|
|
9
15
|
// TAPD 实体响应的富文本字段统一命名为 description(story/bug/task/comment/wiki/iteration/...)
|
|
10
16
|
export const READ_RICHTEXT_FIELDS = new Set(['description']);
|
|
11
17
|
export function isRichtextAutoEnabled() {
|
|
@@ -14,27 +20,34 @@ export function isRichtextAutoEnabled() {
|
|
|
14
20
|
export function looksLikeHtml(value) {
|
|
15
21
|
return BLOCK_HTML_RE.test(value);
|
|
16
22
|
}
|
|
17
|
-
//
|
|
23
|
+
// 写侧三层路由:raw_html 旁路 -> wiki 双写 -> 启发式双模 -> 关闭时全原样
|
|
18
24
|
export function transformWriteArgs(toolName, args) {
|
|
25
|
+
const out = { ...args };
|
|
26
|
+
// raw_html 旁路(P3,R7 服务端保真):先摘除,避免作为未知参数透传给 TAPD API
|
|
27
|
+
const rawHtml = out.raw_html === true;
|
|
28
|
+
delete out.raw_html;
|
|
19
29
|
if (!isRichtextAutoEnabled())
|
|
20
|
-
return
|
|
30
|
+
return out;
|
|
21
31
|
const fields = WRITE_RICHTEXT_FIELDS_BY_TOOL[toolName];
|
|
22
32
|
if (!fields)
|
|
23
|
-
return
|
|
24
|
-
const out = { ...args };
|
|
33
|
+
return out;
|
|
25
34
|
for (const field of fields) {
|
|
26
35
|
const value = out[field];
|
|
27
36
|
if (typeof value !== 'string' || value.trim() === '' || looksLikeHtml(value))
|
|
28
37
|
continue;
|
|
29
|
-
|
|
38
|
+
// raw_html: true → description 原样透传,绕过 md→html(含 at-who/附件锚点转换);
|
|
39
|
+
// markdown_description 维持既有双写策略:永不自动改写(raw_html 时也无 md 源可回填,不自动补 markdown_description)
|
|
40
|
+
if (rawHtml)
|
|
41
|
+
continue;
|
|
42
|
+
if (DUAL_WRITE_TOOLS.includes(toolName)) {
|
|
30
43
|
if (field === 'description') {
|
|
31
44
|
if (out.markdown_description === undefined)
|
|
32
45
|
out.markdown_description = value;
|
|
33
|
-
|
|
46
|
+
out[field] = mdToHtml(value);
|
|
34
47
|
}
|
|
35
48
|
continue;
|
|
36
49
|
}
|
|
37
|
-
out[field] =
|
|
50
|
+
out[field] = mdToHtml(value);
|
|
38
51
|
}
|
|
39
52
|
return out;
|
|
40
53
|
}
|
|
@@ -51,12 +64,17 @@ function walk(node) {
|
|
|
51
64
|
const out = {};
|
|
52
65
|
for (const [key, value] of Object.entries(node)) {
|
|
53
66
|
if (READ_RICHTEXT_FIELDS.has(key) && typeof value === 'string' && looksLikeHtml(value)) {
|
|
54
|
-
out[key] =
|
|
67
|
+
out[key] = htmlToMd(value);
|
|
55
68
|
}
|
|
56
69
|
else {
|
|
57
70
|
out[key] = walk(value);
|
|
58
71
|
}
|
|
59
72
|
}
|
|
73
|
+
// 存量 wiki:description 空、md 原文在 markdown_description,回填保正文闭环
|
|
74
|
+
const legacyMd = out.markdown_description;
|
|
75
|
+
if (!out.description && typeof legacyMd === 'string' && legacyMd.trim() !== '') {
|
|
76
|
+
out.description = legacyMd;
|
|
77
|
+
}
|
|
60
78
|
return out;
|
|
61
79
|
}
|
|
62
80
|
return node;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext.js","sourceRoot":"","sources":["../../src/registry/richtext.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"richtext.js","sourceRoot":"","sources":["../../src/registry/richtext.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
|
|
|
2
2
|
import { allTools } from '../tools/index.js';
|
|
3
3
|
import { resolveWrite } from './write-policy.js';
|
|
4
4
|
import { ToolRegistry } from './registry.js';
|
|
5
|
-
import {
|
|
5
|
+
import { DUAL_WRITE_TOOLS, WRITE_RICHTEXT_FIELDS_BY_TOOL, } from './richtext-manifests.generated.js';
|
|
6
6
|
import { isRichtextAutoEnabled, looksLikeHtml, transformWriteArgs, transformReadData, READ_RICHTEXT_FIELDS, } from './richtext.js';
|
|
7
7
|
const RICHTEXT_PARAM_FIELDS = ['description', 'markdown_description'];
|
|
8
8
|
function withAutoOff(fn) {
|
|
@@ -40,13 +40,15 @@ const checks = [
|
|
|
40
40
|
const args = transformWriteArgs('tapd_create_story', { description: html });
|
|
41
41
|
assert.equal(args.description, html);
|
|
42
42
|
}],
|
|
43
|
-
['write: wiki
|
|
43
|
+
['write: wiki dual-write renders html description and keeps md original', () => {
|
|
44
|
+
const md = '# wiki md\n\n- a\n- b';
|
|
44
45
|
const args = transformWriteArgs('tapd_create_wiki', {
|
|
45
46
|
name: 'w',
|
|
46
|
-
description:
|
|
47
|
+
description: md,
|
|
47
48
|
});
|
|
48
|
-
assert.
|
|
49
|
-
assert.
|
|
49
|
+
assert.match(args.description, /<h1>wiki md<\/h1>/);
|
|
50
|
+
assert.match(args.description, /<li>a<\/li>/);
|
|
51
|
+
assert.equal(args.markdown_description, md);
|
|
50
52
|
}],
|
|
51
53
|
['write: wiki html passthrough keeps description', () => {
|
|
52
54
|
const html = '<p>wiki html</p>';
|
|
@@ -61,7 +63,7 @@ const checks = [
|
|
|
61
63
|
markdown_description: '# explicit md',
|
|
62
64
|
});
|
|
63
65
|
assert.equal(args.markdown_description, '# explicit md');
|
|
64
|
-
assert.
|
|
66
|
+
assert.match(args.description, /<h1>md from description<\/h1>/);
|
|
65
67
|
}],
|
|
66
68
|
['write: switch off leaves args untouched', () => {
|
|
67
69
|
const md = '# 原样';
|
|
@@ -103,6 +105,26 @@ const checks = [
|
|
|
103
105
|
assert.equal(result.note, '<p>note 不在富文本清单</p>');
|
|
104
106
|
assert.equal(result.nested.description, '');
|
|
105
107
|
}],
|
|
108
|
+
['read: legacy wiki falls back to markdown_description when description empty', () => {
|
|
109
|
+
const data = {
|
|
110
|
+
id: '1',
|
|
111
|
+
title: 'legacy',
|
|
112
|
+
description: '',
|
|
113
|
+
markdown_description: '# 存量 md\n\n**加粗**',
|
|
114
|
+
};
|
|
115
|
+
const result = transformReadData(data);
|
|
116
|
+
assert.equal(result.description, '# 存量 md\n\n**加粗**');
|
|
117
|
+
assert.equal(result.markdown_description, '# 存量 md\n\n**加粗**');
|
|
118
|
+
}],
|
|
119
|
+
['read: fallback skips when description already has content', () => {
|
|
120
|
+
const html = '<p>已有正文</p>';
|
|
121
|
+
const data = {
|
|
122
|
+
description: html,
|
|
123
|
+
markdown_description: '**存量 md**',
|
|
124
|
+
};
|
|
125
|
+
const result = transformReadData(data);
|
|
126
|
+
assert.match(result.description, /已有正文/);
|
|
127
|
+
}],
|
|
106
128
|
['read: switch off returns raw html', () => {
|
|
107
129
|
const data = { description: '<p>raw</p>' };
|
|
108
130
|
const result = withAutoOff(() => transformReadData(data));
|
|
@@ -128,6 +150,47 @@ const checks = [
|
|
|
128
150
|
assert.equal(result.ok, true);
|
|
129
151
|
assert.match(captured?.description, /<h1>hi<\/h1>/);
|
|
130
152
|
}],
|
|
153
|
+
['exec: wiki create two-phase writes html then md original', async () => {
|
|
154
|
+
delete process.env.TAPD_RICHTEXT_AUTO;
|
|
155
|
+
const posts = [];
|
|
156
|
+
const registry = new ToolRegistry();
|
|
157
|
+
registry.register([allTools.find(t => t.name === 'tapd_create_wiki')]);
|
|
158
|
+
const result = await registry.exec('tapd_create_wiki', { name: 'zzz-delete-me-d8fix', workspace_id: 39814312, creator: 'x', description: '# 标题\n\n**加粗** 文本\n\n- 项' }, { entry: 'mcp' }, () => ({
|
|
159
|
+
post: (_path, body) => {
|
|
160
|
+
posts.push(body);
|
|
161
|
+
return Promise.resolve({ Wiki: { id: '123' } });
|
|
162
|
+
},
|
|
163
|
+
}));
|
|
164
|
+
assert.equal(result.ok, true);
|
|
165
|
+
assert.equal(posts.length, 2);
|
|
166
|
+
assert.match(posts[0].description, /<h1>标题<\/h1>/);
|
|
167
|
+
assert.match(posts[0].description, /<strong>加粗<\/strong>/);
|
|
168
|
+
assert.equal(posts[0].markdown_description, undefined);
|
|
169
|
+
assert.equal(posts[1].id, '123');
|
|
170
|
+
assert.match(posts[1].description, /<h1>标题<\/h1>/);
|
|
171
|
+
assert.match(posts[1].markdown_description, /\*\*加粗\*\*/);
|
|
172
|
+
}],
|
|
173
|
+
['exec: wiki create auto-off sends single raw request', async () => {
|
|
174
|
+
process.env.TAPD_RICHTEXT_AUTO = '0';
|
|
175
|
+
try {
|
|
176
|
+
const posts = [];
|
|
177
|
+
const registry = new ToolRegistry();
|
|
178
|
+
registry.register([allTools.find(t => t.name === 'tapd_create_wiki')]);
|
|
179
|
+
const result = await registry.exec('tapd_create_wiki', { name: 'zzz-delete-me-d8fix', workspace_id: 39814312, creator: 'x', description: '# 原样' }, { entry: 'cli' }, () => ({
|
|
180
|
+
post: (_path, body) => {
|
|
181
|
+
posts.push(body);
|
|
182
|
+
return Promise.resolve({ Wiki: { id: '123' } });
|
|
183
|
+
},
|
|
184
|
+
}));
|
|
185
|
+
assert.equal(result.ok, true);
|
|
186
|
+
assert.equal(posts.length, 1);
|
|
187
|
+
assert.equal(posts[0].description, '# 原样');
|
|
188
|
+
assert.equal(posts[0].markdown_description, undefined);
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
delete process.env.TAPD_RICHTEXT_AUTO;
|
|
192
|
+
}
|
|
193
|
+
}],
|
|
131
194
|
['exec: read tool returns markdown description', async () => {
|
|
132
195
|
delete process.env.TAPD_RICHTEXT_AUTO;
|
|
133
196
|
const registry = new ToolRegistry();
|
|
@@ -179,7 +242,7 @@ const checks = [
|
|
|
179
242
|
}
|
|
180
243
|
assert.deepEqual(WRITE_RICHTEXT_FIELDS_BY_TOOL, scanned);
|
|
181
244
|
assert.equal(Object.keys(scanned).length >= 25, true);
|
|
182
|
-
for (const name of
|
|
245
|
+
for (const name of DUAL_WRITE_TOOLS) {
|
|
183
246
|
assert.ok(scanned[name]?.includes('description'), name);
|
|
184
247
|
assert.ok(scanned[name]?.includes('markdown_description'), name);
|
|
185
248
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"richtext.test.js","sourceRoot":"","sources":["../../src/registry/richtext.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"richtext.test.js","sourceRoot":"","sources":["../../src/registry/richtext.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HtmlNodeLike } from './mention.js';
|
|
2
|
+
/** TAPD 前端附件组件的 file-type 图标分类。 */
|
|
3
|
+
export type FileType = 'text' | 'image' | 'pdf' | 'other';
|
|
4
|
+
/** 扩展名 → file-type 映射表(键为小写扩展名;导出供 Wave 2 上传工具复用)。 */
|
|
5
|
+
export declare const FILE_TYPE_BY_EXTENSION: Readonly<Record<string, FileType>>;
|
|
6
|
+
/** 由文件名(任意大小写扩展名)映射 file-type;无扩展名或未收录 → other。 */
|
|
7
|
+
export declare function fileTypeFor(filename: string): FileType;
|
|
8
|
+
export declare const ATTACH_SCHEME = "attach:";
|
|
9
|
+
export declare const DEFAULT_ATTACHMENT_SLUG = "story_description_attachment";
|
|
10
|
+
/** 附件引用。size/fileType 可省略:省略 fileType 时按 name 扩展名映射。 */
|
|
11
|
+
export interface AttachmentRef {
|
|
12
|
+
workspaceId: string;
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
size?: number;
|
|
16
|
+
fileType?: FileType;
|
|
17
|
+
}
|
|
18
|
+
export interface AttachmentAnchorHtmlOptions {
|
|
19
|
+
/** href 末段 slug(随实体类型变化的场景可覆盖;默认评论/需求描述通用值)。 */
|
|
20
|
+
slug?: string;
|
|
21
|
+
/** data-can-preview,默认 true(R6 五件套定稿值)。 */
|
|
22
|
+
canPreview?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 生成附件引用 md:`[📎 <文件名>](attach:<ws>/<id>)`。
|
|
26
|
+
* 文件名中的 `[` `]` `\` 按 md 规则转义(parseAttachmentAnchorMd 可逆)。
|
|
27
|
+
*/
|
|
28
|
+
export declare function attachmentAnchorMd(ref: Pick<AttachmentRef, 'workspaceId' | 'id' | 'name'>): string;
|
|
29
|
+
/**
|
|
30
|
+
* 解析单个附件引用 md 片段(非附件链接 / scheme 不符 → null,调用方原样保留)。
|
|
31
|
+
* 返回的 ref 不含 size/fileType(md 形态不承载,html 侧按文件名重新映射)。
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseAttachmentAnchorMd(md: string): AttachmentRef | null;
|
|
34
|
+
/** 生成 R6 定稿最小锚点(data 五件套 + 零 spans)。size 省略时不输出 data-size。 */
|
|
35
|
+
export declare function attachmentAnchorHtml(ref: AttachmentRef, options?: AttachmentAnchorHtmlOptions): string;
|
|
36
|
+
/**
|
|
37
|
+
* 解析单个锚点标签串。识别条件(缺一即 null,调用方原样保留该锚点):
|
|
38
|
+
* data-is-tapd-attachment="true" + data-name + href 形如
|
|
39
|
+
* `/<ws>/attachments/preview_attachments/<id>/<slug>`。兼容完整编辑器模板(含 inner spans / type / class)。
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseAttachmentAnchorHtml(anchorHtml: string): AttachmentRef | null;
|
|
42
|
+
/** 扫描 html 片段中全部可识别的附件锚点。 */
|
|
43
|
+
export declare function findAttachmentAnchors(html: string): AttachmentRef[];
|
|
44
|
+
/**
|
|
45
|
+
* html 片段 → md 语义片段:可识别锚点 → `[📎 name](attach:ws/id)`;
|
|
46
|
+
* 不认识的锚点与其余内容原样透传(交给基础转换器 turndown 处理)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function attachmentHtmlToMd(html: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* md 片段 → html 语义片段:附件引用 → R6 锚点;
|
|
51
|
+
* 非 `attach:` scheme 的链接与其余内容原样透传(交给基础转换器 markdown-it 处理)。
|
|
52
|
+
*/
|
|
53
|
+
export declare function attachmentMdToHtml(md: string): string;
|
|
54
|
+
/** turndown 规则 filter 用:节点是否为可识别附件锚点。 */
|
|
55
|
+
export declare function isAttachmentAnchorNode(node: HtmlNodeLike): boolean;
|
|
56
|
+
/** turndown 规则 replacement 用:锚点节点 → 附件引用 md;不满足识别条件返回 null(调用方保留原样)。 */
|
|
57
|
+
export declare function attachmentAnchorNodeToMd(node: HtmlNodeLike): string | null;
|
|
58
|
+
//# sourceMappingURL=attachment-anchor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-anchor.d.ts","sourceRoot":"","sources":["../../src/richtext/attachment-anchor.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,mCAAmC;AACnC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;AAE1D,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAMrE,CAAC;AAEF,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAItD;AAED,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AAEtE,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAiBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,CAAC,GAAG,MAAM,CAKlG;AAOD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAQxE;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,2BAAgC,GAAG,MAAM,CAoB1G;AAoCD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAGlF;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CASnE;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAavD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED,yCAAyC;AACzC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAGlE;AAED,wEAAwE;AACxE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAc1E"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// TAPD 2.0 rc.2 P1/P3(需求 1139814312001001548)—— 附件引用 md 扩展 ↔ data 五件套锚点 HTML
|
|
2
|
+
// 双向语义(纯函数层)。设计依据:FSD §3.1(embed_md/embed_html)、R6 定稿模板;
|
|
3
|
+
// 实证:rc2-painpoints-research.md(评论 367/368/369 严格作用域)+ e2e 金样 poc-rc2-file-embed.mjs。
|
|
4
|
+
//
|
|
5
|
+
// md 扩展语法(BNF):
|
|
6
|
+
// attachment-md ::= "[📎 " link-text "](attach:" ws "/" id ")"
|
|
7
|
+
// link-text ::= ( md-escape | 非 "\" "]" 换行 字符 )*
|
|
8
|
+
// md-escape ::= "\" 任一非换行字符 (仅 \[ \] \\ 被 unescape 语义消费)
|
|
9
|
+
// ws / id ::= 1*( 排除空白、")(" 、"/" 的字符 )(实际为 TAPD 数字 ID)
|
|
10
|
+
//
|
|
11
|
+
// HTML 定稿最小模板(前端重建组件只读 data 五件套,inner spans 全可省——评论 369 实证完美渲染):
|
|
12
|
+
// <a data-is-tapd-attachment="true" data-can-preview="true" data-file-type="text"
|
|
13
|
+
// data-name="<文件名>" data-size="<字节数>" target="_blank" rel="noopener"
|
|
14
|
+
// href="/<ws>/attachments/preview_attachments/<附件ID>/story_description_attachment"><文件名></a>
|
|
15
|
+
//
|
|
16
|
+
// 语义约定:
|
|
17
|
+
// - data-file-type 由文件扩展名映射(fileTypeFor / FILE_TYPE_BY_EXTENSION,导出供 Wave 2 上传工具复用)。
|
|
18
|
+
// - html→md 方向丢 size/slug/type 细节:md 形态是纯引用(by design,round-trip 允许该损)。
|
|
19
|
+
// - 不认识的锚点(缺 data 五件套关键属性、裸 <a href> 等)原样保留,绝不猜测改写。
|
|
20
|
+
// - 与 mention.ts 相同的分层约定:fragment 级函数只做语义 token 替换 + 其余原样透传,
|
|
21
|
+
// Wave 2 在 markdown-it/turndown token 级接线(本文件提供节点级 duck-typing 辅助)。
|
|
22
|
+
import { decodeHtmlEntities, escapeHtmlAttr, escapeHtmlText } from './escape.js';
|
|
23
|
+
/** 扩展名 → file-type 映射表(键为小写扩展名;导出供 Wave 2 上传工具复用)。 */
|
|
24
|
+
export const FILE_TYPE_BY_EXTENSION = {
|
|
25
|
+
txt: 'text',
|
|
26
|
+
png: 'image',
|
|
27
|
+
jpg: 'image',
|
|
28
|
+
jpeg: 'image',
|
|
29
|
+
pdf: 'pdf',
|
|
30
|
+
};
|
|
31
|
+
/** 由文件名(任意大小写扩展名)映射 file-type;无扩展名或未收录 → other。 */
|
|
32
|
+
export function fileTypeFor(filename) {
|
|
33
|
+
const match = /\.([A-Za-z0-9]+)$/.exec(filename.trim());
|
|
34
|
+
if (!match)
|
|
35
|
+
return 'other';
|
|
36
|
+
return FILE_TYPE_BY_EXTENSION[match[1].toLowerCase()] ?? 'other';
|
|
37
|
+
}
|
|
38
|
+
export const ATTACH_SCHEME = 'attach:';
|
|
39
|
+
export const DEFAULT_ATTACHMENT_SLUG = 'story_description_attachment';
|
|
40
|
+
function assertRefToken(value, field) {
|
|
41
|
+
if (!value)
|
|
42
|
+
throw new TypeError(`attachment ${field} must be a non-empty string`);
|
|
43
|
+
if (/[\s()/]/.test(value)) {
|
|
44
|
+
throw new TypeError(`attachment ${field} must not contain whitespace, "/", "(" or ")": ${JSON.stringify(value)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function escapeMdLinkText(name) {
|
|
48
|
+
return name.replace(/[\\\][]/g, (ch) => `\\${ch}`);
|
|
49
|
+
}
|
|
50
|
+
function unescapeMdLinkText(text) {
|
|
51
|
+
return text.replace(/\\([\\\][])/g, '$1');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 生成附件引用 md:`[📎 <文件名>](attach:<ws>/<id>)`。
|
|
55
|
+
* 文件名中的 `[` `]` `\` 按 md 规则转义(parseAttachmentAnchorMd 可逆)。
|
|
56
|
+
*/
|
|
57
|
+
export function attachmentAnchorMd(ref) {
|
|
58
|
+
assertRefToken(ref.workspaceId, 'workspaceId');
|
|
59
|
+
assertRefToken(ref.id, 'id');
|
|
60
|
+
if (!ref.name)
|
|
61
|
+
throw new TypeError('attachment name must be a non-empty string');
|
|
62
|
+
return `[📎 ${escapeMdLinkText(ref.name)}](${ATTACH_SCHEME}${ref.workspaceId}/${ref.id})`;
|
|
63
|
+
}
|
|
64
|
+
// `\\.` 允许任意转义字符;其余字符排除 `\`、`]`、换行(`[` 无需排除但转义统一处理)。
|
|
65
|
+
const ATTACH_MD_PATTERN = '\\[📎 ((?:\\\\.|[^\\\\\\]\\n])*)\\]\\(attach:([^()\\s]+)/([^()\\s]+)\\)';
|
|
66
|
+
const ATTACH_MD_RE = new RegExp(ATTACH_MD_PATTERN, 'g');
|
|
67
|
+
const ATTACH_MD_RE_ONE = new RegExp(ATTACH_MD_PATTERN);
|
|
68
|
+
/**
|
|
69
|
+
* 解析单个附件引用 md 片段(非附件链接 / scheme 不符 → null,调用方原样保留)。
|
|
70
|
+
* 返回的 ref 不含 size/fileType(md 形态不承载,html 侧按文件名重新映射)。
|
|
71
|
+
*/
|
|
72
|
+
export function parseAttachmentAnchorMd(md) {
|
|
73
|
+
const match = ATTACH_MD_RE_ONE.exec(md);
|
|
74
|
+
if (!match)
|
|
75
|
+
return null;
|
|
76
|
+
return {
|
|
77
|
+
workspaceId: match[2],
|
|
78
|
+
id: match[3],
|
|
79
|
+
name: unescapeMdLinkText(match[1]),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** 生成 R6 定稿最小锚点(data 五件套 + 零 spans)。size 省略时不输出 data-size。 */
|
|
83
|
+
export function attachmentAnchorHtml(ref, options = {}) {
|
|
84
|
+
assertRefToken(ref.workspaceId, 'workspaceId');
|
|
85
|
+
assertRefToken(ref.id, 'id');
|
|
86
|
+
if (!ref.name)
|
|
87
|
+
throw new TypeError('attachment name must be a non-empty string');
|
|
88
|
+
const slug = options.slug ?? DEFAULT_ATTACHMENT_SLUG;
|
|
89
|
+
const canPreview = options.canPreview ?? true;
|
|
90
|
+
const fileType = ref.fileType ?? fileTypeFor(ref.name);
|
|
91
|
+
const attrs = [
|
|
92
|
+
'data-is-tapd-attachment="true"',
|
|
93
|
+
`data-can-preview="${canPreview}"`,
|
|
94
|
+
`data-file-type="${fileType}"`,
|
|
95
|
+
`data-name="${escapeHtmlAttr(ref.name)}"`,
|
|
96
|
+
];
|
|
97
|
+
if (ref.size !== undefined)
|
|
98
|
+
attrs.push(`data-size="${ref.size}"`);
|
|
99
|
+
attrs.push('target="_blank"', 'rel="noopener"', `href="/${ref.workspaceId}/attachments/preview_attachments/${ref.id}/${slug}"`);
|
|
100
|
+
return `<a ${attrs.join(' ')}>${escapeHtmlText(ref.name)}</a>`;
|
|
101
|
+
}
|
|
102
|
+
const A_OPEN_RE = /<a\b[^>]*>/gi;
|
|
103
|
+
const FLAG_ATTR_RE = /\bdata-is-tapd-attachment\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
|
|
104
|
+
const NAME_ATTR_RE = /\bdata-name\s*=\s*(?:"([^"]*)"|'([^']*)')/i;
|
|
105
|
+
const SIZE_ATTR_RE = /\bdata-size\s*=\s*(?:"(\d+)"|'(\d+)')/i;
|
|
106
|
+
const FILE_TYPE_ATTR_RE = /\bdata-file-type\s*=\s*(?:"([^"]*)"|'([^']*)')/i;
|
|
107
|
+
const HREF_ATTR_RE = /\bhref\s*=\s*(?:"([^"]*)"|'([^']*)')/i;
|
|
108
|
+
const PREVIEW_HREF_RE = /^\/([^/\s]+)\/attachments\/preview_attachments\/([^/\s]+)\/([^/\s]*)$/i;
|
|
109
|
+
const FILE_TYPES = new Set(['text', 'image', 'pdf', 'other']);
|
|
110
|
+
function attrValue(match) {
|
|
111
|
+
if (!match)
|
|
112
|
+
return null;
|
|
113
|
+
return decodeHtmlEntities(match[1] ?? match[2] ?? match[3] ?? '');
|
|
114
|
+
}
|
|
115
|
+
function refFromOpenTag(openTag) {
|
|
116
|
+
const flag = attrValue(FLAG_ATTR_RE.exec(openTag));
|
|
117
|
+
if (flag?.toLowerCase() !== 'true')
|
|
118
|
+
return null;
|
|
119
|
+
const name = attrValue(NAME_ATTR_RE.exec(openTag));
|
|
120
|
+
const href = attrValue(HREF_ATTR_RE.exec(openTag));
|
|
121
|
+
if (!name || !href)
|
|
122
|
+
return null;
|
|
123
|
+
const hrefMatch = PREVIEW_HREF_RE.exec(href);
|
|
124
|
+
if (!hrefMatch)
|
|
125
|
+
return null;
|
|
126
|
+
const ref = { workspaceId: hrefMatch[1], id: hrefMatch[2], name };
|
|
127
|
+
const size = attrValue(SIZE_ATTR_RE.exec(openTag));
|
|
128
|
+
if (size !== null) {
|
|
129
|
+
const parsed = Number.parseInt(size, 10);
|
|
130
|
+
if (Number.isFinite(parsed))
|
|
131
|
+
ref.size = parsed;
|
|
132
|
+
}
|
|
133
|
+
const fileType = attrValue(FILE_TYPE_ATTR_RE.exec(openTag));
|
|
134
|
+
if (fileType !== null && FILE_TYPES.has(fileType))
|
|
135
|
+
ref.fileType = fileType;
|
|
136
|
+
return ref;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 解析单个锚点标签串。识别条件(缺一即 null,调用方原样保留该锚点):
|
|
140
|
+
* data-is-tapd-attachment="true" + data-name + href 形如
|
|
141
|
+
* `/<ws>/attachments/preview_attachments/<id>/<slug>`。兼容完整编辑器模板(含 inner spans / type / class)。
|
|
142
|
+
*/
|
|
143
|
+
export function parseAttachmentAnchorHtml(anchorHtml) {
|
|
144
|
+
const openMatch = /^<a\b[^>]*>/i.exec(anchorHtml);
|
|
145
|
+
return openMatch ? refFromOpenTag(openMatch[0]) : null;
|
|
146
|
+
}
|
|
147
|
+
/** 扫描 html 片段中全部可识别的附件锚点。 */
|
|
148
|
+
export function findAttachmentAnchors(html) {
|
|
149
|
+
const refs = [];
|
|
150
|
+
A_OPEN_RE.lastIndex = 0;
|
|
151
|
+
let match;
|
|
152
|
+
while ((match = A_OPEN_RE.exec(html)) !== null) {
|
|
153
|
+
const ref = refFromOpenTag(match[0]);
|
|
154
|
+
if (ref)
|
|
155
|
+
refs.push(ref);
|
|
156
|
+
}
|
|
157
|
+
return refs;
|
|
158
|
+
}
|
|
159
|
+
const A_TAG_RE = /<a\b[^>]*>[\s\S]*?<\/a\s*>|<a\b[^>]*\/?>/gi;
|
|
160
|
+
/**
|
|
161
|
+
* html 片段 → md 语义片段:可识别锚点 → `[📎 name](attach:ws/id)`;
|
|
162
|
+
* 不认识的锚点与其余内容原样透传(交给基础转换器 turndown 处理)。
|
|
163
|
+
*/
|
|
164
|
+
export function attachmentHtmlToMd(html) {
|
|
165
|
+
let out = '';
|
|
166
|
+
let pos = 0;
|
|
167
|
+
let match;
|
|
168
|
+
A_TAG_RE.lastIndex = 0;
|
|
169
|
+
while ((match = A_TAG_RE.exec(html)) !== null) {
|
|
170
|
+
const openMatch = /^<a\b[^>]*>/i.exec(match[0]);
|
|
171
|
+
const ref = openMatch ? refFromOpenTag(openMatch[0]) : null;
|
|
172
|
+
out += html.slice(pos, match.index);
|
|
173
|
+
out += ref ? attachmentAnchorMd(ref) : match[0];
|
|
174
|
+
pos = match.index + match[0].length;
|
|
175
|
+
}
|
|
176
|
+
return out + html.slice(pos);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* md 片段 → html 语义片段:附件引用 → R6 锚点;
|
|
180
|
+
* 非 `attach:` scheme 的链接与其余内容原样透传(交给基础转换器 markdown-it 处理)。
|
|
181
|
+
*/
|
|
182
|
+
export function attachmentMdToHtml(md) {
|
|
183
|
+
let out = '';
|
|
184
|
+
let pos = 0;
|
|
185
|
+
let match;
|
|
186
|
+
ATTACH_MD_RE.lastIndex = 0;
|
|
187
|
+
while ((match = ATTACH_MD_RE.exec(md)) !== null) {
|
|
188
|
+
out += md.slice(pos, match.index);
|
|
189
|
+
out += attachmentAnchorHtml({ workspaceId: match[2], id: match[3], name: unescapeMdLinkText(match[1]) });
|
|
190
|
+
pos = match.index + match[0].length;
|
|
191
|
+
}
|
|
192
|
+
return out + md.slice(pos);
|
|
193
|
+
}
|
|
194
|
+
/** turndown 规则 filter 用:节点是否为可识别附件锚点。 */
|
|
195
|
+
export function isAttachmentAnchorNode(node) {
|
|
196
|
+
if (node.nodeName.toUpperCase() !== 'A')
|
|
197
|
+
return false;
|
|
198
|
+
return (node.getAttribute('data-is-tapd-attachment') ?? '').toLowerCase() === 'true';
|
|
199
|
+
}
|
|
200
|
+
/** turndown 规则 replacement 用:锚点节点 → 附件引用 md;不满足识别条件返回 null(调用方保留原样)。 */
|
|
201
|
+
export function attachmentAnchorNodeToMd(node) {
|
|
202
|
+
if (!isAttachmentAnchorNode(node))
|
|
203
|
+
return null;
|
|
204
|
+
const name = node.getAttribute('data-name');
|
|
205
|
+
const href = node.getAttribute('href');
|
|
206
|
+
if (!name || !href)
|
|
207
|
+
return null;
|
|
208
|
+
const hrefMatch = PREVIEW_HREF_RE.exec(decodeHtmlEntities(href));
|
|
209
|
+
if (!hrefMatch)
|
|
210
|
+
return null;
|
|
211
|
+
const ref = { workspaceId: hrefMatch[1], id: hrefMatch[2], name: decodeHtmlEntities(name) };
|
|
212
|
+
const size = node.getAttribute('data-size');
|
|
213
|
+
const parsedSize = size === null ? Number.NaN : Number.parseInt(size, 10);
|
|
214
|
+
if (Number.isFinite(parsedSize))
|
|
215
|
+
ref.size = parsedSize;
|
|
216
|
+
const fileType = node.getAttribute('data-file-type');
|
|
217
|
+
if (fileType !== null && FILE_TYPES.has(fileType))
|
|
218
|
+
ref.fileType = fileType;
|
|
219
|
+
return attachmentAnchorMd(ref);
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=attachment-anchor.js.map
|