@knpkv/confluence-to-markdown 0.5.0 → 0.6.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/CHANGELOG.md +22 -0
- package/README.md +45 -10
- package/dist/ConfluenceAuth.d.ts.map +1 -1
- package/dist/ConfluenceAuth.js +12 -22
- package/dist/ConfluenceAuth.js.map +1 -1
- package/dist/ConfluenceClient.d.ts +13 -3
- package/dist/ConfluenceClient.d.ts.map +1 -1
- package/dist/ConfluenceClient.js +34 -70
- package/dist/ConfluenceClient.js.map +1 -1
- package/dist/ConfluenceError.d.ts +12 -12
- package/dist/GitError.d.ts +5 -5
- package/dist/GitService.d.ts.map +1 -1
- package/dist/GitService.js +0 -3
- package/dist/GitService.js.map +1 -1
- package/dist/SchemaConverterError.d.ts +3 -3
- package/dist/ast/BlockNode.d.ts +48 -33
- package/dist/ast/BlockNode.d.ts.map +1 -1
- package/dist/ast/BlockNode.js +11 -2
- package/dist/ast/BlockNode.js.map +1 -1
- package/dist/ast/Document.d.ts +30 -2
- package/dist/ast/Document.d.ts.map +1 -1
- package/dist/parsers/ConfluenceParser.d.ts.map +1 -1
- package/dist/parsers/ConfluenceParser.js +7 -12
- package/dist/parsers/ConfluenceParser.js.map +1 -1
- package/dist/parsers/MarkdownParser.js +8 -117
- package/dist/parsers/MarkdownParser.js.map +1 -1
- package/dist/parsers/preprocessing/ConfluencePreprocessing.d.ts +23 -0
- package/dist/parsers/preprocessing/ConfluencePreprocessing.d.ts.map +1 -0
- package/dist/parsers/preprocessing/ConfluencePreprocessing.js +323 -0
- package/dist/parsers/preprocessing/ConfluencePreprocessing.js.map +1 -0
- package/dist/parsers/preprocessing/index.d.ts +7 -0
- package/dist/parsers/preprocessing/index.d.ts.map +1 -0
- package/dist/parsers/preprocessing/index.js +7 -0
- package/dist/parsers/preprocessing/index.js.map +1 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +29 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +1 -1
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js +5 -15
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +1 -1
- package/dist/serializers/ConfluenceSerializer.js +0 -9
- package/dist/serializers/ConfluenceSerializer.js.map +1 -1
- package/dist/serializers/MarkdownSerializer.js +9 -49
- package/dist/serializers/MarkdownSerializer.js.map +1 -1
- package/package.json +35 -26
- package/src/AdfPlaceholders.ts +266 -0
- package/src/AdfSchemaValidator.ts +67 -0
- package/src/AdfWalker.ts +511 -0
- package/src/AtlaskitTransformers.ts +72 -0
- package/src/ConfluenceClient.ts +4 -4
- package/src/ConfluenceError.ts +65 -3
- package/src/MarkdownConverter.ts +106 -139
- package/src/Schemas.ts +4 -4
- package/src/SyncEngine.ts +130 -83
- package/src/atlaskit-adf-schema.d.ts +3 -0
- package/src/commands/clone.ts +8 -1
- package/src/commands/layers.ts +11 -4
- package/src/index.ts +3 -18
- package/test/AdfPlaceholders.test.ts +295 -0
- package/test/AdfSchemaValidator.test.ts +34 -0
- package/test/AdfWalker.test.ts +530 -0
- package/test/AtlaskitTransformers.test.ts +25 -0
- package/test/MarkdownConverter.test.ts +120 -105
- package/test/RoundTrip.test.ts +266 -0
- package/LICENSE +0 -21
- package/src/SchemaConverterError.ts +0 -108
- package/src/ast/BlockNode.ts +0 -469
- package/src/ast/Document.ts +0 -90
- package/src/ast/InlineNode.ts +0 -323
- package/src/ast/MacroNode.ts +0 -245
- package/src/ast/index.ts +0 -83
- package/src/parsers/ConfluenceParser.ts +0 -956
- package/src/parsers/MarkdownParser.ts +0 -1338
- package/src/parsers/index.ts +0 -8
- package/src/schemas/ConfluenceSchema.ts +0 -56
- package/src/schemas/ConversionSchema.ts +0 -318
- package/src/schemas/MarkdownSchema.ts +0 -56
- package/src/schemas/hast/HastFromHtml.ts +0 -153
- package/src/schemas/hast/HastSchema.ts +0 -274
- package/src/schemas/hast/index.ts +0 -35
- package/src/schemas/index.ts +0 -20
- package/src/schemas/mdast/MdastFromMarkdown.ts +0 -118
- package/src/schemas/mdast/MdastSchema.ts +0 -566
- package/src/schemas/mdast/index.ts +0 -59
- package/src/schemas/mdast/mdastToString.ts +0 -102
- package/src/schemas/nodes/block/BlockSchema.ts +0 -773
- package/src/schemas/nodes/block/index.ts +0 -13
- package/src/schemas/nodes/index.ts +0 -20
- package/src/schemas/nodes/inline/InlineSchema.ts +0 -523
- package/src/schemas/nodes/inline/index.ts +0 -14
- package/src/schemas/nodes/macro/MacroSchema.ts +0 -226
- package/src/schemas/nodes/macro/index.ts +0 -6
- package/src/schemas/preprocessing/ConfluencePreprocessor.ts +0 -455
- package/src/schemas/preprocessing/index.ts +0 -8
- package/src/serializers/ConfluenceSerializer.ts +0 -737
- package/src/serializers/MarkdownSerializer.ts +0 -543
- package/src/serializers/index.ts +0 -8
- package/test/ast/BlockNode.test.ts +0 -265
- package/test/ast/Document.test.ts +0 -126
- package/test/ast/InlineNode.test.ts +0 -161
- package/test/fixtures/integration-test.html.fixture +0 -103
- package/test/fixtures/integration-test.md.expected +0 -257
- package/test/parsers/ConfluenceParser.test.ts +0 -452
- package/test/schemas/ConfluencePreprocessor.test.ts +0 -180
- package/test/schemas/ConversionSchema.test.ts +0 -159
- package/test/schemas/HastSchema.test.ts +0 -138
- package/test/schemas/MdastSchema.test.ts +0 -145
- package/test/schemas/nodes/block/BlockSchema.test.ts +0 -173
- package/test/schemas/nodes/inline/InlineSchema.test.ts +0 -198
- package/test/schemas/nodes/macro/MacroSchema.test.ts +0 -142
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
-
import * as Either from "effect/Either"
|
|
3
|
-
import * as Schema from "effect/Schema"
|
|
4
|
-
import {
|
|
5
|
-
BlockNode,
|
|
6
|
-
BlockQuote,
|
|
7
|
-
CodeBlock,
|
|
8
|
-
Heading,
|
|
9
|
-
Image,
|
|
10
|
-
List,
|
|
11
|
-
ListItem,
|
|
12
|
-
Paragraph,
|
|
13
|
-
Table,
|
|
14
|
-
TableCell,
|
|
15
|
-
TableRow,
|
|
16
|
-
ThematicBreak,
|
|
17
|
-
UnsupportedBlock
|
|
18
|
-
} from "../../src/ast/BlockNode.js"
|
|
19
|
-
import { Text } from "../../src/ast/InlineNode.js"
|
|
20
|
-
|
|
21
|
-
describe("BlockNode", () => {
|
|
22
|
-
describe("Heading", () => {
|
|
23
|
-
it("creates heading with level and children", () => {
|
|
24
|
-
const h1 = new Heading({
|
|
25
|
-
level: 1,
|
|
26
|
-
children: [new Text({ value: "Title" })]
|
|
27
|
-
})
|
|
28
|
-
expect(h1._tag).toBe("Heading")
|
|
29
|
-
expect(h1.level).toBe(1)
|
|
30
|
-
expect(h1.version).toBe(1)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it("decodes heading from plain object", () => {
|
|
34
|
-
const result = Schema.decodeUnknownEither(Heading)({
|
|
35
|
-
_tag: "Heading",
|
|
36
|
-
level: 2,
|
|
37
|
-
children: [{ _tag: "Text", value: "Subtitle" }]
|
|
38
|
-
})
|
|
39
|
-
expect(Either.isRight(result)).toBe(true)
|
|
40
|
-
if (Either.isRight(result)) {
|
|
41
|
-
expect(result.right.level).toBe(2)
|
|
42
|
-
expect(result.right.version).toBe(1)
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it("rejects invalid level", () => {
|
|
47
|
-
const result = Schema.decodeUnknownEither(Heading)({
|
|
48
|
-
_tag: "Heading",
|
|
49
|
-
level: 7,
|
|
50
|
-
children: []
|
|
51
|
-
})
|
|
52
|
-
expect(Either.isLeft(result)).toBe(true)
|
|
53
|
-
})
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
describe("Paragraph", () => {
|
|
57
|
-
it("creates paragraph with children", () => {
|
|
58
|
-
const para = new Paragraph({
|
|
59
|
-
children: [new Text({ value: "Hello" })]
|
|
60
|
-
})
|
|
61
|
-
expect(para._tag).toBe("Paragraph")
|
|
62
|
-
expect(para.children).toHaveLength(1)
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
describe("CodeBlock", () => {
|
|
67
|
-
it("creates code block with language", () => {
|
|
68
|
-
const code = new CodeBlock({
|
|
69
|
-
language: "typescript",
|
|
70
|
-
code: "const x = 1"
|
|
71
|
-
})
|
|
72
|
-
expect(code._tag).toBe("CodeBlock")
|
|
73
|
-
expect(code.language).toBe("typescript")
|
|
74
|
-
expect(code.code).toBe("const x = 1")
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it("creates code block without language", () => {
|
|
78
|
-
const code = new CodeBlock({ code: "plain text" })
|
|
79
|
-
expect(code.language).toBeUndefined()
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe("ThematicBreak", () => {
|
|
84
|
-
it("creates thematic break", () => {
|
|
85
|
-
const hr = new ThematicBreak({})
|
|
86
|
-
expect(hr._tag).toBe("ThematicBreak")
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
describe("Image", () => {
|
|
91
|
-
it("creates image with src", () => {
|
|
92
|
-
const img = new Image({
|
|
93
|
-
src: "https://example.com/img.png"
|
|
94
|
-
})
|
|
95
|
-
expect(img._tag).toBe("Image")
|
|
96
|
-
expect(img.src).toBe("https://example.com/img.png")
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it("creates image with alt and title", () => {
|
|
100
|
-
const img = new Image({
|
|
101
|
-
src: "https://example.com/img.png",
|
|
102
|
-
alt: "Alt text",
|
|
103
|
-
title: "Image title"
|
|
104
|
-
})
|
|
105
|
-
expect(img.alt).toBe("Alt text")
|
|
106
|
-
expect(img.title).toBe("Image title")
|
|
107
|
-
})
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
describe("Table", () => {
|
|
111
|
-
it("creates table with header and rows", () => {
|
|
112
|
-
const table = new Table({
|
|
113
|
-
header: new TableRow({
|
|
114
|
-
cells: [
|
|
115
|
-
new TableCell({
|
|
116
|
-
isHeader: true,
|
|
117
|
-
children: [new Text({ value: "Col 1" })]
|
|
118
|
-
})
|
|
119
|
-
]
|
|
120
|
-
}),
|
|
121
|
-
rows: [
|
|
122
|
-
new TableRow({
|
|
123
|
-
cells: [
|
|
124
|
-
new TableCell({
|
|
125
|
-
children: [new Text({ value: "Data" })]
|
|
126
|
-
})
|
|
127
|
-
]
|
|
128
|
-
})
|
|
129
|
-
]
|
|
130
|
-
})
|
|
131
|
-
expect(table._tag).toBe("Table")
|
|
132
|
-
expect(table.header?.cells).toHaveLength(1)
|
|
133
|
-
expect(table.rows).toHaveLength(1)
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
describe("List", () => {
|
|
138
|
-
it("creates unordered list", () => {
|
|
139
|
-
const result = Schema.decodeUnknownEither(List)({
|
|
140
|
-
_tag: "List",
|
|
141
|
-
ordered: false,
|
|
142
|
-
children: [
|
|
143
|
-
{
|
|
144
|
-
_tag: "ListItem",
|
|
145
|
-
children: [
|
|
146
|
-
{
|
|
147
|
-
_tag: "Paragraph",
|
|
148
|
-
children: [{ _tag: "Text", value: "Item 1" }]
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
]
|
|
153
|
-
})
|
|
154
|
-
expect(Either.isRight(result)).toBe(true)
|
|
155
|
-
if (Either.isRight(result)) {
|
|
156
|
-
expect(result.right.ordered).toBe(false)
|
|
157
|
-
expect(result.right.children).toHaveLength(1)
|
|
158
|
-
}
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
it("creates ordered list with start", () => {
|
|
162
|
-
const result = Schema.decodeUnknownEither(List)({
|
|
163
|
-
_tag: "List",
|
|
164
|
-
ordered: true,
|
|
165
|
-
start: 5,
|
|
166
|
-
children: []
|
|
167
|
-
})
|
|
168
|
-
expect(Either.isRight(result)).toBe(true)
|
|
169
|
-
if (Either.isRight(result)) {
|
|
170
|
-
expect(result.right.start).toBe(5)
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
describe("ListItem", () => {
|
|
176
|
-
it("creates list item with checked state", () => {
|
|
177
|
-
const result = Schema.decodeUnknownEither(ListItem)({
|
|
178
|
-
_tag: "ListItem",
|
|
179
|
-
checked: true,
|
|
180
|
-
children: [
|
|
181
|
-
{
|
|
182
|
-
_tag: "Paragraph",
|
|
183
|
-
children: [{ _tag: "Text", value: "Done" }]
|
|
184
|
-
}
|
|
185
|
-
]
|
|
186
|
-
})
|
|
187
|
-
expect(Either.isRight(result)).toBe(true)
|
|
188
|
-
if (Either.isRight(result)) {
|
|
189
|
-
expect(result.right.checked).toBe(true)
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
describe("BlockQuote", () => {
|
|
195
|
-
it("creates block quote with children", () => {
|
|
196
|
-
const result = Schema.decodeUnknownEither(BlockQuote)({
|
|
197
|
-
_tag: "BlockQuote",
|
|
198
|
-
children: [
|
|
199
|
-
{
|
|
200
|
-
_tag: "Paragraph",
|
|
201
|
-
children: [{ _tag: "Text", value: "Quote" }]
|
|
202
|
-
}
|
|
203
|
-
]
|
|
204
|
-
})
|
|
205
|
-
expect(Either.isRight(result)).toBe(true)
|
|
206
|
-
if (Either.isRight(result)) {
|
|
207
|
-
expect(result.right.children).toHaveLength(1)
|
|
208
|
-
}
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
describe("UnsupportedBlock", () => {
|
|
213
|
-
it("creates unsupported block from confluence", () => {
|
|
214
|
-
const block = new UnsupportedBlock({
|
|
215
|
-
rawHtml: "<ac:macro/>",
|
|
216
|
-
source: "confluence"
|
|
217
|
-
})
|
|
218
|
-
expect(block._tag).toBe("UnsupportedBlock")
|
|
219
|
-
expect(block.source).toBe("confluence")
|
|
220
|
-
})
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
describe("BlockNode union", () => {
|
|
224
|
-
it("decodes Heading variant", () => {
|
|
225
|
-
const result = Schema.decodeUnknownEither(BlockNode)({
|
|
226
|
-
_tag: "Heading",
|
|
227
|
-
level: 1,
|
|
228
|
-
children: []
|
|
229
|
-
})
|
|
230
|
-
expect(Either.isRight(result)).toBe(true)
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
it("decodes Paragraph variant", () => {
|
|
234
|
-
const result = Schema.decodeUnknownEither(BlockNode)({
|
|
235
|
-
_tag: "Paragraph",
|
|
236
|
-
children: [{ _tag: "Text", value: "text" }]
|
|
237
|
-
})
|
|
238
|
-
expect(Either.isRight(result)).toBe(true)
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
it("decodes List variant", () => {
|
|
242
|
-
const result = Schema.decodeUnknownEither(BlockNode)({
|
|
243
|
-
_tag: "List",
|
|
244
|
-
ordered: true,
|
|
245
|
-
children: []
|
|
246
|
-
})
|
|
247
|
-
expect(Either.isRight(result)).toBe(true)
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
it("decodes BlockQuote variant", () => {
|
|
251
|
-
const result = Schema.decodeUnknownEither(BlockNode)({
|
|
252
|
-
_tag: "BlockQuote",
|
|
253
|
-
children: []
|
|
254
|
-
})
|
|
255
|
-
expect(Either.isRight(result)).toBe(true)
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
it("rejects unknown tag", () => {
|
|
259
|
-
const result = Schema.decodeUnknownEither(BlockNode)({
|
|
260
|
-
_tag: "Unknown"
|
|
261
|
-
})
|
|
262
|
-
expect(Either.isLeft(result)).toBe(true)
|
|
263
|
-
})
|
|
264
|
-
})
|
|
265
|
-
})
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
-
import * as Either from "effect/Either"
|
|
3
|
-
import * as Schema from "effect/Schema"
|
|
4
|
-
import { Heading } from "../../src/ast/BlockNode.js"
|
|
5
|
-
import { Document, isDocument, makeDocument } from "../../src/ast/Document.js"
|
|
6
|
-
import { Text } from "../../src/ast/InlineNode.js"
|
|
7
|
-
|
|
8
|
-
describe("Document", () => {
|
|
9
|
-
describe("Document schema", () => {
|
|
10
|
-
it("decodes valid document", () => {
|
|
11
|
-
const result = Schema.decodeUnknownEither(Document)({
|
|
12
|
-
children: [
|
|
13
|
-
{
|
|
14
|
-
_tag: "Heading",
|
|
15
|
-
level: 1,
|
|
16
|
-
children: [{ _tag: "Text", value: "Title" }]
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
_tag: "Paragraph",
|
|
20
|
-
children: [{ _tag: "Text", value: "Content" }]
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
})
|
|
24
|
-
expect(Either.isRight(result)).toBe(true)
|
|
25
|
-
if (Either.isRight(result)) {
|
|
26
|
-
expect(result.right.version).toBe(1)
|
|
27
|
-
expect(result.right.children).toHaveLength(2)
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it("decodes document with explicit version", () => {
|
|
32
|
-
const result = Schema.decodeUnknownEither(Document)({
|
|
33
|
-
version: 2,
|
|
34
|
-
children: []
|
|
35
|
-
})
|
|
36
|
-
expect(Either.isRight(result)).toBe(true)
|
|
37
|
-
if (Either.isRight(result)) {
|
|
38
|
-
expect(result.right.version).toBe(2)
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it("decodes document with macro nodes", () => {
|
|
43
|
-
const result = Schema.decodeUnknownEither(Document)({
|
|
44
|
-
children: [
|
|
45
|
-
{
|
|
46
|
-
_tag: "InfoPanel",
|
|
47
|
-
panelType: "warning",
|
|
48
|
-
children: [
|
|
49
|
-
{
|
|
50
|
-
_tag: "Paragraph",
|
|
51
|
-
children: [{ _tag: "Text", value: "Warning!" }]
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
})
|
|
57
|
-
expect(Either.isRight(result)).toBe(true)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it("encodes document to plain object", () => {
|
|
61
|
-
const doc: Schema.Schema.Type<typeof Document> = {
|
|
62
|
-
version: 1,
|
|
63
|
-
children: [
|
|
64
|
-
new Heading({
|
|
65
|
-
level: 1,
|
|
66
|
-
children: [new Text({ value: "Hello" })]
|
|
67
|
-
})
|
|
68
|
-
]
|
|
69
|
-
}
|
|
70
|
-
const result = Schema.encodeUnknownEither(Document)(doc)
|
|
71
|
-
expect(Either.isRight(result)).toBe(true)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it("rejects invalid children", () => {
|
|
75
|
-
const result = Schema.decodeUnknownEither(Document)({
|
|
76
|
-
children: [{ invalid: true }]
|
|
77
|
-
})
|
|
78
|
-
expect(Either.isLeft(result)).toBe(true)
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
describe("makeDocument", () => {
|
|
83
|
-
it("creates document with default version", () => {
|
|
84
|
-
const doc = makeDocument([
|
|
85
|
-
new Heading({
|
|
86
|
-
level: 1,
|
|
87
|
-
children: [new Text({ value: "Title" })]
|
|
88
|
-
})
|
|
89
|
-
])
|
|
90
|
-
expect(doc.version).toBe(1)
|
|
91
|
-
expect(doc.children).toHaveLength(1)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it("creates empty document", () => {
|
|
95
|
-
const doc = makeDocument([])
|
|
96
|
-
expect(doc.children).toHaveLength(0)
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
describe("isDocument", () => {
|
|
101
|
-
it("returns true for valid document", () => {
|
|
102
|
-
const doc = makeDocument([])
|
|
103
|
-
expect(isDocument(doc)).toBe(true)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it("returns true for document-like object", () => {
|
|
107
|
-
expect(isDocument({ children: [] })).toBe(true)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it("returns false for null", () => {
|
|
111
|
-
expect(isDocument(null)).toBe(false)
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it("returns false for non-object", () => {
|
|
115
|
-
expect(isDocument("string")).toBe(false)
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it("returns false for object without children", () => {
|
|
119
|
-
expect(isDocument({ version: 1 })).toBe(false)
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it("returns false for object with non-array children", () => {
|
|
123
|
-
expect(isDocument({ children: "not array" })).toBe(false)
|
|
124
|
-
})
|
|
125
|
-
})
|
|
126
|
-
})
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
-
import * as Either from "effect/Either"
|
|
3
|
-
import * as Schema from "effect/Schema"
|
|
4
|
-
import {
|
|
5
|
-
Emphasis,
|
|
6
|
-
InlineCode,
|
|
7
|
-
InlineNode,
|
|
8
|
-
LineBreak,
|
|
9
|
-
Link,
|
|
10
|
-
Strong,
|
|
11
|
-
Text,
|
|
12
|
-
UnsupportedInline
|
|
13
|
-
} from "../../src/ast/InlineNode.js"
|
|
14
|
-
|
|
15
|
-
describe("InlineNode", () => {
|
|
16
|
-
describe("Text", () => {
|
|
17
|
-
it("creates text node", () => {
|
|
18
|
-
const text = new Text({ value: "Hello world" })
|
|
19
|
-
expect(text.value).toBe("Hello world")
|
|
20
|
-
expect(text._tag).toBe("Text")
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it("decodes from plain object", () => {
|
|
24
|
-
const result = Schema.decodeUnknownEither(Text)({
|
|
25
|
-
_tag: "Text",
|
|
26
|
-
value: "test"
|
|
27
|
-
})
|
|
28
|
-
expect(Either.isRight(result)).toBe(true)
|
|
29
|
-
if (Either.isRight(result)) {
|
|
30
|
-
expect(result.right.value).toBe("test")
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it("encodes to plain object", () => {
|
|
35
|
-
const text = new Text({ value: "hello" })
|
|
36
|
-
const result = Schema.encodeUnknownEither(Text)(text)
|
|
37
|
-
expect(Either.isRight(result)).toBe(true)
|
|
38
|
-
if (Either.isRight(result)) {
|
|
39
|
-
expect(result.right).toEqual({ _tag: "Text", value: "hello" })
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
describe("Strong", () => {
|
|
45
|
-
it("creates strong node with children", () => {
|
|
46
|
-
const strong = new Strong({
|
|
47
|
-
children: [new Text({ value: "bold" })]
|
|
48
|
-
})
|
|
49
|
-
expect(strong._tag).toBe("Strong")
|
|
50
|
-
expect(strong.children).toHaveLength(1)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it("decodes from plain object", () => {
|
|
54
|
-
const result = Schema.decodeUnknownEither(Strong)({
|
|
55
|
-
_tag: "Strong",
|
|
56
|
-
children: [{ _tag: "Text", value: "bold" }]
|
|
57
|
-
})
|
|
58
|
-
expect(Either.isRight(result)).toBe(true)
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
describe("Emphasis", () => {
|
|
63
|
-
it("creates emphasis node with children", () => {
|
|
64
|
-
const em = new Emphasis({
|
|
65
|
-
children: [new Text({ value: "italic" })]
|
|
66
|
-
})
|
|
67
|
-
expect(em._tag).toBe("Emphasis")
|
|
68
|
-
expect(em.children).toHaveLength(1)
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
describe("InlineCode", () => {
|
|
73
|
-
it("creates inline code node", () => {
|
|
74
|
-
const code = new InlineCode({ value: "const x = 1" })
|
|
75
|
-
expect(code._tag).toBe("InlineCode")
|
|
76
|
-
expect(code.value).toBe("const x = 1")
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
describe("Link", () => {
|
|
81
|
-
it("creates link with href and children", () => {
|
|
82
|
-
const link = new Link({
|
|
83
|
-
href: "https://example.com",
|
|
84
|
-
children: [new Text({ value: "Click" })]
|
|
85
|
-
})
|
|
86
|
-
expect(link._tag).toBe("Link")
|
|
87
|
-
expect(link.href).toBe("https://example.com")
|
|
88
|
-
expect(link.title).toBeUndefined()
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it("creates link with optional title", () => {
|
|
92
|
-
const link = new Link({
|
|
93
|
-
href: "https://example.com",
|
|
94
|
-
title: "Example",
|
|
95
|
-
children: [new Text({ value: "Click" })]
|
|
96
|
-
})
|
|
97
|
-
expect(link.title).toBe("Example")
|
|
98
|
-
})
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
describe("LineBreak", () => {
|
|
102
|
-
it("creates line break node", () => {
|
|
103
|
-
const br = new LineBreak({})
|
|
104
|
-
expect(br._tag).toBe("LineBreak")
|
|
105
|
-
})
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
describe("UnsupportedInline", () => {
|
|
109
|
-
it("creates unsupported inline from confluence", () => {
|
|
110
|
-
const unknown = new UnsupportedInline({
|
|
111
|
-
raw: "<ac:custom/>",
|
|
112
|
-
source: "confluence"
|
|
113
|
-
})
|
|
114
|
-
expect(unknown._tag).toBe("UnsupportedInline")
|
|
115
|
-
expect(unknown.source).toBe("confluence")
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it("creates unsupported inline from markdown", () => {
|
|
119
|
-
const unknown = new UnsupportedInline({
|
|
120
|
-
raw: "~~strike~~",
|
|
121
|
-
source: "markdown"
|
|
122
|
-
})
|
|
123
|
-
expect(unknown.source).toBe("markdown")
|
|
124
|
-
})
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
describe("InlineNode union", () => {
|
|
128
|
-
it("decodes Text variant", () => {
|
|
129
|
-
const result = Schema.decodeUnknownEither(InlineNode)({
|
|
130
|
-
_tag: "Text",
|
|
131
|
-
value: "hello"
|
|
132
|
-
})
|
|
133
|
-
expect(Either.isRight(result)).toBe(true)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it("decodes Strong variant", () => {
|
|
137
|
-
const result = Schema.decodeUnknownEither(InlineNode)({
|
|
138
|
-
_tag: "Strong",
|
|
139
|
-
children: [{ _tag: "Text", value: "bold" }]
|
|
140
|
-
})
|
|
141
|
-
expect(Either.isRight(result)).toBe(true)
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it("decodes Link variant", () => {
|
|
145
|
-
const result = Schema.decodeUnknownEither(InlineNode)({
|
|
146
|
-
_tag: "Link",
|
|
147
|
-
href: "https://example.com",
|
|
148
|
-
children: [{ _tag: "Text", value: "link" }]
|
|
149
|
-
})
|
|
150
|
-
expect(Either.isRight(result)).toBe(true)
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
it("rejects unknown tag", () => {
|
|
154
|
-
const result = Schema.decodeUnknownEither(InlineNode)({
|
|
155
|
-
_tag: "Unknown",
|
|
156
|
-
value: "test"
|
|
157
|
-
})
|
|
158
|
-
expect(Either.isLeft(result)).toBe(true)
|
|
159
|
-
})
|
|
160
|
-
})
|
|
161
|
-
})
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
<ac:layout><ac:layout-section ac:type="fixed-width" ac:breakout-mode="default"><ac:layout-cell><table><thead><tr><th /><th /></tr></thead><tbody><tr><td>Owner</td><td><ac:link><ri:user ri:account-id="557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b" /></ac:link></td></tr><tr><td>On this page</td><td><ac:structured-macro ac:name="toc" ac:schema-version="1" ac:macro-id="d452bad4-700f-4973-ae06-574776a14687" /></td></tr></tbody></table>
|
|
2
|
-
<p>Normal text</p>
|
|
3
|
-
<h2>Headings</h2>
|
|
4
|
-
<h1>Heading 1</h1>
|
|
5
|
-
<h2>Heading 2</h2>
|
|
6
|
-
<h3>Heading 3</h3>
|
|
7
|
-
<h4>Heading 4</h4>
|
|
8
|
-
<h5>Heading 5</h5>
|
|
9
|
-
<h6>Heading 6</h6>
|
|
10
|
-
<h2>Text Formatting</h2>
|
|
11
|
-
<h3>Basic Styles</h3>
|
|
12
|
-
<p><strong>Bold</strong></p>
|
|
13
|
-
<p><em>Italic</em></p>
|
|
14
|
-
<p><u>Inderline</u></p>
|
|
15
|
-
<p><del>Strikethrough</del></p>
|
|
16
|
-
<p><code>Code</code></p>
|
|
17
|
-
<p><sub>Subscript</sub></p>
|
|
18
|
-
<p><sup>Superscript</sup></p>
|
|
19
|
-
<h3>Quotes</h3>
|
|
20
|
-
<blockquote><p>Quote</p></blockquote>
|
|
21
|
-
<h3>Alignment</h3>
|
|
22
|
-
<p style="text-align: center;">Align center</p>
|
|
23
|
-
<p style="text-align: right;">Align right</p>
|
|
24
|
-
<p>Default</p>
|
|
25
|
-
<h2>Colors</h2>
|
|
26
|
-
<h3>Text Colors</h3>
|
|
27
|
-
<p><span style="color: rgb(151,160,175);">Gray</span></p>
|
|
28
|
-
<p><span style="color: rgb(255,255,255);">White</span></p>
|
|
29
|
-
<p><span style="color: rgb(7,71,166);">Bold blue</span></p>
|
|
30
|
-
<p><span style="color: rgb(76,154,255);">Blue</span></p>
|
|
31
|
-
<p><span style="color: rgb(179,212,255);">Subtle blue</span></p>
|
|
32
|
-
<p><span style="color: rgb(0,141,166);">Bold teal</span></p>
|
|
33
|
-
<p><span style="color: rgb(0,184,217);">Teal</span></p>
|
|
34
|
-
<p><span style="color: rgb(179,245,255);">Subtle blue</span></p>
|
|
35
|
-
<p><span style="color: rgb(0,102,68);">Bold green</span></p>
|
|
36
|
-
<p><span style="color: rgb(54,179,126);">Green</span></p>
|
|
37
|
-
<p><span style="color: rgb(171,245,209);">Subtle green</span></p>
|
|
38
|
-
<p><span style="color: rgb(255,153,31);">Bold orange</span></p>
|
|
39
|
-
<p><span style="color: rgb(255,196,0);">Yellow</span></p>
|
|
40
|
-
<p><span style="color: rgb(255,240,179);">Subtle yellow</span></p>
|
|
41
|
-
<p><span style="color: rgb(191,38,0);">Bold red</span></p>
|
|
42
|
-
<p><span style="color: rgb(255,86,48);">Red</span></p>
|
|
43
|
-
<p><span style="color: rgb(255,189,173);">Subtle red</span></p>
|
|
44
|
-
<p><span style="color: rgb(64,50,148);">Bold purple</span></p>
|
|
45
|
-
<p><span style="color: rgb(101,84,192);">Purple</span></p>
|
|
46
|
-
<p><span style="color: rgb(234,230,255);">Subtle purple</span></p>
|
|
47
|
-
<h3>Highlights</h3>
|
|
48
|
-
<p><span style="background-color: rgb(220,223,228);">Gray highlight</span></p>
|
|
49
|
-
<p><span style="background-color: rgb(198,237,251);">Teal highlight</span></p>
|
|
50
|
-
<p><span style="background-color: rgb(211,241,167);">Lime highlight</span></p>
|
|
51
|
-
<p><span style="background-color: rgb(254,222,200);">Yellow highlight</span></p>
|
|
52
|
-
<p><span style="background-color: rgb(253,208,236);">Magenta highlight</span></p>
|
|
53
|
-
<p><span style="background-color: rgb(223,216,253);">Purple highlight</span></p>
|
|
54
|
-
<h2>Lists</h2>
|
|
55
|
-
<h3>Bullet Lists</h3>
|
|
56
|
-
<ul><li><p>Bullet list 1</p><ul><li><p>Bullet list 1.1</p><ul><li><p>Bullet list 1.1.1</p></li></ul></li></ul></li><li><p>Bullet list 2</p></li></ul>
|
|
57
|
-
<h3>Numbered Lists</h3>
|
|
58
|
-
<ol><li><p>Numbered list 1</p><ol start="1"><li><p>Numbered list a</p><ol start="1"><li><p>Numbered list i</p></li></ol></li></ol></li><li><p>Numbered list 2</p></li></ol>
|
|
59
|
-
<h3>Indentation</h3>
|
|
60
|
-
<p style="margin-left: 30.0px;">Indent tab 1</p>
|
|
61
|
-
<p style="margin-left: 60.0px;">Indent tab 2</p>
|
|
62
|
-
<p style="margin-left: 90.0px;">Indent tab 3</p>
|
|
63
|
-
<h3>Action Items</h3>
|
|
64
|
-
<ac:task-list>
|
|
65
|
-
<ac:task><ac:task-id>11</ac:task-id><ac:task-uuid>bce1bc39-6cba-44f9-b1b3-6adf0634475a</ac:task-uuid><ac:task-status>incomplete</ac:task-status><ac:task-body><span class="placeholder-inline-tasks">Action Item unchecked</span></ac:task-body></ac:task>
|
|
66
|
-
<ac:task><ac:task-id>12</ac:task-id><ac:task-uuid>49c6a48e-cb41-4d98-ba45-64c1ecf96702</ac:task-uuid><ac:task-status>complete</ac:task-status><ac:task-body><span class="placeholder-inline-tasks">Action item checked</span></ac:task-body></ac:task>
|
|
67
|
-
</ac:task-list>
|
|
68
|
-
<h2>Links & Media</h2>
|
|
69
|
-
<h3>Links</h3>
|
|
70
|
-
<p><a href="http://example.com">External link</a></p>
|
|
71
|
-
<p><ac:link><ac:link-body>Confluence link</ac:link-body></ac:link></p>
|
|
72
|
-
<h3>Images</h3>
|
|
73
|
-
<ac:image ac:align="center" ac:width="238" ac:alt="Atlassian_Confluence_2017_logo.svg"><ri:attachment ri:filename="Atlassian_Confluence_2017_logo.svg" ri:version-at-save="1" /></ac:image>
|
|
74
|
-
<h3>User Mentions</h3>
|
|
75
|
-
<p><ac:link><ri:user ri:account-id="557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b" /></ac:link></p>
|
|
76
|
-
<h3>Emoticons</h3>
|
|
77
|
-
<p><ac:emoticon ac:emoji-shortname=":grinning:" ac:emoji-id="1f600" ac:emoji-fallback="😀" /> <ac:emoticon ac:emoji-shortname=":smiley:" ac:emoji-id="1f603" ac:emoji-fallback="😃" /> <ac:emoticon ac:emoji-shortname=":smile:" ac:emoji-id="1f604" ac:emoji-fallback="😄" /> <ac:emoticon ac:emoji-shortname=":grin:" ac:emoji-id="1f601" ac:emoji-fallback="😁" /> <ac:emoticon ac:emoji-shortname=":laughing:" ac:emoji-id="1f606" ac:emoji-fallback="😆" /> <ac:emoticon ac:emoji-shortname=":sweat_smile:" ac:emoji-id="1f605" ac:emoji-fallback="😅" /> <ac:emoticon ac:emoji-shortname=":joy:" ac:emoji-id="1f602" ac:emoji-fallback="😂" /> <ac:emoticon ac:emoji-shortname=":rofl:" ac:emoji-id="1f923" ac:emoji-fallback="🤣" /></p>
|
|
78
|
-
<h2>Tables</h2>
|
|
79
|
-
<table><thead><tr><th><strong>Header 1</strong></th><th><strong>Header 2</strong></th><th><strong>Header 3</strong></th></tr></thead><tbody><tr><td>Cell 1.1</td><td>Cell 2.1</td><td>Cell 3.1</td></tr><tr><td>Cell 1.2</td><td>Cell 2.2</td><td>Cell 3.2</td></tr></tbody></table></ac:layout-cell></ac:layout-section><ac:layout-section ac:type="two_equal" ac:breakout-mode="wide" ac:breakout-width="760"><ac:layout-cell><p>Column 1</p></ac:layout-cell><ac:layout-cell><p>Column 2</p></ac:layout-cell></ac:layout-section><ac:layout-section ac:type="fixed-width" ac:breakout-mode="default"><ac:layout-cell><h3>Code Blocks</h3>
|
|
80
|
-
<ac:structured-macro ac:name="code" ac:schema-version="1" ac:macro-id="84de7e03-e3b0-4884-aa7b-34cbfce6c1c1"><ac:parameter ac:name="language">typescript</ac:parameter><ac:plain-text-body><![CDATA[const typescript = {};]]></ac:plain-text-body></ac:structured-macro>
|
|
81
|
-
<ac:structured-macro ac:name="code" ac:schema-version="1" ac:macro-id="0d60fe56-c93c-4f6b-979b-3432c79db9ba"><ac:parameter ac:name="language">json</ac:parameter><ac:plain-text-body><![CDATA[{
|
|
82
|
-
"json": true
|
|
83
|
-
}]]></ac:plain-text-body></ac:structured-macro>
|
|
84
|
-
<h3>Decisions</h3>
|
|
85
|
-
<ac:adf-extension><ac:adf-node type="decision-list"><ac:adf-node type="decision-item"><ac:adf-attribute key="local-id">7c3012f5-3ad3-47e1-89cc-cd87267668d3</ac:adf-attribute><ac:adf-attribute key="state">DECIDED</ac:adf-attribute><ac:adf-content>Decision</ac:adf-content></ac:adf-node></ac:adf-node><ac:adf-fallback><ul class="decision-list"><li>Decision</li></ul></ac:adf-fallback></ac:adf-extension>
|
|
86
|
-
<hr />
|
|
87
|
-
<h3>Expand</h3>
|
|
88
|
-
<ac:structured-macro ac:name="expand" ac:schema-version="1" ac:macro-id="a1c56c2d-d8a1-4b83-8dbc-c1283a401cb8"><ac:parameter ac:name="title">Expand title</ac:parameter><ac:rich-text-body><p>Expand content</p></ac:rich-text-body></ac:structured-macro>
|
|
89
|
-
<h3>Dates</h3>
|
|
90
|
-
<p><time datetime="2026-01-01" /></p>
|
|
91
|
-
<h3>Status</h3>
|
|
92
|
-
<p><ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="ba0a4297-9ff9-4d44-bf69-3469663636f7"><ac:parameter ac:name="title">Gray</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="f220ee0c-735a-4613-bbb6-64b5f9952472"><ac:parameter ac:name="colour">Blue</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="71234fd5-5442-4557-a6de-ed762923d99d"><ac:parameter ac:name="colour">Green</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="72ac3007-9264-468e-b0f2-858465e5e9cd"><ac:parameter ac:name="colour">Yellow</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="27fafb59-40d9-44b9-979a-7b820ccc1ba6"><ac:parameter ac:name="colour">Red</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="cc376419-1aa0-4fc3-9378-4a9e0efc5a4e"><ac:parameter ac:name="colour">Purple</ac:parameter></ac:structured-macro></p>
|
|
93
|
-
<h3>Smart Links</h3>
|
|
94
|
-
<p><a href="https://knpkv-team.atlassian.net/issues/?jql=project%20in%20(LEARNJIRA)%20ORDER%20BY%20created%20DESC" data-card-appearance="block" data-datasource="{"id":"d8b75300-dfda-4519-b6cd-e49abbd50401","parameters":{"cloudId":"85fe2d49-d86f-4afa-be53-e7ec408a4d5e","jql":"project in (LEARNJIRA) ORDER BY created DESC"},"views":[{"type":"table","properties":{"columns":[{"key":"issuetype"},{"key":"key"},{"key":"summary"},{"key":"assignee"},{"key":"priority"},{"key":"status"},{"key":"updated"}]}}]}">https://knpkv-team.atlassian.net/issues/?jql=project%20in%20(LEARNJIRA)%20ORDER%20BY%20created%20DESC</a></p>
|
|
95
|
-
<p><a href="https://knpkv-team.atlassian.net/wiki/search?text=Getting+started" data-card-appearance="block" data-datasource="{"id":"768fc736-3af4-4a8f-b27e-203602bff8ca","parameters":{"cloudId":"85fe2d49-d86f-4afa-be53-e7ec408a4d5e","searchString":"Getting started"},"views":[{"type":"table","properties":{"columns":[{"key":"type"},{"key":"title"},{"key":"space","width":243},{"key":"description"},{"key":"ownedBy"},{"key":"updatedAt"}]}}]}">https://knpkv-team.atlassian.net/wiki/search?text=Getting+started</a></p>
|
|
96
|
-
<h3>Panels</h3>
|
|
97
|
-
<ac:structured-macro ac:name="info" ac:schema-version="1" ac:macro-id="5dccc7f1-ede2-43e6-926c-9c36fc4144ce"><ac:rich-text-body><p>Info panel</p></ac:rich-text-body></ac:structured-macro>
|
|
98
|
-
<ac:structured-macro ac:name="note" ac:schema-version="1" ac:macro-id="5884da9b-d738-45b3-9821-e8dc832e6601"><ac:rich-text-body><p>Note panel</p></ac:rich-text-body></ac:structured-macro>
|
|
99
|
-
<ac:structured-macro ac:name="warning" ac:schema-version="1" ac:macro-id="c1c28329-228c-42b7-8456-f2530f56f2c0"><ac:rich-text-body><p>Error panel</p></ac:rich-text-body></ac:structured-macro>
|
|
100
|
-
<ac:structured-macro ac:name="panel" ac:schema-version="1" ac:macro-id="fe489f67-fe69-4a52-bd26-9cc23eea815c"><ac:rich-text-body><p>Custom panel</p></ac:rich-text-body></ac:structured-macro>
|
|
101
|
-
<ac:structured-macro ac:name="tip" ac:schema-version="1" ac:macro-id="77ad7dce-d489-42a1-995d-0a1db3a9ef83"><ac:rich-text-body><p>Success panel</p></ac:rich-text-body></ac:structured-macro>
|
|
102
|
-
<ac:structured-macro ac:name="note" ac:schema-version="1" ac:macro-id="e5c6352e-cf6e-47cb-a423-a912838dcec4"><ac:rich-text-body><p>Warning panel</p></ac:rich-text-body></ac:structured-macro>
|
|
103
|
-
</ac:layout-cell></ac:layout-section></ac:layout>
|