@knpkv/confluence-to-markdown 0.2.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -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 +366 -0
- package/dist/ConfluenceAuth.js.map +1 -0
- package/dist/ConfluenceClient.d.ts +26 -12
- package/dist/ConfluenceClient.d.ts.map +1 -1
- package/dist/ConfluenceClient.js +139 -97
- 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 +99 -16
- 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 +32 -21
- package/src/ConfluenceAuth.ts +581 -0
- package/src/ConfluenceClient.ts +230 -165
- 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
|
@@ -11,7 +11,7 @@ import * as Layer from "effect/Layer";
|
|
|
11
11
|
import type { ContentHash } from "./Brand.js";
|
|
12
12
|
import type { FrontMatterError } from "./ConfluenceError.js";
|
|
13
13
|
import { FileSystemError } from "./ConfluenceError.js";
|
|
14
|
-
import type { PageFrontMatter } from "./Schemas.js";
|
|
14
|
+
import type { NewPageFrontMatter, PageFrontMatter } from "./Schemas.js";
|
|
15
15
|
/**
|
|
16
16
|
* Local markdown file representation.
|
|
17
17
|
*/
|
|
@@ -22,6 +22,19 @@ export interface LocalFile {
|
|
|
22
22
|
readonly contentHash: ContentHash;
|
|
23
23
|
readonly isNew: boolean;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Page tree node for directory structure.
|
|
27
|
+
*/
|
|
28
|
+
export interface PageTreeNode {
|
|
29
|
+
/** File path relative to docsPath */
|
|
30
|
+
readonly path: string;
|
|
31
|
+
/** Page title */
|
|
32
|
+
readonly title: string;
|
|
33
|
+
/** Page ID (null if new page) */
|
|
34
|
+
readonly pageId: string | null;
|
|
35
|
+
/** Child pages */
|
|
36
|
+
readonly children: ReadonlyArray<PageTreeNode>;
|
|
37
|
+
}
|
|
25
38
|
declare const LocalFileSystem_base: Context.TagClass<LocalFileSystem, "@knpkv/confluence-to-markdown/LocalFileSystem", {
|
|
26
39
|
/**
|
|
27
40
|
* Read a markdown file with front-matter.
|
|
@@ -50,11 +63,23 @@ declare const LocalFileSystem_base: Context.TagClass<LocalFileSystem, "@knpkv/co
|
|
|
50
63
|
/**
|
|
51
64
|
* Get the file path for a page.
|
|
52
65
|
*/
|
|
53
|
-
readonly getPagePath: (title: string, hasChildren: boolean, parentPath: string) => string
|
|
66
|
+
readonly getPagePath: (title: string, hasChildren: boolean, parentPath: string) => Effect.Effect<string>;
|
|
54
67
|
/**
|
|
55
68
|
* Get the directory path for a page's children.
|
|
56
69
|
*/
|
|
57
|
-
readonly getPageDir: (title: string, parentPath: string) => string
|
|
70
|
+
readonly getPageDir: (title: string, parentPath: string) => Effect.Effect<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Write a raw file (e.g., source HTML).
|
|
73
|
+
*/
|
|
74
|
+
readonly writeFile: (filePath: string, content: string) => Effect.Effect<void, FileSystemError>;
|
|
75
|
+
/**
|
|
76
|
+
* Build a tree of pages from directory structure.
|
|
77
|
+
*/
|
|
78
|
+
readonly buildPageTree: (docsPath: string, rootPageId: string, rootTitle: string) => Effect.Effect<PageTreeNode, FileSystemError | FrontMatterError>;
|
|
79
|
+
/**
|
|
80
|
+
* Write a new page file with minimal front-matter.
|
|
81
|
+
*/
|
|
82
|
+
readonly writeNewPageFile: (filePath: string, frontMatter: NewPageFrontMatter, content: string) => Effect.Effect<void, FileSystemError>;
|
|
58
83
|
}>;
|
|
59
84
|
/**
|
|
60
85
|
* Local file system service for markdown operations.
|
|
@@ -66,7 +91,7 @@ declare const LocalFileSystem_base: Context.TagClass<LocalFileSystem, "@knpkv/co
|
|
|
66
91
|
*
|
|
67
92
|
* const program = Effect.gen(function* () {
|
|
68
93
|
* const fs = yield* LocalFileSystem
|
|
69
|
-
* const files = yield* fs.listMarkdownFiles(".docs
|
|
94
|
+
* const files = yield* fs.listMarkdownFiles(".confluence/docs")
|
|
70
95
|
* console.log(files)
|
|
71
96
|
* })
|
|
72
97
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalFileSystem.d.ts","sourceRoot":"","sources":["../src/LocalFileSystem.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,UAAU,MAAM,6BAA6B,CAAA;AACzD,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAA;AAC7C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAKtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"LocalFileSystem.d.ts","sourceRoot":"","sources":["../src/LocalFileSystem.ts"],"names":[],"mappings":"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"}
|
package/dist/LocalFileSystem.js
CHANGED
|
@@ -9,8 +9,8 @@ import * as Context from "effect/Context";
|
|
|
9
9
|
import * as Effect from "effect/Effect";
|
|
10
10
|
import * as Layer from "effect/Layer";
|
|
11
11
|
import { FileSystemError } from "./ConfluenceError.js";
|
|
12
|
-
import { parseMarkdown, serializeMarkdown } from "./internal/frontmatter.js";
|
|
13
|
-
import { computeHash } from "./internal/hashUtils.js";
|
|
12
|
+
import { parseMarkdown, serializeMarkdown, serializeNewPageMarkdown } from "./internal/frontmatter.js";
|
|
13
|
+
import { computeHash, HashServiceLive } from "./internal/hashUtils.js";
|
|
14
14
|
import { pageToDir, pageToPath } from "./internal/pathUtils.js";
|
|
15
15
|
/**
|
|
16
16
|
* Local file system service for markdown operations.
|
|
@@ -22,7 +22,7 @@ import { pageToDir, pageToPath } from "./internal/pathUtils.js";
|
|
|
22
22
|
*
|
|
23
23
|
* const program = Effect.gen(function* () {
|
|
24
24
|
* const fs = yield* LocalFileSystem
|
|
25
|
-
* const files = yield* fs.listMarkdownFiles(".docs
|
|
25
|
+
* const files = yield* fs.listMarkdownFiles(".confluence/docs")
|
|
26
26
|
* console.log(files)
|
|
27
27
|
* })
|
|
28
28
|
* ```
|
|
@@ -42,7 +42,7 @@ export const layer = Layer.effect(LocalFileSystem, Effect.gen(function* () {
|
|
|
42
42
|
const readMarkdownFile = (filePath) => Effect.gen(function* () {
|
|
43
43
|
const content = yield* fs.readFileString(filePath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "read", path: filePath, cause })));
|
|
44
44
|
const parsed = yield* parseMarkdown(filePath, content);
|
|
45
|
-
const contentHash = computeHash(parsed.content);
|
|
45
|
+
const contentHash = yield* computeHash(parsed.content).pipe(Effect.provide(HashServiceLive));
|
|
46
46
|
return {
|
|
47
47
|
path: filePath,
|
|
48
48
|
frontMatter: parsed.frontMatter && "pageId" in parsed.frontMatter
|
|
@@ -87,6 +87,77 @@ export const layer = Layer.effect(LocalFileSystem, Effect.gen(function* () {
|
|
|
87
87
|
const ensureDir = (dirPath) => fs.makeDirectory(dirPath, { recursive: true }).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "mkdir", path: dirPath, cause })), Effect.asVoid);
|
|
88
88
|
const deleteFile = (filePath) => fs.remove(filePath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "delete", path: filePath, cause })));
|
|
89
89
|
const exists = (filePath) => fs.exists(filePath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "read", path: filePath, cause })));
|
|
90
|
+
const writeFile = (filePath, content) => Effect.gen(function* () {
|
|
91
|
+
const dir = pathService.dirname(filePath);
|
|
92
|
+
yield* fs.makeDirectory(dir, { recursive: true }).pipe(Effect.catchAll(() => Effect.void));
|
|
93
|
+
// Atomic write: write to temp file, then rename
|
|
94
|
+
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
95
|
+
yield* fs.writeFileString(tempPath, content).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "write", path: filePath, cause })));
|
|
96
|
+
yield* fs.rename(tempPath, filePath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "rename", path: filePath, cause })));
|
|
97
|
+
});
|
|
98
|
+
// Wrap path functions to provide Path service
|
|
99
|
+
const getPagePath = (title, hasChildren, parentPath) => pageToPath(title, hasChildren, parentPath).pipe(Effect.provide(Layer.succeed(Path.Path, pathService)));
|
|
100
|
+
const getPageDir = (title, parentPath) => pageToDir(title, parentPath).pipe(Effect.provide(Layer.succeed(Path.Path, pathService)));
|
|
101
|
+
const writeNewPageFile = (filePath, frontMatter, content) => Effect.gen(function* () {
|
|
102
|
+
const dir = pathService.dirname(filePath);
|
|
103
|
+
yield* fs.makeDirectory(dir, { recursive: true }).pipe(Effect.catchAll(() => Effect.void));
|
|
104
|
+
const serialized = serializeNewPageMarkdown(frontMatter, content);
|
|
105
|
+
// Atomic write: write to temp file, then rename
|
|
106
|
+
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
107
|
+
yield* fs.writeFileString(tempPath, serialized).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "write", path: filePath, cause })));
|
|
108
|
+
yield* fs.rename(tempPath, filePath).pipe(Effect.mapError((cause) => new FileSystemError({ operation: "rename", path: filePath, cause })));
|
|
109
|
+
});
|
|
110
|
+
const buildPageTree = (docsPath, rootPageId, rootTitle) => Effect.gen(function* () {
|
|
111
|
+
// Build a map of directory -> page info
|
|
112
|
+
const pagesByDir = new Map();
|
|
113
|
+
// Get all markdown files
|
|
114
|
+
const files = yield* listMarkdownFiles(docsPath);
|
|
115
|
+
// Parse each file and map to its directory
|
|
116
|
+
for (const filePath of files) {
|
|
117
|
+
const localFile = yield* readMarkdownFile(filePath);
|
|
118
|
+
const relativePath = pathService.relative(docsPath, filePath);
|
|
119
|
+
const dirPath = pathService.dirname(relativePath);
|
|
120
|
+
const baseName = pathService.basename(filePath, ".md");
|
|
121
|
+
// Determine the page's "key" - the directory it owns children in
|
|
122
|
+
// e.g., "foo.md" owns "foo/" directory
|
|
123
|
+
const pageKey = dirPath === "." ? baseName : pathService.join(dirPath, baseName);
|
|
124
|
+
pagesByDir.set(pageKey, {
|
|
125
|
+
path: relativePath,
|
|
126
|
+
title: localFile.frontMatter?.title ?? baseName,
|
|
127
|
+
pageId: localFile.frontMatter?.pageId ?? null
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Build tree recursively
|
|
131
|
+
const buildNode = (key, path, title, pageId) => {
|
|
132
|
+
// Find children: pages whose parent directory matches this key
|
|
133
|
+
const children = [];
|
|
134
|
+
for (const [childKey, childInfo] of pagesByDir.entries()) {
|
|
135
|
+
const childDir = pathService.dirname(childKey);
|
|
136
|
+
if (childDir === key) {
|
|
137
|
+
children.push(buildNode(childKey, childInfo.path, childInfo.title, childInfo.pageId));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Sort children by title
|
|
141
|
+
children.sort((a, b) => a.title.localeCompare(b.title));
|
|
142
|
+
return { path, title, pageId, children };
|
|
143
|
+
};
|
|
144
|
+
// Find root-level pages (those in docsPath root, or the root page itself)
|
|
145
|
+
const rootChildren = [];
|
|
146
|
+
for (const [key, info] of pagesByDir.entries()) {
|
|
147
|
+
const dir = pathService.dirname(key);
|
|
148
|
+
if (dir === ".") {
|
|
149
|
+
rootChildren.push(buildNode(key, info.path, info.title, info.pageId));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Sort children by title
|
|
153
|
+
rootChildren.sort((a, b) => a.title.localeCompare(b.title));
|
|
154
|
+
return {
|
|
155
|
+
path: "",
|
|
156
|
+
title: rootTitle,
|
|
157
|
+
pageId: rootPageId,
|
|
158
|
+
children: rootChildren
|
|
159
|
+
};
|
|
160
|
+
});
|
|
90
161
|
return LocalFileSystem.of({
|
|
91
162
|
readMarkdownFile,
|
|
92
163
|
writeMarkdownFile,
|
|
@@ -94,8 +165,11 @@ export const layer = Layer.effect(LocalFileSystem, Effect.gen(function* () {
|
|
|
94
165
|
ensureDir,
|
|
95
166
|
deleteFile,
|
|
96
167
|
exists,
|
|
97
|
-
getPagePath
|
|
98
|
-
getPageDir
|
|
168
|
+
getPagePath,
|
|
169
|
+
getPageDir,
|
|
170
|
+
writeFile,
|
|
171
|
+
buildPageTree,
|
|
172
|
+
writeNewPageFile
|
|
99
173
|
});
|
|
100
174
|
}));
|
|
101
175
|
//# sourceMappingURL=LocalFileSystem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalFileSystem.js","sourceRoot":"","sources":["../src/LocalFileSystem.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,UAAU,MAAM,6BAA6B,CAAA;AACzD,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAA;AAC7C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAGrC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"LocalFileSystem.js","sourceRoot":"","sources":["../src/LocalFileSystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTML to Markdown conversion service using
|
|
2
|
+
* HTML to Markdown conversion service using AST-based approach.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import * as Context from "effect/Context";
|
|
7
7
|
import * as Effect from "effect/Effect";
|
|
8
8
|
import * as Layer from "effect/Layer";
|
|
9
|
+
import type { Document } from "./ast/Document.js";
|
|
9
10
|
import { ConversionError } from "./ConfluenceError.js";
|
|
11
|
+
import { ParseError, type SerializeError } from "./SchemaConverterError.js";
|
|
12
|
+
import { type SerializeOptions } from "./serializers/MarkdownSerializer.js";
|
|
10
13
|
declare const MarkdownConverter_base: Context.TagClass<MarkdownConverter, "@knpkv/confluence-to-markdown/MarkdownConverter", {
|
|
11
14
|
/**
|
|
12
15
|
* Convert Confluence storage format (HTML) to GitHub Flavored Markdown.
|
|
13
16
|
*/
|
|
14
|
-
readonly htmlToMarkdown: (html: string) => Effect.Effect<string, ConversionError>;
|
|
17
|
+
readonly htmlToMarkdown: (html: string, options?: SerializeOptions) => Effect.Effect<string, ConversionError>;
|
|
15
18
|
/**
|
|
16
19
|
* Convert GitHub Flavored Markdown to HTML (Confluence storage format).
|
|
17
20
|
*/
|
|
18
21
|
readonly markdownToHtml: (markdown: string) => Effect.Effect<string, ConversionError>;
|
|
22
|
+
/**
|
|
23
|
+
* Parse Confluence HTML to Document AST.
|
|
24
|
+
*/
|
|
25
|
+
readonly htmlToAst: (html: string) => Effect.Effect<Document, ParseError>;
|
|
26
|
+
/**
|
|
27
|
+
* Parse Markdown to Document AST.
|
|
28
|
+
*/
|
|
29
|
+
readonly markdownToAst: (markdown: string) => Effect.Effect<Document, ParseError>;
|
|
30
|
+
/**
|
|
31
|
+
* Serialize Document AST to Confluence HTML.
|
|
32
|
+
*/
|
|
33
|
+
readonly astToHtml: (doc: Document) => Effect.Effect<string, SerializeError>;
|
|
34
|
+
/**
|
|
35
|
+
* Serialize Document AST to Markdown.
|
|
36
|
+
*/
|
|
37
|
+
readonly astToMarkdown: (doc: Document) => Effect.Effect<string, SerializeError>;
|
|
19
38
|
}>;
|
|
20
39
|
/**
|
|
21
40
|
* Markdown conversion service for HTML <-> GFM conversion.
|
|
@@ -46,5 +65,33 @@ export declare class MarkdownConverter extends MarkdownConverter_base {
|
|
|
46
65
|
* @category Layers
|
|
47
66
|
*/
|
|
48
67
|
export declare const layer: Layer.Layer<MarkdownConverter>;
|
|
68
|
+
/**
|
|
69
|
+
* Schema-based layer for MarkdownConverter using Effect Schema transforms.
|
|
70
|
+
*
|
|
71
|
+
* This is an alternative implementation that uses the new Schema-based
|
|
72
|
+
* conversion pipeline. It provides the same API as the default layer.
|
|
73
|
+
*
|
|
74
|
+
* Note: For full fidelity, continue to use the default layer. This schema-based
|
|
75
|
+
* layer is useful for simpler use cases or when you want to leverage Schema
|
|
76
|
+
* composition.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* import { MarkdownConverter, schemaBasedLayer } from "@knpkv/confluence-to-markdown/MarkdownConverter"
|
|
81
|
+
* import { Effect } from "effect"
|
|
82
|
+
*
|
|
83
|
+
* const program = Effect.gen(function* () {
|
|
84
|
+
* const converter = yield* MarkdownConverter
|
|
85
|
+
* const md = yield* converter.htmlToMarkdown("<h1>Hello</h1>")
|
|
86
|
+
* })
|
|
87
|
+
*
|
|
88
|
+
* Effect.runPromise(
|
|
89
|
+
* program.pipe(Effect.provide(schemaBasedLayer))
|
|
90
|
+
* )
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @category Layers
|
|
94
|
+
*/
|
|
95
|
+
export declare const schemaBasedLayer: Layer.Layer<MarkdownConverter>;
|
|
49
96
|
export {};
|
|
50
97
|
//# sourceMappingURL=MarkdownConverter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownConverter.d.ts","sourceRoot":"","sources":["../src/MarkdownConverter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"MarkdownConverter.d.ts","sourceRoot":"","sources":["../src/MarkdownConverter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAGtD,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAM3E,OAAO,EAAE,KAAK,gBAAgB,EAAuB,MAAM,qCAAqC,CAAA;;IA4B5F;;OAEG;6BACsB,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,KACvB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAE3C;;OAEG;6BACsB,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAErF;;OAEG;wBACiB,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;IAEzE;;OAEG;4BACqB,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;IAEjF;;OAEG;wBACiB,CAAC,GAAG,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAE5E;;OAEG;4BACqB,CAAC,GAAG,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;;AAzDpF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAkB,SAAQ,sBAsCpC;CAAG;AAEN;;;;GAIG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAiChD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAyC3D,CAAA"}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTML to Markdown conversion service using
|
|
2
|
+
* HTML to Markdown conversion service using AST-based approach.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import * as Context from "effect/Context";
|
|
7
7
|
import * as Effect from "effect/Effect";
|
|
8
8
|
import * as Layer from "effect/Layer";
|
|
9
|
-
import
|
|
10
|
-
import rehypeRemark from "rehype-remark";
|
|
11
|
-
import rehypeStringify from "rehype-stringify";
|
|
12
|
-
import remarkGfm from "remark-gfm";
|
|
13
|
-
import remarkParse from "remark-parse";
|
|
14
|
-
import remarkRehype from "remark-rehype";
|
|
15
|
-
import remarkStringify from "remark-stringify";
|
|
16
|
-
import { unified } from "unified";
|
|
9
|
+
import * as Schema from "effect/Schema";
|
|
17
10
|
import { ConversionError } from "./ConfluenceError.js";
|
|
11
|
+
import { parseConfluenceHtml } from "./parsers/ConfluenceParser.js";
|
|
12
|
+
import { parseMarkdown } from "./parsers/MarkdownParser.js";
|
|
13
|
+
import { ParseError } from "./SchemaConverterError.js";
|
|
14
|
+
import { ConfluenceToMarkdown, DocumentFromHast, DocumentFromMdast } from "./schemas/ConversionSchema.js";
|
|
15
|
+
import { HastFromHtml } from "./schemas/hast/index.js";
|
|
16
|
+
import { MdastFromMarkdown } from "./schemas/mdast/index.js";
|
|
17
|
+
import { PreprocessedHtmlFromConfluence } from "./schemas/preprocessing/index.js";
|
|
18
|
+
import { serializeToConfluence } from "./serializers/ConfluenceSerializer.js";
|
|
19
|
+
import { serializeToMarkdown } from "./serializers/MarkdownSerializer.js";
|
|
18
20
|
/**
|
|
19
21
|
* Markdown conversion service for HTML <-> GFM conversion.
|
|
20
22
|
*
|
|
@@ -38,114 +40,74 @@ import { ConversionError } from "./ConfluenceError.js";
|
|
|
38
40
|
*/
|
|
39
41
|
export class MarkdownConverter extends Context.Tag("@knpkv/confluence-to-markdown/MarkdownConverter")() {
|
|
40
42
|
}
|
|
41
|
-
/** Maximum HTML input size (1MB) to prevent ReDoS attacks */
|
|
42
|
-
const MAX_HTML_SIZE = 1024 * 1024;
|
|
43
|
-
/**
|
|
44
|
-
* Strip Confluence-specific macros while preserving text content.
|
|
45
|
-
* Uses iterative approach to avoid ReDoS with nested content.
|
|
46
|
-
*/
|
|
47
|
-
const stripConfluenceMacros = (html) => Effect.gen(function* () {
|
|
48
|
-
// Limit input size to prevent ReDoS
|
|
49
|
-
if (html.length > MAX_HTML_SIZE) {
|
|
50
|
-
return yield* Effect.fail(new ConversionError({
|
|
51
|
-
direction: "htmlToMarkdown",
|
|
52
|
-
cause: `HTML input too large: ${html.length} bytes (max ${MAX_HTML_SIZE})`
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
let result = html;
|
|
56
|
-
// Process structured macros iteratively to handle nesting safely
|
|
57
|
-
let iterations = 0;
|
|
58
|
-
const maxIterations = 100; // Prevent infinite loops
|
|
59
|
-
while (iterations < maxIterations) {
|
|
60
|
-
const macroStart = result.indexOf("<ac:structured-macro");
|
|
61
|
-
if (macroStart === -1)
|
|
62
|
-
break;
|
|
63
|
-
// Find matching closing tag by counting nesting
|
|
64
|
-
let depth = 1;
|
|
65
|
-
let pos = macroStart + 20; // Skip past opening tag start
|
|
66
|
-
let endPos = -1;
|
|
67
|
-
while (pos < result.length && depth > 0) {
|
|
68
|
-
if (result.slice(pos, pos + 20) === "<ac:structured-macro") {
|
|
69
|
-
depth++;
|
|
70
|
-
pos += 20;
|
|
71
|
-
}
|
|
72
|
-
else if (result.slice(pos, pos + 21) === "</ac:structured-macro") {
|
|
73
|
-
depth--;
|
|
74
|
-
if (depth === 0) {
|
|
75
|
-
endPos = result.indexOf(">", pos) + 1;
|
|
76
|
-
}
|
|
77
|
-
pos += 21;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
pos++;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (endPos === -1)
|
|
84
|
-
break; // Malformed HTML, stop processing
|
|
85
|
-
const macroContent = result.slice(macroStart, endPos);
|
|
86
|
-
// Extract content from macro
|
|
87
|
-
let replacement = "";
|
|
88
|
-
const plainBodyStart = macroContent.indexOf("<ac:plain-text-body><![CDATA[");
|
|
89
|
-
const plainBodyEnd = macroContent.indexOf("]]></ac:plain-text-body>");
|
|
90
|
-
if (plainBodyStart !== -1 && plainBodyEnd !== -1) {
|
|
91
|
-
const content = macroContent.slice(plainBodyStart + 29, plainBodyEnd);
|
|
92
|
-
replacement = `<pre><code>${content}</code></pre>`;
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
const richBodyStart = macroContent.indexOf("<ac:rich-text-body>");
|
|
96
|
-
const richBodyEnd = macroContent.indexOf("</ac:rich-text-body>");
|
|
97
|
-
if (richBodyStart !== -1 && richBodyEnd !== -1) {
|
|
98
|
-
replacement = macroContent.slice(richBodyStart + 19, richBodyEnd);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
result = result.slice(0, macroStart) + replacement + result.slice(endPos);
|
|
102
|
-
iterations++;
|
|
103
|
-
}
|
|
104
|
-
// Remove remaining simple tags with non-greedy bounded patterns
|
|
105
|
-
result = result
|
|
106
|
-
.replace(/<ac:parameter[^>]{0,1000}>[^<]{0,10000}<\/ac:parameter>/gi, "")
|
|
107
|
-
.replace(/<\/?ac:[a-z-]{1,50}[^>]{0,1000}>/gi, "")
|
|
108
|
-
.replace(/<\/?ri:[a-z-]{1,50}[^>]{0,1000}\/?>/gi, "");
|
|
109
|
-
return result;
|
|
110
|
-
});
|
|
111
|
-
/**
|
|
112
|
-
* Create the markdown converter processor for HTML -> Markdown.
|
|
113
|
-
*/
|
|
114
|
-
const createHtmlToMdProcessor = () => unified()
|
|
115
|
-
.use(rehypeParse, { fragment: true })
|
|
116
|
-
.use(rehypeRemark)
|
|
117
|
-
.use(remarkGfm)
|
|
118
|
-
.use(remarkStringify);
|
|
119
|
-
/**
|
|
120
|
-
* Create the markdown converter processor for Markdown -> HTML.
|
|
121
|
-
*/
|
|
122
|
-
const createMdToHtmlProcessor = () => unified()
|
|
123
|
-
.use(remarkParse)
|
|
124
|
-
.use(remarkGfm)
|
|
125
|
-
.use(remarkRehype)
|
|
126
|
-
.use(rehypeStringify);
|
|
127
43
|
/**
|
|
128
44
|
* Layer that provides the MarkdownConverter service.
|
|
129
45
|
*
|
|
130
46
|
* @category Layers
|
|
131
47
|
*/
|
|
132
48
|
export const layer = Layer.succeed(MarkdownConverter, MarkdownConverter.of({
|
|
133
|
-
htmlToMarkdown: (html) => Effect.gen(function* () {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
});
|
|
49
|
+
htmlToMarkdown: (html, options) => Effect.gen(function* () {
|
|
50
|
+
// Use AST-based approach to preserve colors, underlines, etc.
|
|
51
|
+
const doc = yield* parseConfluenceHtml(html).pipe(Effect.mapError((e) => new ConversionError({ direction: "htmlToMarkdown", cause: e.message })));
|
|
52
|
+
return yield* serializeToMarkdown(doc, options).pipe(Effect.mapError((e) => new ConversionError({ direction: "htmlToMarkdown", cause: e.message })));
|
|
53
|
+
}),
|
|
54
|
+
markdownToHtml: (markdown) => Effect.gen(function* () {
|
|
55
|
+
// Use AST-based approach for consistency
|
|
56
|
+
const doc = yield* parseMarkdown(markdown).pipe(Effect.mapError((e) => new ConversionError({ direction: "markdownToHtml", cause: e.message })));
|
|
57
|
+
return yield* serializeToConfluence(doc).pipe(Effect.mapError((e) => new ConversionError({ direction: "markdownToHtml", cause: e.message })));
|
|
142
58
|
}),
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
59
|
+
htmlToAst: (html) => parseConfluenceHtml(html),
|
|
60
|
+
markdownToAst: (markdown) => parseMarkdown(markdown),
|
|
61
|
+
astToHtml: (doc) => serializeToConfluence(doc),
|
|
62
|
+
astToMarkdown: (doc) => serializeToMarkdown(doc)
|
|
63
|
+
}));
|
|
64
|
+
/**
|
|
65
|
+
* Schema-based layer for MarkdownConverter using Effect Schema transforms.
|
|
66
|
+
*
|
|
67
|
+
* This is an alternative implementation that uses the new Schema-based
|
|
68
|
+
* conversion pipeline. It provides the same API as the default layer.
|
|
69
|
+
*
|
|
70
|
+
* Note: For full fidelity, continue to use the default layer. This schema-based
|
|
71
|
+
* layer is useful for simpler use cases or when you want to leverage Schema
|
|
72
|
+
* composition.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { MarkdownConverter, schemaBasedLayer } from "@knpkv/confluence-to-markdown/MarkdownConverter"
|
|
77
|
+
* import { Effect } from "effect"
|
|
78
|
+
*
|
|
79
|
+
* const program = Effect.gen(function* () {
|
|
80
|
+
* const converter = yield* MarkdownConverter
|
|
81
|
+
* const md = yield* converter.htmlToMarkdown("<h1>Hello</h1>")
|
|
82
|
+
* })
|
|
83
|
+
*
|
|
84
|
+
* Effect.runPromise(
|
|
85
|
+
* program.pipe(Effect.provide(schemaBasedLayer))
|
|
86
|
+
* )
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @category Layers
|
|
90
|
+
*/
|
|
91
|
+
export const schemaBasedLayer = Layer.succeed(MarkdownConverter, MarkdownConverter.of({
|
|
92
|
+
// Note: Schema-based layer doesn't support includeRawSource option yet
|
|
93
|
+
htmlToMarkdown: (html, options) => Effect.gen(function* () {
|
|
94
|
+
if (options?.includeRawSource !== undefined) {
|
|
95
|
+
yield* Effect.logWarning("schemaBasedLayer: includeRawSource option is not supported, use default layer");
|
|
96
|
+
}
|
|
97
|
+
return yield* Schema.decode(ConfluenceToMarkdown)(html);
|
|
98
|
+
}).pipe(Effect.mapError((e) => new ConversionError({ direction: "htmlToMarkdown", cause: e.message }))),
|
|
99
|
+
markdownToHtml: (markdown) => Schema.encode(ConfluenceToMarkdown)(markdown).pipe(Effect.mapError((e) => new ConversionError({ direction: "markdownToHtml", cause: e.message }))),
|
|
100
|
+
htmlToAst: (html) => Effect.gen(function* () {
|
|
101
|
+
const preprocessed = yield* Schema.decode(PreprocessedHtmlFromConfluence)(html);
|
|
102
|
+
const hast = yield* Schema.decode(HastFromHtml)(preprocessed);
|
|
103
|
+
return yield* Schema.decode(DocumentFromHast)(hast);
|
|
104
|
+
}).pipe(Effect.mapError((e) => new ParseError({ source: "confluence", message: e.message }))),
|
|
105
|
+
markdownToAst: (markdown) => Effect.gen(function* () {
|
|
106
|
+
const mdast = yield* Schema.decode(MdastFromMarkdown)(markdown);
|
|
107
|
+
return yield* Schema.decode(DocumentFromMdast)(mdast);
|
|
108
|
+
}).pipe(Effect.mapError((e) => new ParseError({ source: "markdown", message: e.message }))),
|
|
109
|
+
// For serialization, continue using the existing serializers for full fidelity
|
|
110
|
+
astToHtml: (doc) => serializeToConfluence(doc),
|
|
111
|
+
astToMarkdown: (doc) => serializeToMarkdown(doc)
|
|
150
112
|
}));
|
|
151
113
|
//# sourceMappingURL=MarkdownConverter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownConverter.js","sourceRoot":"","sources":["../src/MarkdownConverter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"MarkdownConverter.js","sourceRoot":"","sources":["../src/MarkdownConverter.ts"],"names":[],"mappings":"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"}
|