@xihe-lab/tapd-core 2.0.0-rc.1 → 2.0.0-rc.3
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 +23 -0
- package/dist/advisor/index.d.ts.map +1 -1
- package/dist/advisor/index.js +2 -0
- package/dist/advisor/index.js.map +1 -1
- package/dist/cache/read-cache.d.ts +136 -0
- package/dist/cache/read-cache.d.ts.map +1 -0
- package/dist/cache/read-cache.js +322 -0
- package/dist/cache/read-cache.js.map +1 -0
- package/dist/cache/read-cache.test.d.ts +2 -0
- package/dist/cache/read-cache.test.d.ts.map +1 -0
- package/dist/cache/read-cache.test.js +429 -0
- package/dist/cache/read-cache.test.js.map +1 -0
- package/dist/errors/index.d.ts +120 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +429 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/registry/registry.d.ts +7 -0
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +9 -3
- package/dist/registry/registry.js.map +1 -1
- package/dist/registry/registry.test.js +293 -2
- package/dist/registry/registry.test.js.map +1 -1
- 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 +79 -2
- package/dist/tapd-client.d.ts.map +1 -1
- package/dist/tapd-client.js +177 -24
- 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 +278 -32
- 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/board.js +22 -22
- package/dist/tools/board.js.map +1 -1
- package/dist/tools/bug.d.ts.map +1 -1
- package/dist/tools/bug.js +262 -259
- package/dist/tools/bug.js.map +1 -1
- package/dist/tools/changes.js +20 -20
- package/dist/tools/changes.js.map +1 -1
- package/dist/tools/comment.d.ts.map +1 -1
- package/dist/tools/comment.js +26 -23
- package/dist/tools/comment.js.map +1 -1
- package/dist/tools/custom-fields.js +16 -16
- package/dist/tools/custom-fields.js.map +1 -1
- package/dist/tools/image.js +2 -2
- package/dist/tools/image.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/iteration.js +50 -50
- package/dist/tools/iteration.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/mini-comment.js +27 -27
- package/dist/tools/mini-comment.js.map +1 -1
- package/dist/tools/mini-item.js +83 -83
- package/dist/tools/mini-item.js.map +1 -1
- package/dist/tools/mini-workspace.js +5 -5
- package/dist/tools/mini-workspace.js.map +1 -1
- package/dist/tools/program.js +7 -7
- package/dist/tools/program.js.map +1 -1
- package/dist/tools/relations.js +14 -14
- package/dist/tools/relations.js.map +1 -1
- package/dist/tools/release.js +53 -53
- package/dist/tools/release.js.map +1 -1
- package/dist/tools/report.js +8 -8
- package/dist/tools/report.js.map +1 -1
- 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/settings.js +77 -77
- package/dist/tools/settings.js.map +1 -1
- package/dist/tools/source.js +14 -14
- package/dist/tools/source.js.map +1 -1
- package/dist/tools/story.d.ts.map +1 -1
- package/dist/tools/story.js +123 -120
- package/dist/tools/story.js.map +1 -1
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +126 -123
- package/dist/tools/task.js.map +1 -1
- package/dist/tools/test.js +117 -117
- package/dist/tools/test.js.map +1 -1
- package/dist/tools/timesheet.js +23 -23
- package/dist/tools/timesheet.js.map +1 -1
- package/dist/tools/user.js +8 -8
- package/dist/tools/user.js.map +1 -1
- package/dist/tools/utility.d.ts +17 -0
- package/dist/tools/utility.d.ts.map +1 -1
- package/dist/tools/utility.js +204 -88
- package/dist/tools/utility.js.map +1 -1
- package/dist/tools/wiki.d.ts.map +1 -1
- package/dist/tools/wiki.js +71 -56
- package/dist/tools/wiki.js.map +1 -1
- package/dist/tools/workflow.js +26 -26
- package/dist/tools/workflow.js.map +1 -1
- package/dist/tools/workspace.js +16 -16
- package/dist/tools/workspace.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -11
- 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
|
@@ -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":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,6BAA6B,GAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;AAEtE,SAAS,WAAW,CAAI,EAAW;IACjC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACxC,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAA2C;IACrD,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACrE,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC;IAEF,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAC9D,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;YAC9C,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;YACnD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC;IAEF,CAAC,yDAAyD,EAAE,GAAG,EAAE;YAC/D,MAAM,IAAI,GAAG,kBAAkB,CAAC,mBAAmB,EAAE;gBACnD,IAAI,EAAE,GAAG;gBACT,WAAW,EAAE,kBAAkB;aAChC,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAqB,EAAE,cAAc,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAqB,EAAE,aAAa,CAAC,CAAC;QAC1D,CAAC,CAAC;IAEF,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG,iCAAiC,CAAC;YAC/C,MAAM,IAAI,GAAG,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC;IAEF,CAAC,uEAAuE,EAAE,GAAG,EAAE;YAC7E,MAAM,EAAE,GAAG,uBAAuB,CAAC;YACnC,MAAM,IAAI,GAAG,kBAAkB,CAAC,kBAAkB,EAAE;gBAClD,IAAI,EAAE,GAAG;gBACT,WAAW,EAAE,EAAE;aAChB,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAqB,EAAE,mBAAmB,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAqB,EAAE,aAAa,CAAC,CAAC;YACxD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC;IAEF,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACtD,MAAM,IAAI,GAAG,kBAAkB,CAAC;YAChC,MAAM,IAAI,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YACpF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC,CAAC;IAEF,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC5E,MAAM,IAAI,GAAG,kBAAkB,CAAC,kBAAkB,EAAE;gBAClD,IAAI,EAAE,GAAG;gBACT,WAAW,EAAE,uBAAuB;gBACpC,oBAAoB,EAAE,eAAe;aACtC,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAqB,EAAE,+BAA+B,CAAC,CAAC;QAC5E,CAAC,CAAC;IAEF,CAAC,yCAAyC,EAAE,GAAG,EAAE;YAC/C,MAAM,EAAE,GAAG,MAAM,CAAC;YAClB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5F,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5F,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC,CAAC;IAEF,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACtD,MAAM,IAAI,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAC3F,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QACvD,CAAC,CAAC;IAEF,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACpE,MAAM,IAAI,GAAG;gBACX,IAAI,EAAE;oBACJ,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,uCAAuC,EAAE;oBACxE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;oBACvD,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC,EAAE;iBAC5E;aACF,CAAC;YACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAgB,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC,CAAC;IAEF,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC1D,MAAM,IAAI,GAAG;gBACX,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,qBAAqB;gBAC3B,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;aAC5B,CAAC;YACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAgB,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;YACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC;IAEF,CAAC,6EAA6E,EAAE,GAAG,EAAE;YACnF,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,GAAG;gBACP,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,EAAE;gBACf,oBAAoB,EAAE,mBAAmB;aAC1C,CAAC;YACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAgB,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;QACjE,CAAC,CAAC;IAEF,CAAC,2DAA2D,EAAE,GAAG,EAAE;YACjE,MAAM,IAAI,GAAG,aAAa,CAAC;YAC3B,MAAM,IAAI,GAAG;gBACX,WAAW,EAAE,IAAI;gBACjB,oBAAoB,EAAE,WAAW;aAClC,CAAC;YACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAA0D,CAAC;YAChG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC;IAEF,CAAC,mCAAmC,EAAE,GAAG,EAAE;YACzC,MAAM,IAAI,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC;IAEF,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAChD,MAAM,IAAI,GAAG,oHAAoH,CAAC;YAClI,MAAM,EAAE,GAAG,iBAAiB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAA4B,CAAC;YAC/E,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QACpD,CAAC,CAAC;IAEF,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAChE,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACtC,IAAI,QAA6C,CAAC;YAClD,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;YACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAE,CAAC,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC,mBAAmB,EACnB,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,EAC3H,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,GAAG,EAAE,CAAC,CAAC;gBACL,IAAI,EAAE,CAAC,KAAa,EAAE,IAA6B,EAAE,EAAE;oBACrD,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBAClD,CAAC;aACF,CAA0B,CAC5B,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAqB,EAAE,cAAc,CAAC,CAAC;QAChE,CAAC,CAAC;IAEF,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACtE,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACtC,MAAM,KAAK,GAA8B,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;YACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAE,CAAC,CAAC,CAAC;YACxE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC,kBAAkB,EAClB,EAAE,IAAI,EAAE,qBAAqB,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,0BAA0B,EAAE,EAC9G,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,GAAG,EAAE,CAAC,CAAC;gBACL,IAAI,EAAE,CAAC,KAAa,EAAE,IAA6B,EAAE,EAAE;oBACrD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACjB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClD,CAAC;aACF,CAA0B,CAC5B,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAqB,EAAE,cAAc,CAAC,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAqB,EAAE,sBAAsB,CAAC,CAAC;YACrE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAqB,EAAE,cAAc,CAAC,CAAC;YAC7D,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAA8B,EAAE,YAAY,CAAC,CAAC;QACtE,CAAC,CAAC;IAEF,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACjE,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,KAAK,GAA8B,EAAE,CAAC;gBAC5C,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;gBACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAE,CAAC,CAAC,CAAC;gBACxE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC,kBAAkB,EAClB,EAAE,IAAI,EAAE,qBAAqB,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,EAC1F,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,GAAG,EAAE,CAAC,CAAC;oBACL,IAAI,EAAE,CAAC,KAAa,EAAE,IAA6B,EAAE,EAAE;wBACrD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACjB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;oBAClD,CAAC;iBACF,CAA0B,CAC5B,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAC3C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;YACzD,CAAC;oBAAS,CAAC;gBACT,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACxC,CAAC;QACH,CAAC,CAAC;IAEF,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACtC,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;YACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAE,CAAC,CAAC,CAAC;YACxE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC,kBAAkB,EAClB,EAAE,YAAY,EAAE,QAAQ,EAAE,EAC1B,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,GAAG,EAAE,CAAC,CAAC;gBACL,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC,EAAE,CAAC;aAC9G,CAA0B,CAC5B,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAA2C,CAAC;YAChE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC3D,CAAC,CAAC;IAEF,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC3D,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;gBACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAE,CAAC,CAAC,CAAC;gBACzE,IAAI,QAA6C,CAAC;gBAClD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC,mBAAmB,EACnB,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,EAC3H,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,GAAG,EAAE,CAAC,CAAC;oBACL,IAAI,EAAE,CAAC,KAAa,EAAE,IAA6B,EAAE,EAAE;wBACrD,QAAQ,GAAG,IAAI,CAAC;wBAChB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;oBAClD,CAAC;iBACF,CAA0B,CAC5B,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YAC9C,CAAC;oBAAS,CAAC;gBACT,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACxC,CAAC;QACH,CAAC,CAAC;IAEF,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACrE,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACtC,MAAM,QAAQ,GAAG,wEAAwE,CAAC;YAC1F,MAAM,OAAO,GAAG,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;YACnF,MAAM,KAAK,GAAG,OAAO,CAAC,WAAqB,CAAC;YAC5C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAA4B,CAAC;YACtF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YAChG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC;IAEF,CAAC,gEAAgE,EAAE,GAAG,EAAE;YACtE,MAAM,OAAO,GAA6B,EAAE,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAClC,MAAM,KAAK,GAAI,IAAI,CAAC,WAAmD,CAAC,KAAK,IAAI,EAAE,CAAC;gBACpF,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;gBAC7D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACrD,CAAC;YACD,MAAM,CAAC,SAAS,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YACtD,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;gBACpC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC;gBACxD,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC,CAAC;YACnE,CAAC;QACH,CAAC,CAAC;IAEF,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACpE,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC;CACH,CAAC;AAEF,IAAI,MAAM,GAAG,CAAC,CAAC;AACf,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IACrD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-anchor.js","sourceRoot":"","sources":["../../src/richtext/attachment-anchor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-anchor.test.d.ts","sourceRoot":"","sources":["../../src/richtext/attachment-anchor.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// attachment-anchor 语义单测:fileTypeFor 映射 / md 扩展语法 / R6 五件套模板 / 解析容错 / 不认识锚点原样保留。
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { ATTACH_SCHEME, DEFAULT_ATTACHMENT_SLUG, FILE_TYPE_BY_EXTENSION, attachmentAnchorHtml, attachmentAnchorMd, attachmentHtmlToMd, attachmentMdToHtml, fileTypeFor, findAttachmentAnchors, isAttachmentAnchorNode, attachmentAnchorNodeToMd, parseAttachmentAnchorHtml, parseAttachmentAnchorMd, } from './attachment-anchor.js';
|
|
4
|
+
const WS = '39814312';
|
|
5
|
+
const ID = '1139814312001000001';
|
|
6
|
+
// 完整编辑器模板(含 inner spans / type / class,e2e 金样 poc-rc2-file-embed.mjs 同构)
|
|
7
|
+
const EDITOR_STYLE_ANCHOR = `<a data-is-tapd-attachment="true" contenteditable="false" target="_blank" rel="noopener" ` +
|
|
8
|
+
`data-can-preview="true" data-file-type="text" type="text" data-name="comment-embed.txt" data-size="54" ` +
|
|
9
|
+
`href="/${WS}/attachments/preview_attachments/1139814312001000004/story_description_attachment" ` +
|
|
10
|
+
`class="tapd-editor__attachment-item"><span class="tapd-editor__attachment-item__left">` +
|
|
11
|
+
`<span class="tapd-editor__attachment-item__text-wrapper">` +
|
|
12
|
+
`<span class="tapd-editor__attachment-item__title">comment-embed.txt</span>` +
|
|
13
|
+
`<span class="tapd-editor__attachment-item__size">0.00MB</span></span></span></a>`;
|
|
14
|
+
const checks = [
|
|
15
|
+
['fileTypeFor: txt→text、png/jpg/jpeg→image、pdf→pdf、其他→other(大小写不敏感)', () => {
|
|
16
|
+
assert.equal(fileTypeFor('说明.txt'), 'text');
|
|
17
|
+
assert.equal(fileTypeFor('pic.PNG'), 'image');
|
|
18
|
+
assert.equal(fileTypeFor('a.jpg'), 'image');
|
|
19
|
+
assert.equal(fileTypeFor('a.jpeg'), 'image');
|
|
20
|
+
assert.equal(fileTypeFor('doc.pdf'), 'pdf');
|
|
21
|
+
assert.equal(fileTypeFor('app.log'), 'other');
|
|
22
|
+
assert.equal(fileTypeFor('noext'), 'other');
|
|
23
|
+
assert.equal(fileTypeFor('报表@v2.pdf'), 'pdf');
|
|
24
|
+
}],
|
|
25
|
+
['FILE_TYPE_BY_EXTENSION: 映射表导出供 Wave 2 复用', () => {
|
|
26
|
+
assert.equal(FILE_TYPE_BY_EXTENSION.txt, 'text');
|
|
27
|
+
assert.equal(FILE_TYPE_BY_EXTENSION.png, 'image');
|
|
28
|
+
assert.equal(FILE_TYPE_BY_EXTENSION.pdf, 'pdf');
|
|
29
|
+
assert.equal(ATTACH_SCHEME, 'attach:');
|
|
30
|
+
assert.equal(DEFAULT_ATTACHMENT_SLUG, 'story_description_attachment');
|
|
31
|
+
}],
|
|
32
|
+
['attachmentAnchorMd: md 扩展语法生成', () => {
|
|
33
|
+
assert.equal(attachmentAnchorMd({ workspaceId: WS, id: ID, name: '需求说明.txt' }), `[📎 需求说明.txt](attach:${WS}/${ID})`);
|
|
34
|
+
}],
|
|
35
|
+
['attachmentAnchorMd: 文件名中 []\\ 转义可逆;非法 ws/id 抛错', () => {
|
|
36
|
+
const md = attachmentAnchorMd({ workspaceId: WS, id: ID, name: 'a]b[ c\\d.txt' });
|
|
37
|
+
assert.equal(md, `[📎 a\\]b\\[ c\\\\d.txt](attach:${WS}/${ID})`);
|
|
38
|
+
const parsed = parseAttachmentAnchorMd(md);
|
|
39
|
+
assert.equal(parsed?.name, 'a]b[ c\\d.txt');
|
|
40
|
+
assert.throws(() => attachmentAnchorMd({ workspaceId: 'ws x', id: ID, name: 'f' }), TypeError);
|
|
41
|
+
assert.throws(() => attachmentAnchorMd({ workspaceId: WS, id: '', name: 'f' }), TypeError);
|
|
42
|
+
}],
|
|
43
|
+
['parseAttachmentAnchorMd: 非 attach: 链接与普通链接 → null', () => {
|
|
44
|
+
assert.equal(parseAttachmentAnchorMd('[标题](https://www.tapd.cn/x)'), null);
|
|
45
|
+
assert.equal(parseAttachmentAnchorMd('[📎 x](https://a/b)'), null);
|
|
46
|
+
assert.equal(parseAttachmentAnchorMd('plain text'), null);
|
|
47
|
+
}],
|
|
48
|
+
['parseAttachmentAnchorMd: 完整解析 ws/id/name', () => {
|
|
49
|
+
const ref = parseAttachmentAnchorMd(`前缀 [📎 需求说明.txt](attach:${WS}/${ID}) 后缀`);
|
|
50
|
+
assert.deepEqual(ref, { workspaceId: WS, id: ID, name: '需求说明.txt' });
|
|
51
|
+
}],
|
|
52
|
+
['attachmentAnchorHtml: R6 定稿最小模板逐字段(含 size)', () => {
|
|
53
|
+
assert.equal(attachmentAnchorHtml({ workspaceId: WS, id: ID, name: '接口设计.pdf', size: 2048 }), `<a data-is-tapd-attachment="true" data-can-preview="true" data-file-type="pdf" ` +
|
|
54
|
+
`data-name="接口设计.pdf" data-size="2048" target="_blank" rel="noopener" ` +
|
|
55
|
+
`href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment">接口设计.pdf</a>`);
|
|
56
|
+
}],
|
|
57
|
+
['attachmentAnchorHtml: size 省略不输出 data-size;fileType 按扩展名默认映射;slug 可覆盖', () => {
|
|
58
|
+
const html = attachmentAnchorHtml({ workspaceId: WS, id: ID, name: 'app.log' });
|
|
59
|
+
assert.ok(html.includes('data-file-type="other"'));
|
|
60
|
+
assert.ok(!html.includes('data-size'));
|
|
61
|
+
assert.ok(html.includes(`href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment"`));
|
|
62
|
+
const custom = attachmentAnchorHtml({ workspaceId: WS, id: ID, name: 'a.txt', fileType: 'text' }, { slug: 'bug_description_attachment' });
|
|
63
|
+
assert.ok(custom.includes('/bug_description_attachment">'));
|
|
64
|
+
assert.ok(custom.endsWith('>a.txt</a>'));
|
|
65
|
+
}],
|
|
66
|
+
['attachmentAnchorHtml: 文件名 HTML 特殊字符转义', () => {
|
|
67
|
+
const html = attachmentAnchorHtml({ workspaceId: WS, id: ID, name: 'a"b&c.txt' });
|
|
68
|
+
assert.ok(html.includes('data-name="a"b&c.txt"'));
|
|
69
|
+
assert.ok(html.endsWith('>a"b&c.txt</a>') === false);
|
|
70
|
+
assert.ok(html.endsWith('>a"b&c.txt</a>'));
|
|
71
|
+
}],
|
|
72
|
+
['parseAttachmentAnchorHtml: 生成结果可逆解析', () => {
|
|
73
|
+
const html = attachmentAnchorHtml({ workspaceId: WS, id: ID, name: '接口设计.pdf', size: 2048 });
|
|
74
|
+
assert.deepEqual(parseAttachmentAnchorHtml(html), {
|
|
75
|
+
workspaceId: WS, id: ID, name: '接口设计.pdf', size: 2048, fileType: 'pdf',
|
|
76
|
+
});
|
|
77
|
+
}],
|
|
78
|
+
['parseAttachmentAnchorHtml: 完整编辑器模板(inner spans/type/class)可识别', () => {
|
|
79
|
+
assert.deepEqual(parseAttachmentAnchorHtml(EDITOR_STYLE_ANCHOR), {
|
|
80
|
+
workspaceId: WS, id: '1139814312001000004', name: 'comment-embed.txt', size: 54, fileType: 'text',
|
|
81
|
+
});
|
|
82
|
+
assert.deepEqual(findAttachmentAnchors(`<p>前</p>${EDITOR_STYLE_ANCHOR}<p>后</p>`).length, 1);
|
|
83
|
+
}],
|
|
84
|
+
['parseAttachmentAnchorHtml: 不认识的锚点 → null(裸 <a>/缺 data-name/缺 flag)', () => {
|
|
85
|
+
assert.equal(parseAttachmentAnchorHtml(`<a href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment">x.txt</a>`), null);
|
|
86
|
+
assert.equal(parseAttachmentAnchorHtml(`<a data-is-tapd-attachment="true" href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment">残缺</a>`), null);
|
|
87
|
+
assert.equal(parseAttachmentAnchorHtml(`<a data-can-preview="true" data-name="x.txt" href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment">无flag</a>`), null);
|
|
88
|
+
assert.equal(parseAttachmentAnchorHtml(`<a data-is-tapd-attachment="true" data-name="x.txt" href="https://elsewhere/x">外部链接</a>`), null);
|
|
89
|
+
}],
|
|
90
|
+
['attachmentHtmlToMd: 锚点 → md 扩展语法;不认识锚点原样保留', () => {
|
|
91
|
+
const md = attachmentHtmlToMd(`<p>材料</p>${EDITOR_STYLE_ANCHOR}`);
|
|
92
|
+
assert.equal(md, `<p>材料</p>[📎 comment-embed.txt](attach:${WS}/1139814312001000004)`);
|
|
93
|
+
const bare = `<a href="/${WS}/attachments/preview_attachments/${ID}/story_description_attachment">残缺</a>`;
|
|
94
|
+
assert.equal(attachmentHtmlToMd(`<p>x</p>${bare}`), `<p>x</p>${bare}`);
|
|
95
|
+
const plain = '<p>普通 <a href="https://e.com">链接</a></p>';
|
|
96
|
+
assert.equal(attachmentHtmlToMd(plain), plain);
|
|
97
|
+
}],
|
|
98
|
+
['attachmentMdToHtml: md → 锚点;非 attach 链接透传', () => {
|
|
99
|
+
const html = attachmentMdToHtml(`见 [📎 需求说明.txt](attach:${WS}/${ID})`);
|
|
100
|
+
assert.ok(html.startsWith('见 <a data-is-tapd-attachment="true"'));
|
|
101
|
+
assert.ok(html.includes('data-name="需求说明.txt"'));
|
|
102
|
+
assert.ok(html.endsWith(`>需求说明.txt</a>`));
|
|
103
|
+
const link = '参考 [标题](https://e.com/a)';
|
|
104
|
+
assert.equal(attachmentMdToHtml(link), link);
|
|
105
|
+
}],
|
|
106
|
+
['attachmentMdToHtml: 多锚点与转义名可逆', () => {
|
|
107
|
+
const md = `[📎 a.txt](attach:${WS}/1139814312001000002) 中间 [📎 b.pdf](attach:${WS}/${ID})`;
|
|
108
|
+
const html = attachmentMdToHtml(md);
|
|
109
|
+
assert.equal(findAttachmentAnchors(html).length, 2);
|
|
110
|
+
assert.equal(attachmentHtmlToMd(html), md);
|
|
111
|
+
}],
|
|
112
|
+
['节点辅助: isAttachmentAnchorNode / attachmentAnchorNodeToMd', () => {
|
|
113
|
+
const node = {
|
|
114
|
+
nodeName: 'A',
|
|
115
|
+
getAttribute: (name) => ({
|
|
116
|
+
'data-is-tapd-attachment': 'true',
|
|
117
|
+
'data-name': 'comment-embed.txt',
|
|
118
|
+
'data-size': '54',
|
|
119
|
+
'data-file-type': 'text',
|
|
120
|
+
href: `/${WS}/attachments/preview_attachments/1139814312001000004/story_description_attachment`,
|
|
121
|
+
})[name] ?? null,
|
|
122
|
+
};
|
|
123
|
+
assert.equal(isAttachmentAnchorNode(node), true);
|
|
124
|
+
assert.equal(attachmentAnchorNodeToMd(node), `[📎 comment-embed.txt](attach:${WS}/1139814312001000004)`);
|
|
125
|
+
const bare = { nodeName: 'A', getAttribute: () => null };
|
|
126
|
+
assert.equal(isAttachmentAnchorNode(bare), false);
|
|
127
|
+
assert.equal(attachmentAnchorNodeToMd(bare), null);
|
|
128
|
+
}],
|
|
129
|
+
];
|
|
130
|
+
let failed = 0;
|
|
131
|
+
for (const [name, check] of checks) {
|
|
132
|
+
try {
|
|
133
|
+
check();
|
|
134
|
+
console.log(`PASS ${name}`);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
failed += 1;
|
|
138
|
+
console.error(`FAIL ${name}`);
|
|
139
|
+
console.error(` ${error instanceof Error ? error.message : String(error)}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (failed > 0) {
|
|
143
|
+
console.error(`\n${failed}/${checks.length} failed`);
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.log(`\n${checks.length}/${checks.length} passed`);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=attachment-anchor.test.js.map
|