@knpkv/confluence-to-markdown 0.2.0 → 0.4.1
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 +60 -0
- package/LICENSE +21 -0
- package/README.md +282 -14
- package/dist/ConfluenceAuth.d.ts +76 -0
- package/dist/ConfluenceAuth.d.ts.map +1 -0
- package/dist/ConfluenceAuth.js +356 -0
- package/dist/ConfluenceAuth.js.map +1 -0
- package/dist/ConfluenceClient.d.ts +26 -2
- package/dist/ConfluenceClient.d.ts.map +1 -1
- package/dist/ConfluenceClient.js +98 -92
- package/dist/ConfluenceClient.js.map +1 -1
- package/dist/ConfluenceConfig.d.ts +4 -24
- package/dist/ConfluenceConfig.d.ts.map +1 -1
- package/dist/ConfluenceConfig.js +45 -7
- package/dist/ConfluenceConfig.js.map +1 -1
- package/dist/ConfluenceError.d.ts +89 -6
- package/dist/ConfluenceError.d.ts.map +1 -1
- package/dist/ConfluenceError.js +88 -5
- package/dist/ConfluenceError.js.map +1 -1
- package/dist/GitError.d.ts +103 -0
- package/dist/GitError.d.ts.map +1 -0
- package/dist/GitError.js +85 -0
- package/dist/GitError.js.map +1 -0
- package/dist/GitService.d.ts +175 -0
- package/dist/GitService.d.ts.map +1 -0
- package/dist/GitService.js +431 -0
- package/dist/GitService.js.map +1 -0
- package/dist/LocalFileSystem.d.ts +29 -4
- package/dist/LocalFileSystem.d.ts.map +1 -1
- package/dist/LocalFileSystem.js +80 -6
- package/dist/LocalFileSystem.js.map +1 -1
- package/dist/MarkdownConverter.d.ts +49 -2
- package/dist/MarkdownConverter.d.ts.map +1 -1
- package/dist/MarkdownConverter.js +73 -111
- package/dist/MarkdownConverter.js.map +1 -1
- package/dist/SchemaConverterError.d.ts +108 -0
- package/dist/SchemaConverterError.d.ts.map +1 -0
- package/dist/SchemaConverterError.js +84 -0
- package/dist/SchemaConverterError.js.map +1 -0
- package/dist/Schemas.d.ts +225 -1
- package/dist/Schemas.d.ts.map +1 -1
- package/dist/Schemas.js +155 -6
- package/dist/Schemas.js.map +1 -1
- package/dist/SyncEngine.d.ts +30 -20
- package/dist/SyncEngine.d.ts.map +1 -1
- package/dist/SyncEngine.js +566 -117
- package/dist/SyncEngine.js.map +1 -1
- package/dist/ast/BlockNode.d.ts +468 -0
- package/dist/ast/BlockNode.d.ts.map +1 -0
- package/dist/ast/BlockNode.js +319 -0
- package/dist/ast/BlockNode.js.map +1 -0
- package/dist/ast/Document.d.ts +244 -0
- package/dist/ast/Document.d.ts.map +1 -0
- package/dist/ast/Document.js +69 -0
- package/dist/ast/Document.js.map +1 -0
- package/dist/ast/InlineNode.d.ts +477 -0
- package/dist/ast/InlineNode.d.ts.map +1 -0
- package/dist/ast/InlineNode.js +263 -0
- package/dist/ast/InlineNode.js.map +1 -0
- package/dist/ast/MacroNode.d.ts +267 -0
- package/dist/ast/MacroNode.d.ts.map +1 -0
- package/dist/ast/MacroNode.js +164 -0
- package/dist/ast/MacroNode.js.map +1 -0
- package/dist/ast/index.d.ts +10 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +14 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/bin.js +33 -149
- package/dist/bin.js.map +1 -1
- package/dist/commands/auth.d.ts +15 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +86 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/clone.d.ts +12 -0
- package/dist/commands/clone.d.ts.map +1 -0
- package/dist/commands/clone.js +93 -0
- package/dist/commands/clone.js.map +1 -0
- package/dist/commands/delete.d.ts +13 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +48 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/errorHandler.d.ts +14 -0
- package/dist/commands/errorHandler.d.ts.map +1 -0
- package/dist/commands/errorHandler.js +33 -0
- package/dist/commands/errorHandler.js.map +1 -0
- package/dist/commands/git.d.ts +22 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +72 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/index.d.ts +11 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +11 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/layers.d.ts +31 -0
- package/dist/commands/layers.d.ts.map +1 -0
- package/dist/commands/layers.js +137 -0
- package/dist/commands/layers.js.map +1 -0
- package/dist/commands/new.d.ts +9 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +80 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pageTree.d.ts +18 -0
- package/dist/commands/pageTree.d.ts.map +1 -0
- package/dist/commands/pageTree.js +20 -0
- package/dist/commands/pageTree.js.map +1 -0
- package/dist/commands/shared.d.ts +15 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +27 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/sync.d.ts +15 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +101 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/NodeLayers.d.ts +7 -0
- package/dist/internal/NodeLayers.d.ts.map +1 -0
- package/dist/internal/NodeLayers.js +19 -0
- package/dist/internal/NodeLayers.js.map +1 -0
- package/dist/internal/frontmatter.d.ts +10 -0
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +16 -0
- package/dist/internal/frontmatter.js.map +1 -1
- package/dist/internal/gitCommands.d.ts +78 -0
- package/dist/internal/gitCommands.d.ts.map +1 -0
- package/dist/internal/gitCommands.js +156 -0
- package/dist/internal/gitCommands.js.map +1 -0
- package/dist/internal/hashUtils.d.ts +42 -1
- package/dist/internal/hashUtils.d.ts.map +1 -1
- package/dist/internal/hashUtils.js +38 -2
- package/dist/internal/hashUtils.js.map +1 -1
- package/dist/internal/oauthServer.d.ts +55 -0
- package/dist/internal/oauthServer.d.ts.map +1 -0
- package/dist/internal/oauthServer.js +110 -0
- package/dist/internal/oauthServer.js.map +1 -0
- package/dist/internal/pathUtils.d.ts +21 -4
- package/dist/internal/pathUtils.d.ts.map +1 -1
- package/dist/internal/pathUtils.js +24 -13
- package/dist/internal/pathUtils.js.map +1 -1
- package/dist/internal/tokenStorage.d.ts +75 -0
- package/dist/internal/tokenStorage.d.ts.map +1 -0
- package/dist/internal/tokenStorage.js +149 -0
- package/dist/internal/tokenStorage.js.map +1 -0
- package/dist/internal/userCache.d.ts +42 -0
- package/dist/internal/userCache.d.ts.map +1 -0
- package/dist/internal/userCache.js +51 -0
- package/dist/internal/userCache.js.map +1 -0
- package/dist/parsers/ConfluenceParser.d.ts +26 -0
- package/dist/parsers/ConfluenceParser.d.ts.map +1 -0
- package/dist/parsers/ConfluenceParser.js +792 -0
- package/dist/parsers/ConfluenceParser.js.map +1 -0
- package/dist/parsers/MarkdownParser.d.ts +26 -0
- package/dist/parsers/MarkdownParser.d.ts.map +1 -0
- package/dist/parsers/MarkdownParser.js +873 -0
- package/dist/parsers/MarkdownParser.js.map +1 -0
- package/dist/parsers/index.d.ts +8 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +8 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/schemas/ConfluenceSchema.d.ts +21 -0
- package/dist/schemas/ConfluenceSchema.d.ts.map +1 -0
- package/dist/schemas/ConfluenceSchema.js +38 -0
- package/dist/schemas/ConfluenceSchema.js.map +1 -0
- package/dist/schemas/ConversionSchema.d.ts +35 -0
- package/dist/schemas/ConversionSchema.d.ts.map +1 -0
- package/dist/schemas/ConversionSchema.js +208 -0
- package/dist/schemas/ConversionSchema.js.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +21 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.js +38 -0
- package/dist/schemas/MarkdownSchema.js.map +1 -0
- package/dist/schemas/hast/HastFromHtml.d.ts +27 -0
- package/dist/schemas/hast/HastFromHtml.d.ts.map +1 -0
- package/dist/schemas/hast/HastFromHtml.js +107 -0
- package/dist/schemas/hast/HastFromHtml.js.map +1 -0
- package/dist/schemas/hast/HastSchema.d.ts +195 -0
- package/dist/schemas/hast/HastSchema.d.ts.map +1 -0
- package/dist/schemas/hast/HastSchema.js +183 -0
- package/dist/schemas/hast/HastSchema.js.map +1 -0
- package/dist/schemas/hast/index.d.ts +9 -0
- package/dist/schemas/hast/index.d.ts.map +1 -0
- package/dist/schemas/hast/index.js +3 -0
- package/dist/schemas/hast/index.js.map +1 -0
- package/dist/schemas/index.d.ts +14 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +16 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/mdast/MdastFromMarkdown.d.ts +30 -0
- package/dist/schemas/mdast/MdastFromMarkdown.d.ts.map +1 -0
- package/dist/schemas/mdast/MdastFromMarkdown.js +79 -0
- package/dist/schemas/mdast/MdastFromMarkdown.js.map +1 -0
- package/dist/schemas/mdast/MdastSchema.d.ts +385 -0
- package/dist/schemas/mdast/MdastSchema.d.ts.map +1 -0
- package/dist/schemas/mdast/MdastSchema.js +266 -0
- package/dist/schemas/mdast/MdastSchema.js.map +1 -0
- package/dist/schemas/mdast/index.d.ts +10 -0
- package/dist/schemas/mdast/index.d.ts.map +1 -0
- package/dist/schemas/mdast/index.js +4 -0
- package/dist/schemas/mdast/index.js.map +1 -0
- package/dist/schemas/mdast/mdastToString.d.ts +13 -0
- package/dist/schemas/mdast/mdastToString.d.ts.map +1 -0
- package/dist/schemas/mdast/mdastToString.js +85 -0
- package/dist/schemas/mdast/mdastToString.js.map +1 -0
- package/dist/schemas/nodes/block/BlockSchema.d.ts +43 -0
- package/dist/schemas/nodes/block/BlockSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/block/BlockSchema.js +634 -0
- package/dist/schemas/nodes/block/BlockSchema.js.map +1 -0
- package/dist/schemas/nodes/block/index.d.ts +7 -0
- package/dist/schemas/nodes/block/index.d.ts.map +1 -0
- package/dist/schemas/nodes/block/index.js +7 -0
- package/dist/schemas/nodes/block/index.js.map +1 -0
- package/dist/schemas/nodes/index.d.ts +9 -0
- package/dist/schemas/nodes/index.d.ts.map +1 -0
- package/dist/schemas/nodes/index.js +12 -0
- package/dist/schemas/nodes/index.js.map +1 -0
- package/dist/schemas/nodes/inline/InlineSchema.d.ts +48 -0
- package/dist/schemas/nodes/inline/InlineSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/inline/InlineSchema.js +436 -0
- package/dist/schemas/nodes/inline/InlineSchema.js.map +1 -0
- package/dist/schemas/nodes/inline/index.d.ts +7 -0
- package/dist/schemas/nodes/inline/index.d.ts.map +1 -0
- package/dist/schemas/nodes/inline/index.js +7 -0
- package/dist/schemas/nodes/inline/index.js.map +1 -0
- package/dist/schemas/nodes/macro/MacroSchema.d.ts +27 -0
- package/dist/schemas/nodes/macro/MacroSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/macro/MacroSchema.js +162 -0
- package/dist/schemas/nodes/macro/MacroSchema.js.map +1 -0
- package/dist/schemas/nodes/macro/index.d.ts +7 -0
- package/dist/schemas/nodes/macro/index.d.ts.map +1 -0
- package/dist/schemas/nodes/macro/index.js +7 -0
- package/dist/schemas/nodes/macro/index.js.map +1 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +24 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +1 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js +351 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +1 -0
- package/dist/schemas/preprocessing/index.d.ts +8 -0
- package/dist/schemas/preprocessing/index.d.ts.map +1 -0
- package/dist/schemas/preprocessing/index.js +2 -0
- package/dist/schemas/preprocessing/index.js.map +1 -0
- package/dist/serializers/ConfluenceSerializer.d.ts +30 -0
- package/dist/serializers/ConfluenceSerializer.d.ts.map +1 -0
- package/dist/serializers/ConfluenceSerializer.js +551 -0
- package/dist/serializers/ConfluenceSerializer.js.map +1 -0
- package/dist/serializers/MarkdownSerializer.d.ts +34 -0
- package/dist/serializers/MarkdownSerializer.d.ts.map +1 -0
- package/dist/serializers/MarkdownSerializer.js +355 -0
- package/dist/serializers/MarkdownSerializer.js.map +1 -0
- package/dist/serializers/index.d.ts +8 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/index.js +8 -0
- package/dist/serializers/index.js.map +1 -0
- package/package.json +27 -16
- package/src/ConfluenceAuth.ts +571 -0
- package/src/ConfluenceClient.ts +188 -156
- package/src/ConfluenceConfig.ts +63 -7
- package/src/ConfluenceError.ts +110 -14
- package/src/GitError.ts +92 -0
- package/src/GitService.ts +859 -0
- package/src/LocalFileSystem.ts +179 -9
- package/src/MarkdownConverter.ts +126 -122
- package/src/SchemaConverterError.ts +108 -0
- package/src/Schemas.ts +223 -6
- package/src/SyncEngine.ts +745 -162
- package/src/ast/BlockNode.ts +425 -0
- package/src/ast/Document.ts +90 -0
- package/src/ast/InlineNode.ts +323 -0
- package/src/ast/MacroNode.ts +245 -0
- package/src/ast/index.ts +83 -0
- package/src/bin.ts +50 -249
- package/src/commands/auth.ts +117 -0
- package/src/commands/clone.ts +145 -0
- package/src/commands/delete.ts +57 -0
- package/src/commands/errorHandler.ts +32 -0
- package/src/commands/git.ts +114 -0
- package/src/commands/index.ts +10 -0
- package/src/commands/layers.ts +211 -0
- package/src/commands/new.ts +99 -0
- package/src/commands/pageTree.ts +40 -0
- package/src/commands/shared.ts +35 -0
- package/src/commands/sync.ts +129 -0
- package/src/index.ts +21 -1
- package/src/internal/NodeLayers.ts +21 -0
- package/src/internal/frontmatter.ts +21 -0
- package/src/internal/gitCommands.ts +229 -0
- package/src/internal/hashUtils.ts +65 -3
- package/src/internal/oauthServer.ts +199 -0
- package/src/internal/pathUtils.ts +34 -17
- package/src/internal/tokenStorage.ts +240 -0
- package/src/internal/userCache.ts +90 -0
- package/src/parsers/ConfluenceParser.ts +950 -0
- package/src/parsers/MarkdownParser.ts +1198 -0
- package/src/parsers/index.ts +8 -0
- package/src/schemas/ConfluenceSchema.ts +56 -0
- package/src/schemas/ConversionSchema.ts +318 -0
- package/src/schemas/MarkdownSchema.ts +56 -0
- package/src/schemas/hast/HastFromHtml.ts +153 -0
- package/src/schemas/hast/HastSchema.ts +274 -0
- package/src/schemas/hast/index.ts +35 -0
- package/src/schemas/index.ts +20 -0
- package/src/schemas/mdast/MdastFromMarkdown.ts +118 -0
- package/src/schemas/mdast/MdastSchema.ts +566 -0
- package/src/schemas/mdast/index.ts +59 -0
- package/src/schemas/mdast/mdastToString.ts +102 -0
- package/src/schemas/nodes/block/BlockSchema.ts +773 -0
- package/src/schemas/nodes/block/index.ts +13 -0
- package/src/schemas/nodes/index.ts +20 -0
- package/src/schemas/nodes/inline/InlineSchema.ts +523 -0
- package/src/schemas/nodes/inline/index.ts +14 -0
- package/src/schemas/nodes/macro/MacroSchema.ts +226 -0
- package/src/schemas/nodes/macro/index.ts +6 -0
- package/src/schemas/preprocessing/ConfluencePreprocessor.ts +446 -0
- package/src/schemas/preprocessing/index.ts +8 -0
- package/src/serializers/ConfluenceSerializer.ts +717 -0
- package/src/serializers/MarkdownSerializer.ts +493 -0
- package/src/serializers/index.ts +8 -0
- package/test/GitService.test.ts +209 -0
- package/test/MarkdownConverter.test.ts +37 -3
- package/test/Schemas.test.ts +97 -2
- package/test/ast/BlockNode.test.ts +265 -0
- package/test/ast/Document.test.ts +126 -0
- package/test/ast/InlineNode.test.ts +161 -0
- package/test/fixtures/integration-test.html.fixture +103 -0
- package/test/fixtures/integration-test.md.expected +257 -0
- package/test/integration.test.ts +269 -0
- package/test/oauthServer.test.ts +50 -0
- package/test/parsers/ConfluenceParser.test.ts +283 -0
- package/test/schemas/ConfluencePreprocessor.test.ts +180 -0
- package/test/schemas/ConversionSchema.test.ts +159 -0
- package/test/schemas/HastSchema.test.ts +138 -0
- package/test/schemas/MdastSchema.test.ts +145 -0
- package/test/schemas/nodes/block/BlockSchema.test.ts +173 -0
- package/test/schemas/nodes/inline/InlineSchema.test.ts +198 -0
- package/test/schemas/nodes/macro/MacroSchema.test.ts +142 -0
- package/test/tokenStorage.test.ts +99 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
+
import type { UnsupportedBlock } from "../../../../src/ast/BlockNode.js"
|
|
3
|
+
import {
|
|
4
|
+
CodeBlock,
|
|
5
|
+
Heading,
|
|
6
|
+
Paragraph,
|
|
7
|
+
Table,
|
|
8
|
+
TableCell,
|
|
9
|
+
TableRow,
|
|
10
|
+
ThematicBreak
|
|
11
|
+
} from "../../../../src/ast/BlockNode.js"
|
|
12
|
+
import { Text } from "../../../../src/ast/InlineNode.js"
|
|
13
|
+
import { makeMdastHeading, makeMdastParagraph, makeMdastText } from "../../../../src/schemas/mdast/index.js"
|
|
14
|
+
import { blockNodeFromMdast, blockNodeToHast, blockNodeToMdast } from "../../../../src/schemas/nodes/block/index.js"
|
|
15
|
+
|
|
16
|
+
describe("BlockSchema", () => {
|
|
17
|
+
describe("blockNodeToHast", () => {
|
|
18
|
+
it("converts Heading to hast h element", () => {
|
|
19
|
+
const heading = new Heading({ level: 2, children: [new Text({ value: "Title" })] })
|
|
20
|
+
const result = blockNodeToHast(heading)
|
|
21
|
+
expect(result._tag).toBe("element")
|
|
22
|
+
expect(result.tagName).toBe("h2")
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it("converts Paragraph to hast p element", () => {
|
|
26
|
+
const para = new Paragraph({ children: [new Text({ value: "Hello" })] })
|
|
27
|
+
const result = blockNodeToHast(para)
|
|
28
|
+
expect(result._tag).toBe("element")
|
|
29
|
+
expect(result.tagName).toBe("p")
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("converts CodeBlock to hast pre/code elements", () => {
|
|
33
|
+
const code = new CodeBlock({ code: "const x = 1", language: "ts" })
|
|
34
|
+
const result = blockNodeToHast(code)
|
|
35
|
+
expect(result._tag).toBe("element")
|
|
36
|
+
expect(result.tagName).toBe("pre")
|
|
37
|
+
expect(result.properties?.dataLanguage).toBe("ts")
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("converts ThematicBreak to hast hr element", () => {
|
|
41
|
+
const hr = new ThematicBreak({})
|
|
42
|
+
const result = blockNodeToHast(hr)
|
|
43
|
+
expect(result._tag).toBe("element")
|
|
44
|
+
expect(result.tagName).toBe("hr")
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it("converts Table to hast table element", () => {
|
|
48
|
+
const table = new Table({
|
|
49
|
+
header: new TableRow({
|
|
50
|
+
cells: [new TableCell({ isHeader: true, children: [new Text({ value: "Col" })] })]
|
|
51
|
+
}),
|
|
52
|
+
rows: [
|
|
53
|
+
new TableRow({
|
|
54
|
+
cells: [new TableCell({ children: [new Text({ value: "Val" })] })]
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
})
|
|
58
|
+
const result = blockNodeToHast(table)
|
|
59
|
+
expect(result._tag).toBe("element")
|
|
60
|
+
expect(result.tagName).toBe("table")
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe("blockNodeToMdast", () => {
|
|
65
|
+
it("converts Heading to mdast heading", () => {
|
|
66
|
+
const heading = new Heading({ level: 1, children: [new Text({ value: "Title" })] })
|
|
67
|
+
const result = blockNodeToMdast(heading)
|
|
68
|
+
expect(result.type).toBe("heading")
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it("converts Paragraph to mdast paragraph", () => {
|
|
72
|
+
const para = new Paragraph({ children: [new Text({ value: "Hello" })] })
|
|
73
|
+
const result = blockNodeToMdast(para)
|
|
74
|
+
expect(result.type).toBe("paragraph")
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it("converts CodeBlock to mdast code", () => {
|
|
78
|
+
const code = new CodeBlock({ code: "const x = 1", language: "ts" })
|
|
79
|
+
const result = blockNodeToMdast(code)
|
|
80
|
+
expect(result.type).toBe("code")
|
|
81
|
+
expect((result as { value: string }).value).toBe("const x = 1")
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it("converts ThematicBreak to mdast thematicBreak", () => {
|
|
85
|
+
const hr = new ThematicBreak({})
|
|
86
|
+
const result = blockNodeToMdast(hr)
|
|
87
|
+
expect(result.type).toBe("thematicBreak")
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it("converts Table to mdast table", () => {
|
|
91
|
+
const table = new Table({ rows: [] })
|
|
92
|
+
const result = blockNodeToMdast(table)
|
|
93
|
+
expect(result.type).toBe("table")
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe("blockNodeFromMdast", () => {
|
|
98
|
+
it("converts mdast heading to Heading", () => {
|
|
99
|
+
const mdast = makeMdastHeading(2, [makeMdastText("Title")])
|
|
100
|
+
const result = blockNodeFromMdast(mdast)
|
|
101
|
+
expect(result._tag).toBe("Heading")
|
|
102
|
+
expect((result as Heading).level).toBe(2)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it("converts mdast paragraph to Paragraph", () => {
|
|
106
|
+
const mdast = makeMdastParagraph([makeMdastText("Hello")])
|
|
107
|
+
const result = blockNodeFromMdast(mdast)
|
|
108
|
+
expect(result._tag).toBe("Paragraph")
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it("converts mdast code to CodeBlock", () => {
|
|
112
|
+
const mdast = { type: "code" as const, value: "const x = 1", lang: "ts" }
|
|
113
|
+
const result = blockNodeFromMdast(mdast)
|
|
114
|
+
expect(result._tag).toBe("CodeBlock")
|
|
115
|
+
expect((result as CodeBlock).code).toBe("const x = 1")
|
|
116
|
+
expect((result as CodeBlock).language).toBe("ts")
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it("converts mdast thematicBreak to ThematicBreak", () => {
|
|
120
|
+
const mdast = { type: "thematicBreak" as const }
|
|
121
|
+
const result = blockNodeFromMdast(mdast)
|
|
122
|
+
expect(result._tag).toBe("ThematicBreak")
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it("converts mdast blockquote to BlockQuote", () => {
|
|
126
|
+
const mdast = {
|
|
127
|
+
type: "blockquote" as const,
|
|
128
|
+
children: [makeMdastParagraph([makeMdastText("Quote")])]
|
|
129
|
+
}
|
|
130
|
+
const result = blockNodeFromMdast(mdast)
|
|
131
|
+
expect(result._tag).toBe("BlockQuote")
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it("converts mdast list to List", () => {
|
|
135
|
+
const mdast = {
|
|
136
|
+
type: "list" as const,
|
|
137
|
+
ordered: true,
|
|
138
|
+
children: [{
|
|
139
|
+
type: "listItem" as const,
|
|
140
|
+
children: [makeMdastParagraph([makeMdastText("Item")])]
|
|
141
|
+
}]
|
|
142
|
+
}
|
|
143
|
+
const result = blockNodeFromMdast(mdast)
|
|
144
|
+
expect(result._tag).toBe("List")
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it("converts mdast html to UnsupportedBlock", () => {
|
|
148
|
+
const mdast = { type: "html" as const, value: "<custom>x</custom>" }
|
|
149
|
+
const result = blockNodeFromMdast(mdast)
|
|
150
|
+
expect(result._tag).toBe("UnsupportedBlock")
|
|
151
|
+
expect((result as UnsupportedBlock).rawMarkdown).toBe("<custom>x</custom>")
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe("roundtrip", () => {
|
|
156
|
+
it("Heading roundtrips through MDAST", () => {
|
|
157
|
+
const original = new Heading({ level: 3, children: [new Text({ value: "Title" })] })
|
|
158
|
+
const mdast = blockNodeToMdast(original)
|
|
159
|
+
const result = blockNodeFromMdast(mdast)
|
|
160
|
+
expect(result._tag).toBe("Heading")
|
|
161
|
+
expect((result as Heading).level).toBe(3)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it("CodeBlock roundtrips through MDAST", () => {
|
|
165
|
+
const original = new CodeBlock({ code: "x = 1", language: "py" })
|
|
166
|
+
const mdast = blockNodeToMdast(original)
|
|
167
|
+
const result = blockNodeFromMdast(mdast)
|
|
168
|
+
expect(result._tag).toBe("CodeBlock")
|
|
169
|
+
expect((result as CodeBlock).code).toBe("x = 1")
|
|
170
|
+
expect((result as CodeBlock).language).toBe("py")
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
})
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
+
import type { UnsupportedInline } from "../../../../src/ast/InlineNode.js"
|
|
3
|
+
import { Emphasis, InlineCode, LineBreak, Link, Strong, Text } from "../../../../src/ast/InlineNode.js"
|
|
4
|
+
import { makeHastText } from "../../../../src/schemas/hast/index.js"
|
|
5
|
+
import { makeMdastText } from "../../../../src/schemas/mdast/index.js"
|
|
6
|
+
import {
|
|
7
|
+
inlineNodeFromMdast,
|
|
8
|
+
inlineNodeToHast,
|
|
9
|
+
inlineNodeToMdast,
|
|
10
|
+
textFromHastText
|
|
11
|
+
} from "../../../../src/schemas/nodes/inline/index.js"
|
|
12
|
+
|
|
13
|
+
describe("InlineSchema", () => {
|
|
14
|
+
describe("textFromHastText", () => {
|
|
15
|
+
it("converts hast text to Text node", () => {
|
|
16
|
+
const hastText = makeHastText("hello")
|
|
17
|
+
const result = textFromHastText(hastText)
|
|
18
|
+
expect(result._tag).toBe("Text")
|
|
19
|
+
expect(result.value).toBe("hello")
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
describe("inlineNodeToHast", () => {
|
|
24
|
+
it("converts Text to hast text", () => {
|
|
25
|
+
const text = new Text({ value: "hello" })
|
|
26
|
+
const result = inlineNodeToHast(text)
|
|
27
|
+
expect(result._tag).toBe("text")
|
|
28
|
+
expect((result as { value: string }).value).toBe("hello")
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it("converts Strong to hast strong", () => {
|
|
32
|
+
const strong = new Strong({ children: [new Text({ value: "bold" })] })
|
|
33
|
+
const result = inlineNodeToHast(strong)
|
|
34
|
+
expect(result._tag).toBe("element")
|
|
35
|
+
expect((result as { tagName: string }).tagName).toBe("strong")
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it("converts Emphasis to hast em", () => {
|
|
39
|
+
const emphasis = new Emphasis({ children: [new Text({ value: "italic" })] })
|
|
40
|
+
const result = inlineNodeToHast(emphasis)
|
|
41
|
+
expect(result._tag).toBe("element")
|
|
42
|
+
expect((result as { tagName: string }).tagName).toBe("em")
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("converts InlineCode to hast code", () => {
|
|
46
|
+
const code = new InlineCode({ value: "const x = 1" })
|
|
47
|
+
const result = inlineNodeToHast(code)
|
|
48
|
+
expect(result._tag).toBe("element")
|
|
49
|
+
expect((result as { tagName: string }).tagName).toBe("code")
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("converts Link to hast anchor", () => {
|
|
53
|
+
const link = new Link({
|
|
54
|
+
href: "https://example.com",
|
|
55
|
+
title: "Example",
|
|
56
|
+
children: [new Text({ value: "click" })]
|
|
57
|
+
})
|
|
58
|
+
const result = inlineNodeToHast(link)
|
|
59
|
+
expect(result._tag).toBe("element")
|
|
60
|
+
expect((result as { tagName: string }).tagName).toBe("a")
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it("converts LineBreak to hast br", () => {
|
|
64
|
+
const br = new LineBreak({})
|
|
65
|
+
const result = inlineNodeToHast(br)
|
|
66
|
+
expect(result._tag).toBe("element")
|
|
67
|
+
expect((result as { tagName: string }).tagName).toBe("br")
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe("inlineNodeToMdast", () => {
|
|
72
|
+
it("converts Text to mdast text", () => {
|
|
73
|
+
const text = new Text({ value: "hello" })
|
|
74
|
+
const result = inlineNodeToMdast(text)
|
|
75
|
+
expect(result.type).toBe("text")
|
|
76
|
+
expect((result as { value: string }).value).toBe("hello")
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("converts Strong to mdast strong", () => {
|
|
80
|
+
const strong = new Strong({ children: [new Text({ value: "bold" })] })
|
|
81
|
+
const result = inlineNodeToMdast(strong)
|
|
82
|
+
expect(result.type).toBe("strong")
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it("converts Emphasis to mdast emphasis", () => {
|
|
86
|
+
const emphasis = new Emphasis({ children: [new Text({ value: "italic" })] })
|
|
87
|
+
const result = inlineNodeToMdast(emphasis)
|
|
88
|
+
expect(result.type).toBe("emphasis")
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it("converts InlineCode to mdast inlineCode", () => {
|
|
92
|
+
const code = new InlineCode({ value: "x" })
|
|
93
|
+
const result = inlineNodeToMdast(code)
|
|
94
|
+
expect(result.type).toBe("inlineCode")
|
|
95
|
+
expect((result as { value: string }).value).toBe("x")
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it("converts Link to mdast link", () => {
|
|
99
|
+
const link = new Link({
|
|
100
|
+
href: "https://example.com",
|
|
101
|
+
children: [new Text({ value: "click" })]
|
|
102
|
+
})
|
|
103
|
+
const result = inlineNodeToMdast(link)
|
|
104
|
+
expect(result.type).toBe("link")
|
|
105
|
+
expect((result as { url: string }).url).toBe("https://example.com")
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it("converts LineBreak to mdast break", () => {
|
|
109
|
+
const br = new LineBreak({})
|
|
110
|
+
const result = inlineNodeToMdast(br)
|
|
111
|
+
expect(result.type).toBe("break")
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe("inlineNodeFromMdast", () => {
|
|
116
|
+
it("converts mdast text to Text", () => {
|
|
117
|
+
const mdast = makeMdastText("hello")
|
|
118
|
+
const result = inlineNodeFromMdast(mdast)
|
|
119
|
+
expect(result._tag).toBe("Text")
|
|
120
|
+
expect((result as Text).value).toBe("hello")
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("converts mdast strong to Strong", () => {
|
|
124
|
+
const mdast = { type: "strong" as const, children: [makeMdastText("bold")] }
|
|
125
|
+
const result = inlineNodeFromMdast(mdast)
|
|
126
|
+
expect(result._tag).toBe("Strong")
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it("converts mdast emphasis to Emphasis", () => {
|
|
130
|
+
const mdast = { type: "emphasis" as const, children: [makeMdastText("italic")] }
|
|
131
|
+
const result = inlineNodeFromMdast(mdast)
|
|
132
|
+
expect(result._tag).toBe("Emphasis")
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it("converts mdast inlineCode to InlineCode", () => {
|
|
136
|
+
const mdast = { type: "inlineCode" as const, value: "x" }
|
|
137
|
+
const result = inlineNodeFromMdast(mdast)
|
|
138
|
+
expect(result._tag).toBe("InlineCode")
|
|
139
|
+
expect((result as InlineCode).value).toBe("x")
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it("converts mdast link to Link", () => {
|
|
143
|
+
const mdast = {
|
|
144
|
+
type: "link" as const,
|
|
145
|
+
url: "https://example.com",
|
|
146
|
+
title: null,
|
|
147
|
+
children: [makeMdastText("click")]
|
|
148
|
+
}
|
|
149
|
+
const result = inlineNodeFromMdast(mdast)
|
|
150
|
+
expect(result._tag).toBe("Link")
|
|
151
|
+
expect((result as Link).href).toBe("https://example.com")
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it("converts mdast break to LineBreak", () => {
|
|
155
|
+
const mdast = { type: "break" as const }
|
|
156
|
+
const result = inlineNodeFromMdast(mdast)
|
|
157
|
+
expect(result._tag).toBe("LineBreak")
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it("converts mdast delete to Strikethrough", () => {
|
|
161
|
+
const mdast = { type: "delete" as const, children: [makeMdastText("deleted")] }
|
|
162
|
+
const result = inlineNodeFromMdast(mdast)
|
|
163
|
+
expect(result._tag).toBe("Strikethrough")
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it("converts mdast html to UnsupportedInline", () => {
|
|
167
|
+
const mdast = { type: "html" as const, value: "<custom>x</custom>" }
|
|
168
|
+
const result = inlineNodeFromMdast(mdast)
|
|
169
|
+
expect(result._tag).toBe("UnsupportedInline")
|
|
170
|
+
expect((result as UnsupportedInline).raw).toBe("<custom>x</custom>")
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
describe("roundtrip", () => {
|
|
175
|
+
it("Text roundtrips through MDAST", () => {
|
|
176
|
+
const original = new Text({ value: "hello" })
|
|
177
|
+
const mdast = inlineNodeToMdast(original)
|
|
178
|
+
const result = inlineNodeFromMdast(mdast)
|
|
179
|
+
expect(result._tag).toBe("Text")
|
|
180
|
+
expect((result as Text).value).toBe("hello")
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
it("Strong roundtrips through MDAST", () => {
|
|
184
|
+
const original = new Strong({ children: [new Text({ value: "bold" })] })
|
|
185
|
+
const mdast = inlineNodeToMdast(original)
|
|
186
|
+
const result = inlineNodeFromMdast(mdast)
|
|
187
|
+
expect(result._tag).toBe("Strong")
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it("Text roundtrips through HAST", () => {
|
|
191
|
+
const original = new Text({ value: "hello" })
|
|
192
|
+
const hast = inlineNodeToHast(original)
|
|
193
|
+
const result = textFromHastText(hast as { _tag: "text"; value: string })
|
|
194
|
+
expect(result._tag).toBe("Text")
|
|
195
|
+
expect(result.value).toBe("hello")
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
})
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
+
import { Paragraph } from "../../../../src/ast/BlockNode.js"
|
|
3
|
+
import { Text } from "../../../../src/ast/InlineNode.js"
|
|
4
|
+
import type { CodeMacro, ExpandMacro, InfoPanel, StatusMacro, TocMacro } from "../../../../src/ast/MacroNode.js"
|
|
5
|
+
import { macroNodeToHast, macroNodeToMdast } from "../../../../src/schemas/nodes/macro/index.js"
|
|
6
|
+
|
|
7
|
+
describe("MacroSchema", () => {
|
|
8
|
+
describe("macroNodeToHast", () => {
|
|
9
|
+
it("converts InfoPanel to hast div with data attributes", () => {
|
|
10
|
+
const panel: InfoPanel = {
|
|
11
|
+
_tag: "InfoPanel",
|
|
12
|
+
version: 1,
|
|
13
|
+
panelType: "warning",
|
|
14
|
+
title: "Important",
|
|
15
|
+
children: [new Paragraph({ children: [new Text({ value: "Content" })] })]
|
|
16
|
+
}
|
|
17
|
+
const result = macroNodeToHast(panel)
|
|
18
|
+
expect(result._tag).toBe("element")
|
|
19
|
+
expect(result.tagName).toBe("div")
|
|
20
|
+
expect(result.properties?.dataMacro).toBe("warning")
|
|
21
|
+
expect(result.properties?.dataTitle).toBe("Important")
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it("converts ExpandMacro to hast details element", () => {
|
|
25
|
+
const expand: ExpandMacro = {
|
|
26
|
+
_tag: "ExpandMacro",
|
|
27
|
+
version: 1,
|
|
28
|
+
title: "Click to expand",
|
|
29
|
+
children: [new Paragraph({ children: [new Text({ value: "Hidden" })] })]
|
|
30
|
+
}
|
|
31
|
+
const result = macroNodeToHast(expand)
|
|
32
|
+
expect(result._tag).toBe("element")
|
|
33
|
+
expect(result.tagName).toBe("details")
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("converts TocMacro to hast nav element", () => {
|
|
37
|
+
const toc: TocMacro = {
|
|
38
|
+
_tag: "TocMacro",
|
|
39
|
+
version: 1,
|
|
40
|
+
minLevel: 2,
|
|
41
|
+
maxLevel: 4
|
|
42
|
+
}
|
|
43
|
+
const result = macroNodeToHast(toc)
|
|
44
|
+
expect(result._tag).toBe("element")
|
|
45
|
+
expect(result.tagName).toBe("nav")
|
|
46
|
+
expect(result.properties?.dataMacro).toBe("toc")
|
|
47
|
+
expect(result.properties?.dataMin).toBe("2")
|
|
48
|
+
expect(result.properties?.dataMax).toBe("4")
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it("converts CodeMacro to hast pre/code elements", () => {
|
|
52
|
+
const code: CodeMacro = {
|
|
53
|
+
_tag: "CodeMacro",
|
|
54
|
+
version: 1,
|
|
55
|
+
language: "typescript",
|
|
56
|
+
code: "const x = 1",
|
|
57
|
+
lineNumbers: false,
|
|
58
|
+
collapse: false
|
|
59
|
+
}
|
|
60
|
+
const result = macroNodeToHast(code)
|
|
61
|
+
expect(result._tag).toBe("element")
|
|
62
|
+
expect(result.tagName).toBe("pre")
|
|
63
|
+
expect(result.properties?.dataLanguage).toBe("typescript")
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("converts StatusMacro to hast span element", () => {
|
|
67
|
+
const status: StatusMacro = {
|
|
68
|
+
_tag: "StatusMacro",
|
|
69
|
+
version: 1,
|
|
70
|
+
text: "Done",
|
|
71
|
+
color: "Green"
|
|
72
|
+
}
|
|
73
|
+
const result = macroNodeToHast(status)
|
|
74
|
+
expect(result._tag).toBe("element")
|
|
75
|
+
expect(result.tagName).toBe("span")
|
|
76
|
+
expect(result.properties?.dataMacro).toBe("status")
|
|
77
|
+
expect(result.properties?.dataColor).toBe("Green")
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
describe("macroNodeToMdast", () => {
|
|
82
|
+
it("converts InfoPanel to mdast html with container syntax", () => {
|
|
83
|
+
const panel: InfoPanel = {
|
|
84
|
+
_tag: "InfoPanel",
|
|
85
|
+
version: 1,
|
|
86
|
+
panelType: "info",
|
|
87
|
+
children: [new Paragraph({ children: [new Text({ value: "Note content" })] })]
|
|
88
|
+
}
|
|
89
|
+
const result = macroNodeToMdast(panel)
|
|
90
|
+
expect(result.type).toBe("html")
|
|
91
|
+
expect((result as { value: string }).value).toContain(":::info")
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it("converts ExpandMacro to mdast html with details element", () => {
|
|
95
|
+
const expand: ExpandMacro = {
|
|
96
|
+
_tag: "ExpandMacro",
|
|
97
|
+
version: 1,
|
|
98
|
+
title: "More info",
|
|
99
|
+
children: []
|
|
100
|
+
}
|
|
101
|
+
const result = macroNodeToMdast(expand)
|
|
102
|
+
expect(result.type).toBe("html")
|
|
103
|
+
expect((result as { value: string }).value).toContain("<details>")
|
|
104
|
+
expect((result as { value: string }).value).toContain("More info")
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it("converts TocMacro to mdast html with toc marker", () => {
|
|
108
|
+
const toc: TocMacro = {
|
|
109
|
+
_tag: "TocMacro",
|
|
110
|
+
version: 1
|
|
111
|
+
}
|
|
112
|
+
const result = macroNodeToMdast(toc)
|
|
113
|
+
expect(result.type).toBe("html")
|
|
114
|
+
expect((result as { value: string }).value).toBe("[[toc]]")
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it("converts CodeMacro to mdast code", () => {
|
|
118
|
+
const code: CodeMacro = {
|
|
119
|
+
_tag: "CodeMacro",
|
|
120
|
+
version: 1,
|
|
121
|
+
language: "py",
|
|
122
|
+
code: "print(1)",
|
|
123
|
+
lineNumbers: false,
|
|
124
|
+
collapse: false
|
|
125
|
+
}
|
|
126
|
+
const result = macroNodeToMdast(code)
|
|
127
|
+
expect(result.type).toBe("code")
|
|
128
|
+
expect((result as { value: string }).value).toBe("print(1)")
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it("converts StatusMacro to mdast paragraph with badge text", () => {
|
|
132
|
+
const status: StatusMacro = {
|
|
133
|
+
_tag: "StatusMacro",
|
|
134
|
+
version: 1,
|
|
135
|
+
text: "In Progress",
|
|
136
|
+
color: "Blue"
|
|
137
|
+
}
|
|
138
|
+
const result = macroNodeToMdast(status)
|
|
139
|
+
expect(result.type).toBe("paragraph")
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { describe, expect, it } from "@effect/vitest"
|
|
2
|
+
import * as Either from "effect/Either"
|
|
3
|
+
import * as Schema from "effect/Schema"
|
|
4
|
+
import { OAuthConfigSchema, OAuthTokenSchema } from "../src/Schemas.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tests for OAuth schema validation used by tokenStorage.
|
|
8
|
+
* Full integration tests for file operations would require mocking the filesystem.
|
|
9
|
+
*/
|
|
10
|
+
describe("tokenStorage schemas", () => {
|
|
11
|
+
describe("OAuthTokenSchema", () => {
|
|
12
|
+
it("validates complete token", () => {
|
|
13
|
+
const token = {
|
|
14
|
+
access_token: "test_access_token",
|
|
15
|
+
refresh_token: "test_refresh_token",
|
|
16
|
+
expires_at: Date.now() + 3600000,
|
|
17
|
+
scope: "read:confluence-content.all",
|
|
18
|
+
cloud_id: "test_cloud_id",
|
|
19
|
+
site_url: "https://test.atlassian.net"
|
|
20
|
+
}
|
|
21
|
+
const result = Schema.decodeUnknownEither(OAuthTokenSchema)(token)
|
|
22
|
+
expect(Either.isRight(result)).toBe(true)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it("validates token with user info", () => {
|
|
26
|
+
const token = {
|
|
27
|
+
access_token: "test_access_token",
|
|
28
|
+
refresh_token: "test_refresh_token",
|
|
29
|
+
expires_at: Date.now() + 3600000,
|
|
30
|
+
scope: "read:confluence-content.all",
|
|
31
|
+
cloud_id: "test_cloud_id",
|
|
32
|
+
site_url: "https://test.atlassian.net",
|
|
33
|
+
user: {
|
|
34
|
+
account_id: "user123",
|
|
35
|
+
name: "Test User",
|
|
36
|
+
email: "test@example.com"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const result = Schema.decodeUnknownEither(OAuthTokenSchema)(token)
|
|
40
|
+
expect(Either.isRight(result)).toBe(true)
|
|
41
|
+
if (Either.isRight(result)) {
|
|
42
|
+
expect(result.right.user?.name).toBe("Test User")
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it("rejects token missing required field", () => {
|
|
47
|
+
const token = {
|
|
48
|
+
access_token: "test",
|
|
49
|
+
// missing refresh_token
|
|
50
|
+
expires_at: Date.now(),
|
|
51
|
+
scope: "test",
|
|
52
|
+
cloud_id: "test",
|
|
53
|
+
site_url: "https://test.atlassian.net"
|
|
54
|
+
}
|
|
55
|
+
const result = Schema.decodeUnknownEither(OAuthTokenSchema)(token)
|
|
56
|
+
expect(Either.isLeft(result)).toBe(true)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it("rejects token with invalid expires_at type", () => {
|
|
60
|
+
const token = {
|
|
61
|
+
access_token: "test",
|
|
62
|
+
refresh_token: "test",
|
|
63
|
+
expires_at: "not a number",
|
|
64
|
+
scope: "test",
|
|
65
|
+
cloud_id: "test",
|
|
66
|
+
site_url: "https://test.atlassian.net"
|
|
67
|
+
}
|
|
68
|
+
const result = Schema.decodeUnknownEither(OAuthTokenSchema)(token)
|
|
69
|
+
expect(Either.isLeft(result)).toBe(true)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe("OAuthConfigSchema", () => {
|
|
74
|
+
it("validates complete config", () => {
|
|
75
|
+
const config = {
|
|
76
|
+
clientId: "test_client_id",
|
|
77
|
+
clientSecret: "test_client_secret"
|
|
78
|
+
}
|
|
79
|
+
const result = Schema.decodeUnknownEither(OAuthConfigSchema)(config)
|
|
80
|
+
expect(Either.isRight(result)).toBe(true)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it("rejects config missing clientSecret", () => {
|
|
84
|
+
const config = {
|
|
85
|
+
clientId: "test_client_id"
|
|
86
|
+
}
|
|
87
|
+
const result = Schema.decodeUnknownEither(OAuthConfigSchema)(config)
|
|
88
|
+
expect(Either.isLeft(result)).toBe(true)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it("rejects config missing clientId", () => {
|
|
92
|
+
const config = {
|
|
93
|
+
clientSecret: "test_client_secret"
|
|
94
|
+
}
|
|
95
|
+
const result = Schema.decodeUnknownEither(OAuthConfigSchema)(config)
|
|
96
|
+
expect(Either.isLeft(result)).toBe(true)
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
})
|