@jagadeesh52423/atlassian-mcp-server 1.3.1 → 1.4.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/README.md +3 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/formatters/annotations.d.ts +82 -0
- package/dist/formatters/annotations.d.ts.map +1 -0
- package/dist/formatters/annotations.js +441 -0
- package/dist/formatters/annotations.js.map +1 -0
- package/dist/formatters/index.d.ts +3 -0
- package/dist/formatters/index.d.ts.map +1 -1
- package/dist/formatters/index.js +2 -0
- package/dist/formatters/index.js.map +1 -1
- package/dist/formatters/markdown-to-adf.d.ts.map +1 -1
- package/dist/formatters/markdown-to-adf.js +79 -1
- package/dist/formatters/markdown-to-adf.js.map +1 -1
- package/dist/formatters/wiki-guard.d.ts +18 -0
- package/dist/formatters/wiki-guard.d.ts.map +1 -0
- package/dist/formatters/wiki-guard.js +66 -0
- package/dist/formatters/wiki-guard.js.map +1 -0
- package/dist/handlers/bitbucket-handlers.d.ts +2 -0
- package/dist/handlers/bitbucket-handlers.d.ts.map +1 -1
- package/dist/handlers/bitbucket-handlers.js +8 -6
- package/dist/handlers/bitbucket-handlers.js.map +1 -1
- package/dist/handlers/confluence-handlers.d.ts +4 -0
- package/dist/handlers/confluence-handlers.d.ts.map +1 -1
- package/dist/handlers/confluence-handlers.js +42 -1
- package/dist/handlers/confluence-handlers.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/services/bitbucket.d.ts +2 -1
- package/dist/services/bitbucket.d.ts.map +1 -1
- package/dist/services/bitbucket.js +13 -1
- package/dist/services/bitbucket.js.map +1 -1
- package/dist/services/confluence.d.ts +50 -2
- package/dist/services/confluence.d.ts.map +1 -1
- package/dist/services/confluence.js +190 -4
- package/dist/services/confluence.js.map +1 -1
- package/dist/tools/bitbucket-tools.d.ts.map +1 -1
- package/dist/tools/bitbucket-tools.js +9 -1
- package/dist/tools/bitbucket-tools.js.map +1 -1
- package/dist/tools/confluence-tools.d.ts.map +1 -1
- package/dist/tools/confluence-tools.js +27 -2
- package/dist/tools/confluence-tools.js.map +1 -1
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -179,7 +179,8 @@ Add one of the following to your Claude Desktop config:
|
|
|
179
179
|
| `confluence_search_pages` | Search pages via CQL text query |
|
|
180
180
|
| `confluence_get_page` | Get a page by ID (returns ADF JSON body) |
|
|
181
181
|
| `confluence_create_page` | Create a page (accepts Markdown) |
|
|
182
|
-
| `confluence_update_page` | Update a page (accepts Markdown) |
|
|
182
|
+
| `confluence_update_page` | Update a page (accepts Markdown). Re-anchors inline comments automatically; reports any it could not |
|
|
183
|
+
| `confluence_reattach_inline_comments` | Repair inline comments detached by an earlier update, using page history. `dryRun` defaults to `true` |
|
|
183
184
|
| `confluence_delete_page` | Delete a page |
|
|
184
185
|
| `confluence_get_spaces` | List all spaces |
|
|
185
186
|
| `confluence_get_pages_by_space` | Get pages in a space |
|
|
@@ -252,6 +253,7 @@ Confluence pages and comments use **ADF (Atlassian Document Format)** natively:
|
|
|
252
253
|
- **Input** -- `create_page`, `update_page`, `add_comment`, `update_comment` accept **Markdown**, which the server converts to ADF using the official `@atlaskit/editor-markdown-transformer`.
|
|
253
254
|
- **Output** -- `get_page`, `get_comments` return ADF JSON (an object, not a string).
|
|
254
255
|
- **Comments** -- `get_comments` returns **both footer (page-level) and inline (text-anchored) comments** by default. Use the `commentType` param (`footer` | `inline` | `all`, default `all`) to filter. Every comment carries a `type` field (`"footer"` or `"inline"`). Inline comments additionally include `anchoredText` (the highlighted page text the comment is attached to), `resolutionStatus` (e.g. `"open"`, `"resolved"`), `markerRef`, and `webuiLink`. _Backwards-compatibility note: callers that previously relied on `get_comments` returning footer comments only will now also receive inline comments under the default `all`; pass `commentType: "footer"` to restore the old footer-only behaviour. The new `type` field is additive and does not remove any existing field._
|
|
256
|
+
- **Inline comment anchors** -- An inline comment is not a separate resource: it anchors to page text via an `annotation` mark **inside the page body**. Any update that rebuilds the body therefore detaches every inline comment on the page. `update_page` guards against this by reading the live body first and re-anchoring each marker onto text that survived the edit, then reporting `inlineComments: { preserved, dropped, ambiguous }`. A comment whose text you reworded or deleted appears in `dropped`; one whose text now occurs in more than one place appears in `ambiguous`, because the server refuses to pick an occurrence — a wrong guess silently moves a reviewer's question onto unrelated text while reporting success. Either way the comment stays on the page but unattached, which is exactly what Confluence does today. **Prefer leaving commented sentences intact.** To repair comments detached by an earlier update (including ones made before this feature existed), use `confluence_reattach_inline_comments`: it walks page history to find where each orphan was anchored, re-marks only unambiguous matches, and reports the rest rather than guessing. It never alters page text, and searches back at most 50 versions. Anchors are keyed by surrounding content (table header + first-column value, or block type + text) rather than by position, so they survive rows and paragraphs being inserted above them — which is what lets a comment on a repeated field name like `unique_id` resolve even though that text appears ten times on the page. Note that `anchoredText` from `get_comments` is truncated by Confluence at ~250 characters (252 observed); the history lookup recovers the full anchor.
|
|
255
257
|
- **Inline images** -- Not currently supported via ADF media nodes (requires Atlassian Media API tokens). Use `confluence_add_attachment` instead.
|
|
256
258
|
|
|
257
259
|
## Project Structure
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAGX,eAAO,MAAM,QAAQ;;;;;;;;CAQX,CAAC;AAGX,eAAO,MAAM,aAAa;;;;;;;;;;;;CAiBhB,CAAC;AAGX,eAAO,MAAM,WAAW;;;CAGd,CAAC;AAGX,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAGX,eAAO,MAAM,cAAc;;oCAEF,MAAM;kCACR,MAAM;CACnB,CAAC;AAGX,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAGX,eAAO,MAAM,QAAQ;;;;;;;;CAQX,CAAC;AAGX,eAAO,MAAM,aAAa;;;;;;;;;;;;CAiBhB,CAAC;AAGX,eAAO,MAAM,WAAW;;;CAGd,CAAC;AAGX,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAGX,eAAO,MAAM,cAAc;;oCAEF,MAAM;kCACR,MAAM;CACnB,CAAC;AAGX,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;CAeR,CAAC"}
|
package/dist/constants.js
CHANGED
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,wBAAwB,EAAE,EAAE;IAC5B,kBAAkB,EAAE,EAAE;IACtB,uBAAuB,EAAE,EAAE;IAC3B,iBAAiB,EAAE,EAAE;CACb,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,MAAM;IACnB,eAAe,EAAE,MAAM;IACvB,gBAAgB,EAAE,MAAM;IACxB,oBAAoB,EAAE,KAAK;IAC3B,wBAAwB,EAAE,OAAO;IACjC,kBAAkB,EAAE,MAAM;IAC1B,qBAAqB,EAAE,MAAM;CACrB,CAAC;AAEX,gBAAgB;AAChB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,aAAa;IACb,kBAAkB,EAAE,wBAAwB;IAC5C,yBAAyB,EAAE,+BAA+B;IAC1D,gBAAgB,EAAE,sBAAsB;IAExC,OAAO;IACP,WAAW,EAAE,wBAAwB;IACrC,UAAU,EAAE,mBAAmB;IAC/B,YAAY,EAAE,qBAAqB;IACnC,gBAAgB,EAAE,yBAAyB;IAC3C,eAAe,EAAE,uBAAuB;IACxC,oBAAoB,EAAE,2BAA2B;IACjD,eAAe,EAAE,wBAAwB;IAEzC,YAAY;IACZ,kBAAkB,EAAE,+BAA+B;CAC3C,CAAC;AAEX,sBAAsB;AACtB,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa,EAAE,qDAAqD;IACpE,YAAY,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;CAC5E,CAAC;AAEX,4BAA4B;AAC5B,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,kBAAkB,EAAE,iDAAiD;IACrE,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;IAC3D,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,iBAAiB,IAAI,EAAE;CAC/C,CAAC;AAEX,wCAAwC;AACxC,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,GAAG;IACV,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,IAAI;IACjB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,KAAK;IACb,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;CACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,sBAAsB;AACtB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,wBAAwB,EAAE,EAAE;IAC5B,kBAAkB,EAAE,EAAE;IACtB,uBAAuB,EAAE,EAAE;IAC3B,iBAAiB,EAAE,EAAE;CACb,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,MAAM;IACnB,eAAe,EAAE,MAAM;IACvB,gBAAgB,EAAE,MAAM;IACxB,oBAAoB,EAAE,KAAK;IAC3B,wBAAwB,EAAE,OAAO;IACjC,kBAAkB,EAAE,MAAM;IAC1B,qBAAqB,EAAE,MAAM;CACrB,CAAC;AAEX,gBAAgB;AAChB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,aAAa;IACb,kBAAkB,EAAE,wBAAwB;IAC5C,yBAAyB,EAAE,+BAA+B;IAC1D,gBAAgB,EAAE,sBAAsB;IAExC,OAAO;IACP,WAAW,EAAE,wBAAwB;IACrC,UAAU,EAAE,mBAAmB;IAC/B,YAAY,EAAE,qBAAqB;IACnC,gBAAgB,EAAE,yBAAyB;IAC3C,eAAe,EAAE,uBAAuB;IACxC,oBAAoB,EAAE,2BAA2B;IACjD,eAAe,EAAE,wBAAwB;IAEzC,YAAY;IACZ,kBAAkB,EAAE,+BAA+B;CAC3C,CAAC;AAEX,sBAAsB;AACtB,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa,EAAE,qDAAqD;IACpE,YAAY,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;CAC5E,CAAC;AAEX,4BAA4B;AAC5B,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;CACd,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,kBAAkB,EAAE,iDAAiD;IACrE,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;IAC3D,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,iBAAiB,IAAI,EAAE;CAC/C,CAAC;AAEX,wCAAwC;AACxC,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,IAAI;IACjB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,KAAK;IACb,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;CACN,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserves Confluence inline comments across a page update.
|
|
3
|
+
*
|
|
4
|
+
* An inline comment is not a separate resource — it is an `annotation` mark
|
|
5
|
+
* (`annotationType: "inlineComment"`, `id` = the comment's marker ref) carried
|
|
6
|
+
* by the text nodes it covers. Markdown cannot express those marks, so writing
|
|
7
|
+
* a body built from markdown deletes every marker and detaches every inline
|
|
8
|
+
* comment on the page.
|
|
9
|
+
*
|
|
10
|
+
* The fix is to read the marks off the live body first and re-anchor them onto
|
|
11
|
+
* the new document by matching the annotated text.
|
|
12
|
+
*/
|
|
13
|
+
export interface Annotation {
|
|
14
|
+
id: string;
|
|
15
|
+
annotationType: string;
|
|
16
|
+
/** The text the comment was anchored to, concatenated in document order. */
|
|
17
|
+
text: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Collect every inline-comment annotation in `doc`, in document order.
|
|
21
|
+
* Text spanning several nodes (a comment covering bold text, say) is
|
|
22
|
+
* concatenated under one id.
|
|
23
|
+
*/
|
|
24
|
+
export declare function collectAnnotations(doc: any): Annotation[];
|
|
25
|
+
/**
|
|
26
|
+
* Re-apply `annotations` to `doc`, matching on the annotated text.
|
|
27
|
+
*
|
|
28
|
+
* An anchor whose text occurs more than once is reported in `ambiguous` and
|
|
29
|
+
* left unmarked. Picking an occurrence would move a reviewer's comment onto
|
|
30
|
+
* unrelated text while reporting success; leaving it unmarked reproduces
|
|
31
|
+
* exactly what Confluence does today, so it costs nothing and stays visible.
|
|
32
|
+
*
|
|
33
|
+
* ponytail: exact substring within a single text node. A comment whose text was
|
|
34
|
+
* reworded, or whose span is broken up by other marks (`**bold** inside the
|
|
35
|
+
* selection`), lands in `dropped`. Upgrade path if that bites: match across
|
|
36
|
+
* adjacent text nodes, then fuzzy/longest-common-substring.
|
|
37
|
+
*/
|
|
38
|
+
export declare function reapplyAnnotations(doc: any, annotations: Annotation[]): {
|
|
39
|
+
doc: any;
|
|
40
|
+
preserved: Annotation[];
|
|
41
|
+
dropped: Annotation[];
|
|
42
|
+
ambiguous: Annotation[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Where an annotation sat in an earlier version of a page, described by
|
|
46
|
+
* surrounding content rather than by index so it survives edits above it.
|
|
47
|
+
*/
|
|
48
|
+
export type Locator = {
|
|
49
|
+
kind: 'tableCell';
|
|
50
|
+
header: string[];
|
|
51
|
+
rowKey: string;
|
|
52
|
+
cell: number;
|
|
53
|
+
text: string;
|
|
54
|
+
annotationType: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'block';
|
|
57
|
+
blockType: string;
|
|
58
|
+
blockText: string;
|
|
59
|
+
text: string;
|
|
60
|
+
annotationType: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Describe where `markerRef` is anchored in `doc`. Returns null if absent.
|
|
64
|
+
*
|
|
65
|
+
* Tables are keyed by header row + the row's first-column value, so a comment
|
|
66
|
+
* on a field-reference row still resolves after rows are added or reordered
|
|
67
|
+
* above it — an index would not survive that.
|
|
68
|
+
*/
|
|
69
|
+
export declare function locateAnnotation(doc: any, markerRef: string): Locator | null;
|
|
70
|
+
/**
|
|
71
|
+
* Re-attach `markerRef` to `doc` at the position `locator` describes.
|
|
72
|
+
*
|
|
73
|
+
* 'ambiguous' means several equally-good hosts matched; the caller must decide,
|
|
74
|
+
* because guessing silently moves a reviewer's comment onto unrelated text.
|
|
75
|
+
* That is not hypothetical — anchor text "unique_id" occurs in ten text nodes
|
|
76
|
+
* of a real page whose true anchor was one specific table cell.
|
|
77
|
+
*/
|
|
78
|
+
export declare function applyLocator(doc: any, locator: Locator, markerRef: string): {
|
|
79
|
+
doc: any;
|
|
80
|
+
status: 'exact' | 'ambiguous' | 'lost' | 'unmatchable';
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=annotations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/formatters/annotations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;CACd;AAwBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,EAAE,CAqBzD;AAgCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,UAAU,EAAE,GACxB;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,SAAS,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,UAAU,EAAE,CAAA;CAAE,CAwBvF;AAID;;;GAGG;AACH,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC3G;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAyBlG;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAmB5E;AA6BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,aAAa,CAAA;CAAE,CAkBtE"}
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserves Confluence inline comments across a page update.
|
|
3
|
+
*
|
|
4
|
+
* An inline comment is not a separate resource — it is an `annotation` mark
|
|
5
|
+
* (`annotationType: "inlineComment"`, `id` = the comment's marker ref) carried
|
|
6
|
+
* by the text nodes it covers. Markdown cannot express those marks, so writing
|
|
7
|
+
* a body built from markdown deletes every marker and detaches every inline
|
|
8
|
+
* comment on the page.
|
|
9
|
+
*
|
|
10
|
+
* The fix is to read the marks off the live body first and re-anchor them onto
|
|
11
|
+
* the new document by matching the annotated text.
|
|
12
|
+
*/
|
|
13
|
+
import { pathToFileURL } from 'node:url';
|
|
14
|
+
const isAnnotation = (m) => m?.type === 'annotation' && m?.attrs?.id;
|
|
15
|
+
/**
|
|
16
|
+
* Only this id blocks re-marking — Confluence allows several comments on the
|
|
17
|
+
* same phrase, so an unrelated annotation must not hide the text from another.
|
|
18
|
+
*/
|
|
19
|
+
const hasAnnotationId = (n, id) => (n?.marks ?? []).some((m) => isAnnotation(m) && m.attrs.id === id);
|
|
20
|
+
/**
|
|
21
|
+
* Occurrences of `ann.text` that could take the mark. Counts per occurrence,
|
|
22
|
+
* not per node: one text node saying "set attributes before reading attributes"
|
|
23
|
+
* offers two candidates, and picking either silently relocates the comment.
|
|
24
|
+
*/
|
|
25
|
+
function countCandidates(node, ann) {
|
|
26
|
+
if (node?.type === 'text') {
|
|
27
|
+
if (typeof node.text !== 'string' || hasAnnotationId(node, ann.id))
|
|
28
|
+
return 0;
|
|
29
|
+
return node.text.split(ann.text).length - 1;
|
|
30
|
+
}
|
|
31
|
+
return (node?.content ?? []).reduce((sum, c) => sum + countCandidates(c, ann), 0);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Collect every inline-comment annotation in `doc`, in document order.
|
|
35
|
+
* Text spanning several nodes (a comment covering bold text, say) is
|
|
36
|
+
* concatenated under one id.
|
|
37
|
+
*/
|
|
38
|
+
export function collectAnnotations(doc) {
|
|
39
|
+
const byId = new Map();
|
|
40
|
+
const walk = (node) => {
|
|
41
|
+
if (!node || typeof node !== 'object')
|
|
42
|
+
return;
|
|
43
|
+
if (node.type === 'text' && typeof node.text === 'string') {
|
|
44
|
+
for (const m of node.marks ?? []) {
|
|
45
|
+
if (!isAnnotation(m))
|
|
46
|
+
continue;
|
|
47
|
+
const found = byId.get(m.attrs.id);
|
|
48
|
+
if (found)
|
|
49
|
+
found.text += node.text;
|
|
50
|
+
else
|
|
51
|
+
byId.set(m.attrs.id, {
|
|
52
|
+
id: m.attrs.id,
|
|
53
|
+
annotationType: m.attrs.annotationType ?? 'inlineComment',
|
|
54
|
+
text: node.text,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const child of node.content ?? [])
|
|
59
|
+
walk(child);
|
|
60
|
+
};
|
|
61
|
+
walk(doc);
|
|
62
|
+
return [...byId.values()];
|
|
63
|
+
}
|
|
64
|
+
/** Split `node` at `at` so the annotated slice carries the extra mark. */
|
|
65
|
+
function splitText(node, at, ann) {
|
|
66
|
+
const before = node.text.slice(0, at);
|
|
67
|
+
const after = node.text.slice(at + ann.text.length);
|
|
68
|
+
const mark = { type: 'annotation', attrs: { id: ann.id, annotationType: ann.annotationType } };
|
|
69
|
+
return [
|
|
70
|
+
...(before ? [{ ...node, text: before }] : []),
|
|
71
|
+
{ ...node, text: ann.text, marks: [...(node.marks ?? []), mark] },
|
|
72
|
+
...(after ? [{ ...node, text: after }] : []),
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
/** Re-anchor one annotation onto the first unannotated text node containing its text. */
|
|
76
|
+
function applyOne(node, ann, state) {
|
|
77
|
+
if (state.applied || !node || !Array.isArray(node.content))
|
|
78
|
+
return node;
|
|
79
|
+
const out = [];
|
|
80
|
+
for (const child of node.content) {
|
|
81
|
+
if (!state.applied && child?.type === 'text' && typeof child.text === 'string' && !hasAnnotationId(child, ann.id)) {
|
|
82
|
+
const at = child.text.indexOf(ann.text);
|
|
83
|
+
if (at !== -1) {
|
|
84
|
+
state.applied = true;
|
|
85
|
+
out.push(...splitText(child, at, ann));
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
out.push(state.applied ? child : applyOne(child, ann, state));
|
|
90
|
+
}
|
|
91
|
+
return { ...node, content: out };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Re-apply `annotations` to `doc`, matching on the annotated text.
|
|
95
|
+
*
|
|
96
|
+
* An anchor whose text occurs more than once is reported in `ambiguous` and
|
|
97
|
+
* left unmarked. Picking an occurrence would move a reviewer's comment onto
|
|
98
|
+
* unrelated text while reporting success; leaving it unmarked reproduces
|
|
99
|
+
* exactly what Confluence does today, so it costs nothing and stays visible.
|
|
100
|
+
*
|
|
101
|
+
* ponytail: exact substring within a single text node. A comment whose text was
|
|
102
|
+
* reworded, or whose span is broken up by other marks (`**bold** inside the
|
|
103
|
+
* selection`), lands in `dropped`. Upgrade path if that bites: match across
|
|
104
|
+
* adjacent text nodes, then fuzzy/longest-common-substring.
|
|
105
|
+
*/
|
|
106
|
+
export function reapplyAnnotations(doc, annotations) {
|
|
107
|
+
let out = doc;
|
|
108
|
+
const preserved = [];
|
|
109
|
+
const dropped = [];
|
|
110
|
+
const ambiguous = [];
|
|
111
|
+
for (const ann of annotations) {
|
|
112
|
+
if (!ann.text.trim()) {
|
|
113
|
+
dropped.push(ann);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (countCandidates(out, ann) > 1) {
|
|
117
|
+
ambiguous.push(ann);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const state = { applied: false };
|
|
121
|
+
const next = applyOne(out, ann, state);
|
|
122
|
+
if (state.applied) {
|
|
123
|
+
out = next;
|
|
124
|
+
preserved.push(ann);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
dropped.push(ann);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { doc: out, preserved, dropped, ambiguous };
|
|
131
|
+
}
|
|
132
|
+
const TABLE = 'table';
|
|
133
|
+
/** Concatenated text of the nodes under `node` carrying `markerRef`. */
|
|
134
|
+
function annotatedText(node, markerRef) {
|
|
135
|
+
if (node?.type === 'text') {
|
|
136
|
+
return (node.marks ?? []).some((m) => isAnnotation(m) && m.attrs.id === markerRef) ? node.text : '';
|
|
137
|
+
}
|
|
138
|
+
return (node?.content ?? []).map((c) => annotatedText(c, markerRef)).join('');
|
|
139
|
+
}
|
|
140
|
+
const flatten = (node) => node?.type === 'text' ? node.text ?? '' : (node?.content ?? []).map(flatten).join('');
|
|
141
|
+
function annotationTypeOf(node, markerRef) {
|
|
142
|
+
if (node?.type === 'text') {
|
|
143
|
+
const found = (node.marks ?? []).find((m) => isAnnotation(m) && m.attrs.id === markerRef);
|
|
144
|
+
return found?.attrs?.annotationType ?? '';
|
|
145
|
+
}
|
|
146
|
+
for (const child of node?.content ?? []) {
|
|
147
|
+
const found = annotationTypeOf(child, markerRef);
|
|
148
|
+
if (found)
|
|
149
|
+
return found;
|
|
150
|
+
}
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Describe where `markerRef` is anchored in `doc`. Returns null if absent.
|
|
155
|
+
*
|
|
156
|
+
* Tables are keyed by header row + the row's first-column value, so a comment
|
|
157
|
+
* on a field-reference row still resolves after rows are added or reordered
|
|
158
|
+
* above it — an index would not survive that.
|
|
159
|
+
*/
|
|
160
|
+
export function locateAnnotation(doc, markerRef) {
|
|
161
|
+
for (const block of doc?.content ?? []) {
|
|
162
|
+
const text = annotatedText(block, markerRef);
|
|
163
|
+
if (!text)
|
|
164
|
+
continue;
|
|
165
|
+
const annotationType = annotationTypeOf(block, markerRef) || 'inlineComment';
|
|
166
|
+
if (block.type === TABLE) {
|
|
167
|
+
const header = (block.content?.[0]?.content ?? []).map(flatten);
|
|
168
|
+
for (const row of block.content ?? []) {
|
|
169
|
+
const cells = row.content ?? [];
|
|
170
|
+
const cell = cells.findIndex((c) => annotatedText(c, markerRef));
|
|
171
|
+
if (cell === -1)
|
|
172
|
+
continue;
|
|
173
|
+
return { kind: 'tableCell', header, rowKey: flatten(cells[0]), cell, text, annotationType };
|
|
174
|
+
}
|
|
175
|
+
continue; // marker counted inside the table but no cell owned it — treat as unlocatable
|
|
176
|
+
}
|
|
177
|
+
return { kind: 'block', blockType: block.type, blockText: flatten(block), text, annotationType };
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/** Candidate nodes in `doc` that `locator` could describe. */
|
|
182
|
+
function findHosts(doc, locator) {
|
|
183
|
+
const blocks = doc?.content ?? [];
|
|
184
|
+
if (locator.kind === 'block') {
|
|
185
|
+
return blocks.filter((b) => b?.type === locator.blockType && flatten(b) === locator.blockText);
|
|
186
|
+
}
|
|
187
|
+
const hosts = [];
|
|
188
|
+
const wantHeader = JSON.stringify(locator.header);
|
|
189
|
+
for (const block of blocks) {
|
|
190
|
+
if (block?.type !== TABLE)
|
|
191
|
+
continue;
|
|
192
|
+
if (JSON.stringify((block.content?.[0]?.content ?? []).map(flatten)) !== wantHeader)
|
|
193
|
+
continue;
|
|
194
|
+
for (const row of block.content ?? []) {
|
|
195
|
+
const cells = row.content ?? [];
|
|
196
|
+
if (flatten(cells[0]) !== locator.rowKey)
|
|
197
|
+
continue;
|
|
198
|
+
if (cells[locator.cell])
|
|
199
|
+
hosts.push(cells[locator.cell]);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return hosts;
|
|
203
|
+
}
|
|
204
|
+
/** Rebuild `node` with `target` (matched by identity) swapped for `replacement`. */
|
|
205
|
+
function replaceNode(node, target, replacement) {
|
|
206
|
+
if (node === target)
|
|
207
|
+
return replacement;
|
|
208
|
+
if (!node || !Array.isArray(node.content))
|
|
209
|
+
return node;
|
|
210
|
+
return { ...node, content: node.content.map((c) => replaceNode(c, target, replacement)) };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Re-attach `markerRef` to `doc` at the position `locator` describes.
|
|
214
|
+
*
|
|
215
|
+
* 'ambiguous' means several equally-good hosts matched; the caller must decide,
|
|
216
|
+
* because guessing silently moves a reviewer's comment onto unrelated text.
|
|
217
|
+
* That is not hypothetical — anchor text "unique_id" occurs in ten text nodes
|
|
218
|
+
* of a real page whose true anchor was one specific table cell.
|
|
219
|
+
*/
|
|
220
|
+
export function applyLocator(doc, locator, markerRef) {
|
|
221
|
+
const ann = { id: markerRef, annotationType: locator.annotationType, text: locator.text };
|
|
222
|
+
const structural = findHosts(doc, locator);
|
|
223
|
+
const hosts = structural.filter((h) => canMark(h, ann));
|
|
224
|
+
if (hosts.length === 0) {
|
|
225
|
+
// 'unmatchable' only when the text is genuinely still there but split across
|
|
226
|
+
// nodes. A surviving host proves nothing on its own: a renamed table field
|
|
227
|
+
// keeps its row while the anchored words are gone, and that is 'lost'.
|
|
228
|
+
const stillPresent = structural.some((h) => flatten(h).includes(ann.text));
|
|
229
|
+
return { doc, status: stillPresent ? 'unmatchable' : 'lost' };
|
|
230
|
+
}
|
|
231
|
+
if (hosts.length > 1)
|
|
232
|
+
return { doc, status: 'ambiguous' };
|
|
233
|
+
// Narrowing to one host is not enough: the anchor may repeat inside it, and
|
|
234
|
+
// applyOne would take the first occurrence and report success.
|
|
235
|
+
if (countCandidates(hosts[0], ann) > 1)
|
|
236
|
+
return { doc, status: 'ambiguous' };
|
|
237
|
+
const state = { applied: false };
|
|
238
|
+
const marked = applyOne(hosts[0], ann, state);
|
|
239
|
+
return state.applied ? { doc: replaceNode(doc, hosts[0], marked), status: 'exact' } : { doc, status: 'unmatchable' };
|
|
240
|
+
}
|
|
241
|
+
function canMark(host, ann) {
|
|
242
|
+
const state = { applied: false };
|
|
243
|
+
applyOne(host, ann, state);
|
|
244
|
+
return state.applied;
|
|
245
|
+
}
|
|
246
|
+
// ponytail: self-check, run with `npx tsx src/formatters/annotations.ts`
|
|
247
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
248
|
+
const { deepEqual, equal } = await import('node:assert');
|
|
249
|
+
const must = (loc) => {
|
|
250
|
+
if (!loc)
|
|
251
|
+
throw new Error('expected a locator, got null');
|
|
252
|
+
return loc;
|
|
253
|
+
};
|
|
254
|
+
const ann = (id) => ({ type: 'annotation', attrs: { id, annotationType: 'inlineComment' } });
|
|
255
|
+
const text = (t, marks) => ({ type: 'text', text: t, ...(marks ? { marks } : {}) });
|
|
256
|
+
const para = (...content) => ({ type: 'paragraph', content });
|
|
257
|
+
const doc = (...content) => ({ type: 'doc', version: 1, content });
|
|
258
|
+
// collect: single node, multi-node span, and none
|
|
259
|
+
deepEqual(collectAnnotations(doc(para(text('hi '), text('there', [ann('c1')])))), [
|
|
260
|
+
{ id: 'c1', annotationType: 'inlineComment', text: 'there' },
|
|
261
|
+
]);
|
|
262
|
+
deepEqual(collectAnnotations(doc(para(text('a', [ann('c1')]), text('b', [ann('c1'), { type: 'strong' }])))), [{ id: 'c1', annotationType: 'inlineComment', text: 'ab' }]);
|
|
263
|
+
deepEqual(collectAnnotations(doc(para(text('plain')))), []);
|
|
264
|
+
// reapply: text survived -> node splits into 3, mark on the middle slice
|
|
265
|
+
const anns = collectAnnotations(doc(para(text('fix '), text('this bug', [ann('c1')]), text(' now'))));
|
|
266
|
+
const fresh = doc(para(text('please fix this bug now, thanks')));
|
|
267
|
+
const r = reapplyAnnotations(fresh, anns);
|
|
268
|
+
equal(r.preserved.length, 1);
|
|
269
|
+
equal(r.dropped.length, 0);
|
|
270
|
+
deepEqual(r.doc.content[0].content, [
|
|
271
|
+
text('please fix '),
|
|
272
|
+
text('this bug', [ann('c1')]),
|
|
273
|
+
text(' now, thanks'),
|
|
274
|
+
]);
|
|
275
|
+
// original left untouched
|
|
276
|
+
deepEqual(fresh.content[0].content, [text('please fix this bug now, thanks')]);
|
|
277
|
+
// reapply: anchors inside nested structures, and preserves existing marks
|
|
278
|
+
const nested = doc({
|
|
279
|
+
type: 'bulletList',
|
|
280
|
+
content: [{ type: 'listItem', content: [para(text('the bug', [{ type: 'strong' }]))] }],
|
|
281
|
+
});
|
|
282
|
+
const rn = reapplyAnnotations(nested, [{ id: 'c9', annotationType: 'inlineComment', text: 'the bug' }]);
|
|
283
|
+
equal(rn.preserved.length, 1);
|
|
284
|
+
deepEqual(rn.doc.content[0].content[0].content[0].content, [
|
|
285
|
+
text('the bug', [{ type: 'strong' }, ann('c9')]),
|
|
286
|
+
]);
|
|
287
|
+
// reapply: reworded text is dropped, not force-fitted
|
|
288
|
+
const rd = reapplyAnnotations(doc(para(text('completely rewritten'))), anns);
|
|
289
|
+
equal(rd.preserved.length, 0);
|
|
290
|
+
deepEqual(rd.dropped.map((a) => a.id), ['c1']);
|
|
291
|
+
// an anchor occurring twice is refused, not guessed at — marking either one
|
|
292
|
+
// would move a reviewer's comment onto unrelated text and report success
|
|
293
|
+
const twice = [{ id: 'a', annotationType: 'inlineComment', text: 'dup' }];
|
|
294
|
+
const rtwice = reapplyAnnotations(doc(para(text('dup one')), para(text('dup two'))), twice);
|
|
295
|
+
deepEqual(rtwice.ambiguous.map((a) => a.id), ['a']);
|
|
296
|
+
equal(rtwice.preserved.length, 0);
|
|
297
|
+
deepEqual(rtwice.doc.content[0].content[0].marks, undefined); // nothing marked
|
|
298
|
+
// two comments on the SAME occurrence both attach — Confluence allows it, so
|
|
299
|
+
// an unrelated annotation must not hide the text from the next one
|
|
300
|
+
const same = [
|
|
301
|
+
{ id: 'a', annotationType: 'inlineComment', text: 'shared' },
|
|
302
|
+
{ id: 'b', annotationType: 'inlineComment', text: 'shared' },
|
|
303
|
+
];
|
|
304
|
+
const rsame = reapplyAnnotations(doc(para(text('shared'))), same);
|
|
305
|
+
equal(rsame.preserved.length, 2);
|
|
306
|
+
equal(rsame.ambiguous.length, 0);
|
|
307
|
+
deepEqual(rsame.doc.content[0].content[0].marks, [ann('a'), ann('b')]);
|
|
308
|
+
// two comments sharing an anchor text over two occurrences are BOTH refused —
|
|
309
|
+
// each occurrence is a candidate for each id, so neither can be placed safely.
|
|
310
|
+
// ponytail: the old first-match behaviour paired them in document order and
|
|
311
|
+
// was right when comment order matched text order; refusing is the safe
|
|
312
|
+
// default. Upgrade path if it bites: pair by document order.
|
|
313
|
+
const rt = reapplyAnnotations(doc(para(text('dup ')), para(text('dup '))), [
|
|
314
|
+
{ id: 'a', annotationType: 'inlineComment', text: 'dup ' },
|
|
315
|
+
{ id: 'b', annotationType: 'inlineComment', text: 'dup ' },
|
|
316
|
+
]);
|
|
317
|
+
equal(rt.ambiguous.length, 2);
|
|
318
|
+
equal(rt.preserved.length, 0);
|
|
319
|
+
// a repeat INSIDE one text node is two candidates, not one — counting nodes
|
|
320
|
+
// instead of occurrences let this through and marked the first silently
|
|
321
|
+
const twiceInOne = [{ id: 'r', annotationType: 'inlineComment', text: 'attributes' }];
|
|
322
|
+
const rIn = reapplyAnnotations(doc(para(text('set attributes before reading attributes'))), twiceInOne);
|
|
323
|
+
deepEqual(rIn.ambiguous.map((a) => a.id), ['r']);
|
|
324
|
+
deepEqual(rIn.doc.content[0].content[0].marks, undefined);
|
|
325
|
+
// same repeat, but reached through the structural locator — the primary path
|
|
326
|
+
const priorRepeat = doc(para(text('set '), text('attributes', [ann('r2')]), text(' before reading attributes')));
|
|
327
|
+
const locRepeat = must(locateAnnotation(priorRepeat, 'r2'));
|
|
328
|
+
const flatRepeat = doc(para(text('set attributes before reading attributes')));
|
|
329
|
+
equal(applyLocator(flatRepeat, locRepeat, 'r2').status, 'ambiguous');
|
|
330
|
+
// empty/whitespace anchor is never applied
|
|
331
|
+
equal(reapplyAnnotations(doc(para(text('x'))), [{ id: 'z', annotationType: 'inlineComment', text: ' ' }]).dropped.length, 1);
|
|
332
|
+
deepEqual(reapplyAnnotations(doc(), []), { doc: doc(), preserved: [], dropped: [], ambiguous: [] });
|
|
333
|
+
// ---- locateAnnotation / applyLocator ----
|
|
334
|
+
// Shapes and expectations mirror the real page this was built for: a
|
|
335
|
+
// field-reference table (header row 'JSON key'…) whose first column holds the
|
|
336
|
+
// field name, plus an h2 whose text IS the anchor.
|
|
337
|
+
const cell = (...content) => ({ type: 'tableCell', content });
|
|
338
|
+
const row = (...content) => ({ type: 'tableRow', content });
|
|
339
|
+
const p = (t, marks) => para(text(t, marks));
|
|
340
|
+
const fieldTable = (keyRowMarks) => ({
|
|
341
|
+
type: 'table',
|
|
342
|
+
content: [
|
|
343
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
344
|
+
row(cell(p('unique_id', keyRowMarks)), cell(p('string')), cell(p('the source_data key'))),
|
|
345
|
+
row(cell(p('attributes')), cell(p('object')), cell(p('your payload'))),
|
|
346
|
+
],
|
|
347
|
+
});
|
|
348
|
+
// locate: table cell, keyed by header + first-column value, not by index
|
|
349
|
+
const prior = doc(fieldTable([ann('m1')]), { type: 'heading', attrs: { level: 2 }, content: [text('Field reference', [ann('m2')])] });
|
|
350
|
+
deepEqual(locateAnnotation(prior, 'm1'), {
|
|
351
|
+
kind: 'tableCell', header: ['JSON key', 'Type', 'Notes'], rowKey: 'unique_id', cell: 0,
|
|
352
|
+
text: 'unique_id', annotationType: 'inlineComment',
|
|
353
|
+
});
|
|
354
|
+
deepEqual(locateAnnotation(prior, 'm2'), {
|
|
355
|
+
kind: 'block', blockType: 'heading', blockText: 'Field reference',
|
|
356
|
+
text: 'Field reference', annotationType: 'inlineComment',
|
|
357
|
+
});
|
|
358
|
+
equal(locateAnnotation(prior, 'nope'), null);
|
|
359
|
+
// apply: lands on the field-name cell even though 'unique_id' also appears in
|
|
360
|
+
// another row's Notes column — the bug that motivated this resolver
|
|
361
|
+
const noisy = doc({
|
|
362
|
+
type: 'table',
|
|
363
|
+
content: [
|
|
364
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
365
|
+
row(cell(p('tenant_id')), cell(p('string')), cell(p('pairs with unique_id'))),
|
|
366
|
+
row(cell(p('unique_id')), cell(p('string')), cell(p('the source_data key'))),
|
|
367
|
+
],
|
|
368
|
+
});
|
|
369
|
+
const applied = applyLocator(noisy, must(locateAnnotation(prior, 'm1')), 'm1');
|
|
370
|
+
equal(applied.status, 'exact');
|
|
371
|
+
deepEqual(applied.doc.content[0].content[2].content[0].content[0].content, [text('unique_id', [ann('m1')])]);
|
|
372
|
+
// the decoy row is untouched
|
|
373
|
+
deepEqual(applied.doc.content[0].content[1].content[2].content[0].content, [text('pairs with unique_id')]);
|
|
374
|
+
// apply: row inserted above the target shifts every index, rowKey still finds it
|
|
375
|
+
const shifted = doc({
|
|
376
|
+
type: 'table',
|
|
377
|
+
content: [
|
|
378
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
379
|
+
row(cell(p('event_name')), cell(p('string')), cell(p('added later'))),
|
|
380
|
+
row(cell(p('unique_id')), cell(p('string')), cell(p('the source_data key'))),
|
|
381
|
+
row(cell(p('attributes')), cell(p('object')), cell(p('your payload'))),
|
|
382
|
+
],
|
|
383
|
+
});
|
|
384
|
+
equal(applyLocator(shifted, must(locateAnnotation(prior, 'm1')), 'm1').status, 'exact');
|
|
385
|
+
// ambiguous: two rows share the key, so there is no single right answer
|
|
386
|
+
const dupKey = doc({
|
|
387
|
+
type: 'table',
|
|
388
|
+
content: [
|
|
389
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
390
|
+
row(cell(p('unique_id')), cell(p('string')), cell(p('one'))),
|
|
391
|
+
row(cell(p('unique_id')), cell(p('string')), cell(p('two'))),
|
|
392
|
+
],
|
|
393
|
+
});
|
|
394
|
+
const amb = applyLocator(dupKey, must(locateAnnotation(prior, 'm1')), 'm1');
|
|
395
|
+
equal(amb.status, 'ambiguous');
|
|
396
|
+
equal(JSON.stringify(amb.doc), JSON.stringify(dupKey)); // must not mark anything
|
|
397
|
+
// lost: the row is gone, and separately, the table header changed
|
|
398
|
+
const rowGone = doc({
|
|
399
|
+
type: 'table',
|
|
400
|
+
content: [row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))), row(cell(p('attributes')), cell(p('object')), cell(p('x')))],
|
|
401
|
+
});
|
|
402
|
+
equal(applyLocator(rowGone, must(locateAnnotation(prior, 'm1')), 'm1').status, 'lost');
|
|
403
|
+
equal(applyLocator(doc({
|
|
404
|
+
type: 'table',
|
|
405
|
+
content: [row(cell(p('Field')), cell(p('Type')), cell(p('Notes'))), row(cell(p('unique_id')), cell(p('string')), cell(p('x')))],
|
|
406
|
+
}), must(locateAnnotation(prior, 'm1')), 'm1').status, 'lost');
|
|
407
|
+
// lost: heading text reworded
|
|
408
|
+
equal(applyLocator(doc({ type: 'heading', attrs: { level: 2 }, content: [text('Fields')] }), must(locateAnnotation(prior, 'm2')), 'm2').status, 'lost');
|
|
409
|
+
// exact: heading unchanged
|
|
410
|
+
equal(applyLocator(doc({ type: 'heading', attrs: { level: 2 }, content: [text('Field reference')] }), must(locateAnnotation(prior, 'm2')), 'm2').status, 'exact');
|
|
411
|
+
// unmatchable, NOT lost: the block survives but the anchor spans two text
|
|
412
|
+
// nodes, so it cannot be marked as one run — the reason must say so
|
|
413
|
+
const spanning = doc(para(text('fix '), text('this', [ann('m3'), { type: 'strong' }]), text(' bug')));
|
|
414
|
+
const spanLoc = must(locateAnnotation(spanning, 'm3'));
|
|
415
|
+
equal(spanLoc.text, 'this');
|
|
416
|
+
const splitAnchor = doc(para(text('fix '), text('th'), text('is bug')));
|
|
417
|
+
equal(applyLocator(splitAnchor, { ...spanLoc, text: 'this bug' }, 'm3').status, 'unmatchable');
|
|
418
|
+
// and genuinely-gone text still reports lost
|
|
419
|
+
equal(applyLocator(doc(para(text('unrelated'))), { ...spanLoc, text: 'this bug' }, 'm3').status, 'lost');
|
|
420
|
+
// lost, NOT unmatchable: the host row survives but the anchored field was
|
|
421
|
+
// renamed away. A surviving host must not be read as surviving text.
|
|
422
|
+
const priorRenamed = doc({
|
|
423
|
+
type: 'table',
|
|
424
|
+
content: [
|
|
425
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
426
|
+
row(cell(p('event_name')), cell(p('string')), cell(para(text('must match an '), text('alert_config', [ann('m4')])))),
|
|
427
|
+
],
|
|
428
|
+
});
|
|
429
|
+
const renamedLoc = must(locateAnnotation(priorRenamed, 'm4'));
|
|
430
|
+
equal(renamedLoc.kind === 'tableCell' && renamedLoc.rowKey, 'event_name');
|
|
431
|
+
const renamedNow = doc({
|
|
432
|
+
type: 'table',
|
|
433
|
+
content: [
|
|
434
|
+
row(cell(p('JSON key')), cell(p('Type')), cell(p('Notes'))),
|
|
435
|
+
row(cell(p('event_name')), cell(p('string')), cell(p('must match a configured alert or notification'))),
|
|
436
|
+
],
|
|
437
|
+
});
|
|
438
|
+
equal(applyLocator(renamedNow, renamedLoc, 'm4').status, 'lost');
|
|
439
|
+
console.log('annotations: ok');
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=annotations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/formatters/annotations.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,4 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { markdownToADF } from './markdown-to-adf.js';
|
|
7
7
|
export { extractTextFromADF } from './adf-to-text.js';
|
|
8
|
+
export { assertMarkdown } from './wiki-guard.js';
|
|
9
|
+
export { collectAnnotations, reapplyAnnotations, locateAnnotation, applyLocator } from './annotations.js';
|
|
10
|
+
export type { Annotation, Locator } from './annotations.js';
|
|
8
11
|
//# sourceMappingURL=index.d.ts.map
|