@knpkv/confluence-to-markdown 0.5.0 → 0.7.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.
Files changed (395) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +58 -14
  3. package/dist/AdfPlaceholders.d.ts +42 -0
  4. package/dist/AdfPlaceholders.d.ts.map +1 -0
  5. package/dist/AdfPlaceholders.js +547 -0
  6. package/dist/AdfPlaceholders.js.map +1 -0
  7. package/dist/AdfSchemaValidator.d.ts +37 -0
  8. package/dist/AdfSchemaValidator.d.ts.map +1 -0
  9. package/dist/AdfSchemaValidator.js +37 -0
  10. package/dist/AdfSchemaValidator.js.map +1 -0
  11. package/dist/AdfWalker.d.ts +39 -0
  12. package/dist/AdfWalker.d.ts.map +1 -0
  13. package/dist/AdfWalker.js +527 -0
  14. package/dist/AdfWalker.js.map +1 -0
  15. package/dist/AtlaskitTransformers.d.ts +35 -0
  16. package/dist/AtlaskitTransformers.d.ts.map +1 -0
  17. package/dist/AtlaskitTransformers.js +48 -0
  18. package/dist/AtlaskitTransformers.js.map +1 -0
  19. package/dist/Brand.d.ts +6 -6
  20. package/dist/Brand.d.ts.map +1 -1
  21. package/dist/Brand.js +8 -6
  22. package/dist/Brand.js.map +1 -1
  23. package/dist/ConfluenceAuth.d.ts +4 -4
  24. package/dist/ConfluenceAuth.d.ts.map +1 -1
  25. package/dist/ConfluenceAuth.js +15 -27
  26. package/dist/ConfluenceAuth.js.map +1 -1
  27. package/dist/ConfluenceClient.d.ts +4 -4
  28. package/dist/ConfluenceClient.d.ts.map +1 -1
  29. package/dist/ConfluenceClient.js +21 -14
  30. package/dist/ConfluenceClient.js.map +1 -1
  31. package/dist/ConfluenceConfig.d.ts +3 -3
  32. package/dist/ConfluenceConfig.d.ts.map +1 -1
  33. package/dist/ConfluenceConfig.js +13 -11
  34. package/dist/ConfluenceConfig.js.map +1 -1
  35. package/dist/ConfluenceError.d.ts +56 -4
  36. package/dist/ConfluenceError.d.ts.map +1 -1
  37. package/dist/ConfluenceError.js +30 -1
  38. package/dist/ConfluenceError.js.map +1 -1
  39. package/dist/GitService.d.ts +11 -3
  40. package/dist/GitService.d.ts.map +1 -1
  41. package/dist/GitService.js +19 -27
  42. package/dist/GitService.js.map +1 -1
  43. package/dist/LocalFileSystem.d.ts +3 -3
  44. package/dist/LocalFileSystem.d.ts.map +1 -1
  45. package/dist/LocalFileSystem.js +6 -6
  46. package/dist/LocalFileSystem.js.map +1 -1
  47. package/dist/MarkdownConverter.d.ts +16 -65
  48. package/dist/MarkdownConverter.d.ts.map +1 -1
  49. package/dist/MarkdownConverter.js +64 -85
  50. package/dist/MarkdownConverter.js.map +1 -1
  51. package/dist/Schemas.d.ts +128 -141
  52. package/dist/Schemas.d.ts.map +1 -1
  53. package/dist/Schemas.js +21 -23
  54. package/dist/Schemas.js.map +1 -1
  55. package/dist/SyncEngine.d.ts +8 -5
  56. package/dist/SyncEngine.d.ts.map +1 -1
  57. package/dist/SyncEngine.js +189 -113
  58. package/dist/SyncEngine.js.map +1 -1
  59. package/dist/bin.js +23 -35
  60. package/dist/bin.js.map +1 -1
  61. package/dist/commands/auth.d.ts +2 -14
  62. package/dist/commands/auth.d.ts.map +1 -1
  63. package/dist/commands/auth.js +11 -16
  64. package/dist/commands/auth.js.map +1 -1
  65. package/dist/commands/clone.d.ts +4 -6
  66. package/dist/commands/clone.d.ts.map +1 -1
  67. package/dist/commands/clone.js +34 -32
  68. package/dist/commands/clone.js.map +1 -1
  69. package/dist/commands/delete.d.ts +2 -10
  70. package/dist/commands/delete.d.ts.map +1 -1
  71. package/dist/commands/delete.js +5 -4
  72. package/dist/commands/delete.js.map +1 -1
  73. package/dist/commands/errorHandler.d.ts +2 -1
  74. package/dist/commands/errorHandler.d.ts.map +1 -1
  75. package/dist/commands/errorHandler.js +22 -15
  76. package/dist/commands/errorHandler.js.map +1 -1
  77. package/dist/commands/fetch.d.ts +27 -0
  78. package/dist/commands/fetch.d.ts.map +1 -0
  79. package/dist/commands/fetch.js +48 -0
  80. package/dist/commands/fetch.js.map +1 -0
  81. package/dist/commands/git.d.ts +7 -10
  82. package/dist/commands/git.d.ts.map +1 -1
  83. package/dist/commands/git.js +6 -6
  84. package/dist/commands/git.js.map +1 -1
  85. package/dist/commands/index.d.ts +1 -0
  86. package/dist/commands/index.d.ts.map +1 -1
  87. package/dist/commands/index.js +1 -0
  88. package/dist/commands/index.js.map +1 -1
  89. package/dist/commands/layers.d.ts +10 -9
  90. package/dist/commands/layers.d.ts.map +1 -1
  91. package/dist/commands/layers.js +41 -30
  92. package/dist/commands/layers.js.map +1 -1
  93. package/dist/commands/new.d.ts +2 -6
  94. package/dist/commands/new.d.ts.map +1 -1
  95. package/dist/commands/new.js +5 -4
  96. package/dist/commands/new.js.map +1 -1
  97. package/dist/commands/pageInput.d.ts +19 -0
  98. package/dist/commands/pageInput.d.ts.map +1 -0
  99. package/dist/commands/pageInput.js +68 -0
  100. package/dist/commands/pageInput.js.map +1 -0
  101. package/dist/commands/root.d.ts +8 -0
  102. package/dist/commands/root.d.ts.map +1 -0
  103. package/dist/commands/root.js +29 -0
  104. package/dist/commands/root.js.map +1 -0
  105. package/dist/commands/sync.d.ts +6 -9
  106. package/dist/commands/sync.d.ts.map +1 -1
  107. package/dist/commands/sync.js +5 -6
  108. package/dist/commands/sync.js.map +1 -1
  109. package/dist/index.d.ts +3 -8
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +2 -13
  112. package/dist/index.js.map +1 -1
  113. package/dist/internal/NodeLayers.d.ts.map +1 -1
  114. package/dist/internal/NodeLayers.js +1 -2
  115. package/dist/internal/NodeLayers.js.map +1 -1
  116. package/dist/internal/adfMetadata.d.ts +30 -0
  117. package/dist/internal/adfMetadata.d.ts.map +1 -0
  118. package/dist/internal/adfMetadata.js +126 -0
  119. package/dist/internal/adfMetadata.js.map +1 -0
  120. package/dist/internal/cleanMarkdown.d.ts +5 -0
  121. package/dist/internal/cleanMarkdown.d.ts.map +1 -0
  122. package/dist/internal/cleanMarkdown.js +13 -0
  123. package/dist/internal/cleanMarkdown.js.map +1 -0
  124. package/dist/internal/frontmatter.d.ts.map +1 -1
  125. package/dist/internal/frontmatter.js +41 -8
  126. package/dist/internal/frontmatter.js.map +1 -1
  127. package/dist/internal/gitCommands.d.ts +9 -3
  128. package/dist/internal/gitCommands.d.ts.map +1 -1
  129. package/dist/internal/gitCommands.js +18 -9
  130. package/dist/internal/gitCommands.js.map +1 -1
  131. package/dist/internal/hashUtils.d.ts +1 -1
  132. package/dist/internal/hashUtils.d.ts.map +1 -1
  133. package/dist/internal/hashUtils.js +1 -1
  134. package/dist/internal/hashUtils.js.map +1 -1
  135. package/dist/internal/oauthServer.d.ts +10 -5
  136. package/dist/internal/oauthServer.d.ts.map +1 -1
  137. package/dist/internal/oauthServer.js +19 -40
  138. package/dist/internal/oauthServer.js.map +1 -1
  139. package/dist/internal/pathUtils.d.ts +1 -1
  140. package/dist/internal/pathUtils.d.ts.map +1 -1
  141. package/dist/internal/pathUtils.js +1 -1
  142. package/dist/internal/pathUtils.js.map +1 -1
  143. package/dist/internal/process.d.ts +15 -0
  144. package/dist/internal/process.d.ts.map +1 -0
  145. package/dist/internal/process.js +10 -0
  146. package/dist/internal/process.js.map +1 -0
  147. package/dist/internal/stdio.d.ts +6 -0
  148. package/dist/internal/stdio.d.ts.map +1 -0
  149. package/dist/internal/stdio.js +15 -0
  150. package/dist/internal/stdio.js.map +1 -0
  151. package/dist/internal/tokenStorage.d.ts +3 -13
  152. package/dist/internal/tokenStorage.d.ts.map +1 -1
  153. package/dist/internal/tokenStorage.js +26 -24
  154. package/dist/internal/tokenStorage.js.map +1 -1
  155. package/dist/internal/userCache.d.ts +1 -1
  156. package/dist/internal/userCache.d.ts.map +1 -1
  157. package/dist/internal/userCache.js +1 -1
  158. package/dist/internal/userCache.js.map +1 -1
  159. package/package.json +29 -20
  160. package/skills/confluence/SKILL.md +143 -0
  161. package/skills/confluence/agents/openai.yaml +4 -0
  162. package/src/AdfPlaceholders.ts +563 -0
  163. package/src/AdfSchemaValidator.ts +65 -0
  164. package/src/AdfWalker.ts +591 -0
  165. package/src/AtlaskitTransformers.ts +70 -0
  166. package/src/Brand.ts +11 -16
  167. package/src/ConfluenceAuth.ts +22 -30
  168. package/src/ConfluenceClient.ts +28 -24
  169. package/src/ConfluenceConfig.ts +14 -14
  170. package/src/ConfluenceError.ts +65 -3
  171. package/src/GitService.ts +39 -49
  172. package/src/LocalFileSystem.ts +7 -9
  173. package/src/MarkdownConverter.ts +108 -143
  174. package/src/Schemas.ts +17 -16
  175. package/src/SyncEngine.ts +272 -127
  176. package/src/atlaskit-adf-schema.d.ts +3 -0
  177. package/src/bin.ts +30 -56
  178. package/src/commands/auth.ts +21 -18
  179. package/src/commands/clone.ts +46 -38
  180. package/src/commands/delete.ts +5 -4
  181. package/src/commands/errorHandler.ts +25 -18
  182. package/src/commands/fetch.ts +90 -0
  183. package/src/commands/git.ts +6 -6
  184. package/src/commands/index.ts +1 -0
  185. package/src/commands/layers.ts +64 -37
  186. package/src/commands/new.ts +5 -4
  187. package/src/commands/pageInput.ts +103 -0
  188. package/src/commands/root.ts +59 -0
  189. package/src/commands/sync.ts +7 -6
  190. package/src/index.ts +3 -18
  191. package/src/internal/NodeLayers.ts +1 -2
  192. package/src/internal/adfMetadata.ts +145 -0
  193. package/src/internal/cleanMarkdown.ts +15 -0
  194. package/src/internal/frontmatter.ts +45 -8
  195. package/src/internal/gitCommands.ts +23 -17
  196. package/src/internal/hashUtils.ts +2 -2
  197. package/src/internal/oauthServer.ts +84 -105
  198. package/src/internal/pathUtils.ts +1 -1
  199. package/src/internal/process.ts +15 -0
  200. package/src/internal/stdio.ts +22 -0
  201. package/src/internal/tokenStorage.ts +39 -29
  202. package/src/internal/userCache.ts +2 -2
  203. package/test/AdfPlaceholders.test.ts +508 -0
  204. package/test/AdfSchemaValidator.test.ts +34 -0
  205. package/test/AdfWalker.test.ts +676 -0
  206. package/test/AtlaskitTransformers.test.ts +25 -0
  207. package/test/Brand.test.ts +11 -11
  208. package/test/GitService.test.ts +6 -2
  209. package/test/MarkdownConverter.test.ts +121 -105
  210. package/test/RoundTrip.test.ts +521 -0
  211. package/test/Schemas.test.ts +40 -40
  212. package/test/adfMetadata.test.ts +110 -0
  213. package/test/cleanMarkdown.test.ts +36 -0
  214. package/test/commandHarness.test.ts +79 -0
  215. package/test/commandHarness.ts +147 -0
  216. package/test/fetch.test.ts +61 -0
  217. package/test/frontmatter.test.ts +41 -0
  218. package/test/integration.test.ts +569 -156
  219. package/test/layers.test.ts +12 -0
  220. package/test/oauthServer.test.ts +4 -5
  221. package/test/pageInput.test.ts +83 -0
  222. package/test/tokenStorage.test.ts +17 -17
  223. package/dist/SchemaConverterError.d.ts +0 -108
  224. package/dist/SchemaConverterError.d.ts.map +0 -1
  225. package/dist/SchemaConverterError.js +0 -84
  226. package/dist/SchemaConverterError.js.map +0 -1
  227. package/dist/ast/BlockNode.d.ts +0 -453
  228. package/dist/ast/BlockNode.d.ts.map +0 -1
  229. package/dist/ast/BlockNode.js +0 -310
  230. package/dist/ast/BlockNode.js.map +0 -1
  231. package/dist/ast/Document.d.ts +0 -216
  232. package/dist/ast/Document.d.ts.map +0 -1
  233. package/dist/ast/Document.js +0 -69
  234. package/dist/ast/Document.js.map +0 -1
  235. package/dist/ast/InlineNode.d.ts +0 -477
  236. package/dist/ast/InlineNode.d.ts.map +0 -1
  237. package/dist/ast/InlineNode.js +0 -263
  238. package/dist/ast/InlineNode.js.map +0 -1
  239. package/dist/ast/MacroNode.d.ts +0 -267
  240. package/dist/ast/MacroNode.d.ts.map +0 -1
  241. package/dist/ast/MacroNode.js +0 -164
  242. package/dist/ast/MacroNode.js.map +0 -1
  243. package/dist/ast/index.d.ts +0 -10
  244. package/dist/ast/index.d.ts.map +0 -1
  245. package/dist/ast/index.js +0 -14
  246. package/dist/ast/index.js.map +0 -1
  247. package/dist/parsers/ConfluenceParser.d.ts +0 -26
  248. package/dist/parsers/ConfluenceParser.d.ts.map +0 -1
  249. package/dist/parsers/ConfluenceParser.js +0 -797
  250. package/dist/parsers/ConfluenceParser.js.map +0 -1
  251. package/dist/parsers/MarkdownParser.d.ts +0 -26
  252. package/dist/parsers/MarkdownParser.d.ts.map +0 -1
  253. package/dist/parsers/MarkdownParser.js +0 -982
  254. package/dist/parsers/MarkdownParser.js.map +0 -1
  255. package/dist/parsers/index.d.ts +0 -8
  256. package/dist/parsers/index.d.ts.map +0 -1
  257. package/dist/parsers/index.js +0 -8
  258. package/dist/parsers/index.js.map +0 -1
  259. package/dist/schemas/ConfluenceSchema.d.ts +0 -21
  260. package/dist/schemas/ConfluenceSchema.d.ts.map +0 -1
  261. package/dist/schemas/ConfluenceSchema.js +0 -38
  262. package/dist/schemas/ConfluenceSchema.js.map +0 -1
  263. package/dist/schemas/ConversionSchema.d.ts +0 -35
  264. package/dist/schemas/ConversionSchema.d.ts.map +0 -1
  265. package/dist/schemas/ConversionSchema.js +0 -208
  266. package/dist/schemas/ConversionSchema.js.map +0 -1
  267. package/dist/schemas/MarkdownSchema.d.ts +0 -21
  268. package/dist/schemas/MarkdownSchema.d.ts.map +0 -1
  269. package/dist/schemas/MarkdownSchema.js +0 -38
  270. package/dist/schemas/MarkdownSchema.js.map +0 -1
  271. package/dist/schemas/hast/HastFromHtml.d.ts +0 -27
  272. package/dist/schemas/hast/HastFromHtml.d.ts.map +0 -1
  273. package/dist/schemas/hast/HastFromHtml.js +0 -107
  274. package/dist/schemas/hast/HastFromHtml.js.map +0 -1
  275. package/dist/schemas/hast/HastSchema.d.ts +0 -195
  276. package/dist/schemas/hast/HastSchema.d.ts.map +0 -1
  277. package/dist/schemas/hast/HastSchema.js +0 -183
  278. package/dist/schemas/hast/HastSchema.js.map +0 -1
  279. package/dist/schemas/hast/index.d.ts +0 -9
  280. package/dist/schemas/hast/index.d.ts.map +0 -1
  281. package/dist/schemas/hast/index.js +0 -3
  282. package/dist/schemas/hast/index.js.map +0 -1
  283. package/dist/schemas/index.d.ts +0 -14
  284. package/dist/schemas/index.d.ts.map +0 -1
  285. package/dist/schemas/index.js +0 -16
  286. package/dist/schemas/index.js.map +0 -1
  287. package/dist/schemas/mdast/MdastFromMarkdown.d.ts +0 -30
  288. package/dist/schemas/mdast/MdastFromMarkdown.d.ts.map +0 -1
  289. package/dist/schemas/mdast/MdastFromMarkdown.js +0 -79
  290. package/dist/schemas/mdast/MdastFromMarkdown.js.map +0 -1
  291. package/dist/schemas/mdast/MdastSchema.d.ts +0 -385
  292. package/dist/schemas/mdast/MdastSchema.d.ts.map +0 -1
  293. package/dist/schemas/mdast/MdastSchema.js +0 -266
  294. package/dist/schemas/mdast/MdastSchema.js.map +0 -1
  295. package/dist/schemas/mdast/index.d.ts +0 -10
  296. package/dist/schemas/mdast/index.d.ts.map +0 -1
  297. package/dist/schemas/mdast/index.js +0 -4
  298. package/dist/schemas/mdast/index.js.map +0 -1
  299. package/dist/schemas/mdast/mdastToString.d.ts +0 -13
  300. package/dist/schemas/mdast/mdastToString.d.ts.map +0 -1
  301. package/dist/schemas/mdast/mdastToString.js +0 -85
  302. package/dist/schemas/mdast/mdastToString.js.map +0 -1
  303. package/dist/schemas/nodes/block/BlockSchema.d.ts +0 -43
  304. package/dist/schemas/nodes/block/BlockSchema.d.ts.map +0 -1
  305. package/dist/schemas/nodes/block/BlockSchema.js +0 -634
  306. package/dist/schemas/nodes/block/BlockSchema.js.map +0 -1
  307. package/dist/schemas/nodes/block/index.d.ts +0 -7
  308. package/dist/schemas/nodes/block/index.d.ts.map +0 -1
  309. package/dist/schemas/nodes/block/index.js +0 -7
  310. package/dist/schemas/nodes/block/index.js.map +0 -1
  311. package/dist/schemas/nodes/index.d.ts +0 -9
  312. package/dist/schemas/nodes/index.d.ts.map +0 -1
  313. package/dist/schemas/nodes/index.js +0 -12
  314. package/dist/schemas/nodes/index.js.map +0 -1
  315. package/dist/schemas/nodes/inline/InlineSchema.d.ts +0 -48
  316. package/dist/schemas/nodes/inline/InlineSchema.d.ts.map +0 -1
  317. package/dist/schemas/nodes/inline/InlineSchema.js +0 -436
  318. package/dist/schemas/nodes/inline/InlineSchema.js.map +0 -1
  319. package/dist/schemas/nodes/inline/index.d.ts +0 -7
  320. package/dist/schemas/nodes/inline/index.d.ts.map +0 -1
  321. package/dist/schemas/nodes/inline/index.js +0 -7
  322. package/dist/schemas/nodes/inline/index.js.map +0 -1
  323. package/dist/schemas/nodes/macro/MacroSchema.d.ts +0 -27
  324. package/dist/schemas/nodes/macro/MacroSchema.d.ts.map +0 -1
  325. package/dist/schemas/nodes/macro/MacroSchema.js +0 -162
  326. package/dist/schemas/nodes/macro/MacroSchema.js.map +0 -1
  327. package/dist/schemas/nodes/macro/index.d.ts +0 -7
  328. package/dist/schemas/nodes/macro/index.d.ts.map +0 -1
  329. package/dist/schemas/nodes/macro/index.js +0 -7
  330. package/dist/schemas/nodes/macro/index.js.map +0 -1
  331. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +0 -24
  332. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +0 -1
  333. package/dist/schemas/preprocessing/ConfluencePreprocessor.js +0 -359
  334. package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +0 -1
  335. package/dist/schemas/preprocessing/index.d.ts +0 -8
  336. package/dist/schemas/preprocessing/index.d.ts.map +0 -1
  337. package/dist/schemas/preprocessing/index.js +0 -2
  338. package/dist/schemas/preprocessing/index.js.map +0 -1
  339. package/dist/serializers/ConfluenceSerializer.d.ts +0 -30
  340. package/dist/serializers/ConfluenceSerializer.d.ts.map +0 -1
  341. package/dist/serializers/ConfluenceSerializer.js +0 -560
  342. package/dist/serializers/ConfluenceSerializer.js.map +0 -1
  343. package/dist/serializers/MarkdownSerializer.d.ts +0 -34
  344. package/dist/serializers/MarkdownSerializer.d.ts.map +0 -1
  345. package/dist/serializers/MarkdownSerializer.js +0 -395
  346. package/dist/serializers/MarkdownSerializer.js.map +0 -1
  347. package/dist/serializers/index.d.ts +0 -8
  348. package/dist/serializers/index.d.ts.map +0 -1
  349. package/dist/serializers/index.js +0 -8
  350. package/dist/serializers/index.js.map +0 -1
  351. package/src/SchemaConverterError.ts +0 -108
  352. package/src/ast/BlockNode.ts +0 -469
  353. package/src/ast/Document.ts +0 -90
  354. package/src/ast/InlineNode.ts +0 -323
  355. package/src/ast/MacroNode.ts +0 -245
  356. package/src/ast/index.ts +0 -83
  357. package/src/parsers/ConfluenceParser.ts +0 -956
  358. package/src/parsers/MarkdownParser.ts +0 -1338
  359. package/src/parsers/index.ts +0 -8
  360. package/src/schemas/ConfluenceSchema.ts +0 -56
  361. package/src/schemas/ConversionSchema.ts +0 -318
  362. package/src/schemas/MarkdownSchema.ts +0 -56
  363. package/src/schemas/hast/HastFromHtml.ts +0 -153
  364. package/src/schemas/hast/HastSchema.ts +0 -274
  365. package/src/schemas/hast/index.ts +0 -35
  366. package/src/schemas/index.ts +0 -20
  367. package/src/schemas/mdast/MdastFromMarkdown.ts +0 -118
  368. package/src/schemas/mdast/MdastSchema.ts +0 -566
  369. package/src/schemas/mdast/index.ts +0 -59
  370. package/src/schemas/mdast/mdastToString.ts +0 -102
  371. package/src/schemas/nodes/block/BlockSchema.ts +0 -773
  372. package/src/schemas/nodes/block/index.ts +0 -13
  373. package/src/schemas/nodes/index.ts +0 -20
  374. package/src/schemas/nodes/inline/InlineSchema.ts +0 -523
  375. package/src/schemas/nodes/inline/index.ts +0 -14
  376. package/src/schemas/nodes/macro/MacroSchema.ts +0 -226
  377. package/src/schemas/nodes/macro/index.ts +0 -6
  378. package/src/schemas/preprocessing/ConfluencePreprocessor.ts +0 -455
  379. package/src/schemas/preprocessing/index.ts +0 -8
  380. package/src/serializers/ConfluenceSerializer.ts +0 -737
  381. package/src/serializers/MarkdownSerializer.ts +0 -543
  382. package/src/serializers/index.ts +0 -8
  383. package/test/ast/BlockNode.test.ts +0 -265
  384. package/test/ast/Document.test.ts +0 -126
  385. package/test/ast/InlineNode.test.ts +0 -161
  386. package/test/fixtures/integration-test.html.fixture +0 -103
  387. package/test/fixtures/integration-test.md.expected +0 -257
  388. package/test/parsers/ConfluenceParser.test.ts +0 -452
  389. package/test/schemas/ConfluencePreprocessor.test.ts +0 -180
  390. package/test/schemas/ConversionSchema.test.ts +0 -159
  391. package/test/schemas/HastSchema.test.ts +0 -138
  392. package/test/schemas/MdastSchema.test.ts +0 -145
  393. package/test/schemas/nodes/block/BlockSchema.test.ts +0 -173
  394. package/test/schemas/nodes/inline/InlineSchema.test.ts +0 -198
  395. package/test/schemas/nodes/macro/MacroSchema.test.ts +0 -142
@@ -1,543 +0,0 @@
1
- /**
2
- * Serializer for AST to Markdown.
3
- *
4
- * @module
5
- */
6
- import * as Effect from "effect/Effect"
7
- import type { CodeBlock, Heading, Image, Paragraph, Table, ThematicBreak, UnsupportedBlock } from "../ast/BlockNode.js"
8
- import type { Document, DocumentNode } from "../ast/Document.js"
9
- import type { InlineNode } from "../ast/InlineNode.js"
10
- import type { SerializeError } from "../SchemaConverterError.js"
11
-
12
- /**
13
- * Serialize Document AST to Markdown.
14
- *
15
- * @example
16
- * ```typescript
17
- * import { serializeToMarkdown } from "@knpkv/confluence-to-markdown/serializers/MarkdownSerializer"
18
- * import { makeDocument, Heading, Text } from "@knpkv/confluence-to-markdown/ast"
19
- * import { Effect } from "effect"
20
- *
21
- * Effect.gen(function* () {
22
- * const doc = makeDocument([
23
- * new Heading({ level: 1, children: [new Text({ value: "Title" })] })
24
- * ])
25
- * const md = yield* serializeToMarkdown(doc)
26
- * console.log(md) // # Title
27
- * })
28
- * ```
29
- *
30
- * @category Serializers
31
- */
32
- export interface SerializeOptions {
33
- /** Include raw Confluence HTML for lossless roundtrip. Default: true */
34
- readonly includeRawSource?: boolean
35
- }
36
-
37
- export const serializeToMarkdown = (
38
- doc: Document,
39
- options: SerializeOptions = {}
40
- ): Effect.Effect<string, SerializeError> =>
41
- Effect.gen(function*() {
42
- const { includeRawSource = true } = options
43
- const parts: Array<string> = []
44
- for (const node of doc.children) {
45
- const serialized = yield* serializeDocumentNode(node)
46
- parts.push(serialized)
47
- }
48
-
49
- const content = parts.join("\n\n")
50
-
51
- // Embed rawConfluence in comment for 1-to-1 roundtrip preservation
52
- if (includeRawSource && doc.rawConfluence !== undefined) {
53
- // Encode entire raw HTML for roundtrip
54
- const encoded = Buffer.from(doc.rawConfluence, "utf-8").toString("base64")
55
- return `${content}\n\n<!--cf:raw:${encoded}-->`
56
- }
57
-
58
- return content
59
- })
60
-
61
- /**
62
- * Serialize a document node to Markdown.
63
- */
64
- const serializeDocumentNode = (node: DocumentNode): Effect.Effect<string, SerializeError> =>
65
- Effect.gen(function*() {
66
- switch (node._tag) {
67
- // Block nodes
68
- case "Heading":
69
- return yield* serializeHeading(node)
70
- case "Paragraph":
71
- return yield* serializeParagraph({
72
- children: node.children,
73
- alignment: node.alignment,
74
- indent: node.indent
75
- })
76
- case "CodeBlock":
77
- return serializeCodeBlock(node)
78
- case "ThematicBreak":
79
- return "---"
80
- case "Image":
81
- return serializeImage(node)
82
- case "Table":
83
- return yield* serializeTable(node)
84
- case "List":
85
- return yield* serializeList(node)
86
- case "BlockQuote":
87
- return yield* serializeBlockQuote(node)
88
- case "UnsupportedBlock":
89
- return node.rawMarkdown || node.rawHtml || ""
90
-
91
- // Macro nodes
92
- case "InfoPanel":
93
- return yield* serializeInfoPanel(node)
94
- case "ExpandMacro":
95
- return yield* serializeExpandMacro(node)
96
- case "TocMacro":
97
- return serializeTocMacro(node)
98
- case "CodeMacro":
99
- return serializeCodeMacro(node)
100
- case "StatusMacro":
101
- return serializeStatusMacro(node)
102
- case "TaskList":
103
- return yield* serializeTaskList(node.children)
104
-
105
- default:
106
- return ""
107
- }
108
- })
109
-
110
- /**
111
- * Serialize heading.
112
- */
113
- const serializeHeading = (
114
- node: { level: 1 | 2 | 3 | 4 | 5 | 6; children: ReadonlyArray<InlineNode> }
115
- ): Effect.Effect<string, SerializeError> =>
116
- Effect.gen(function*() {
117
- const prefix = "#".repeat(node.level)
118
- const content = yield* serializeInlineNodes(node.children)
119
- return `${prefix} ${content}`
120
- })
121
-
122
- /**
123
- * Serialize paragraph.
124
- */
125
- const serializeParagraph = (
126
- node: {
127
- children: ReadonlyArray<InlineNode>
128
- alignment?: "left" | "center" | "right" | undefined
129
- indent?: number | undefined
130
- }
131
- ): Effect.Effect<string, SerializeError> =>
132
- Effect.gen(function*() {
133
- const content = yield* serializeInlineNodes(node.children)
134
- // If has alignment or indent, wrap in HTML div for roundtrip
135
- if (node.alignment || node.indent) {
136
- const styles: Array<string> = []
137
- if (node.alignment) styles.push(`text-align: ${node.alignment};`)
138
- if (node.indent) styles.push(`margin-left: ${node.indent}px;`)
139
- return `<p style="${styles.join(" ")}">${content}</p>`
140
- }
141
- return content
142
- })
143
-
144
- /**
145
- * Serialize code block.
146
- */
147
- const serializeCodeBlock = (node: { code: string; language?: string | undefined }): string => {
148
- const lang = node.language || ""
149
- return `\`\`\`${lang}\n${node.code}\n\`\`\``
150
- }
151
-
152
- /**
153
- * Serialize image (supports both URL and Confluence attachments).
154
- * Uses comment-encoding for attachments to preserve roundtrip fidelity.
155
- */
156
- const serializeImage = (node: {
157
- src?: string | undefined
158
- attachment?: { filename: string; version?: number | undefined } | undefined
159
- alt?: string | undefined
160
- title?: string | undefined
161
- align?: string | undefined
162
- width?: number | undefined
163
- }): string => {
164
- // If image has attachment or align/width, use comment encoding for roundtrip
165
- if (node.attachment || node.align || node.width) {
166
- const parts: Array<string> = []
167
- if (node.attachment) {
168
- parts.push(`f=${encodeURIComponent(node.attachment.filename)}`)
169
- if (node.attachment.version) parts.push(`v=${node.attachment.version}`)
170
- }
171
- if (node.src) parts.push(`s=${encodeURIComponent(node.src)}`)
172
- if (node.alt) parts.push(`a=${encodeURIComponent(node.alt)}`)
173
- if (node.title) parts.push(`t=${encodeURIComponent(node.title)}`)
174
- if (node.align) parts.push(`al=${node.align}`)
175
- if (node.width) parts.push(`w=${node.width}`)
176
- return `<!--cf:image:${parts.join("|")}-->`
177
- }
178
-
179
- // Simple external image - use markdown syntax
180
- const alt = node.alt || ""
181
- const title = node.title ? ` "${node.title}"` : ""
182
- const src = node.src || ""
183
- return `![${alt}](${src}${title})`
184
- }
185
-
186
- /**
187
- * Serialize table.
188
- */
189
- const serializeTable = (
190
- node: {
191
- header?: { cells: ReadonlyArray<{ children: ReadonlyArray<InlineNode> }> } | undefined
192
- rows: ReadonlyArray<{ cells: ReadonlyArray<{ children: ReadonlyArray<InlineNode> }> }>
193
- }
194
- ): Effect.Effect<string, SerializeError> =>
195
- Effect.gen(function*() {
196
- const lines: Array<string> = []
197
-
198
- // Markdown tables require a header divider. When the source had no <thead>,
199
- // emit a synthetic empty header so the table still renders. A leading
200
- // <!--cf:synth-thead--> marker discriminates it from a legitimate empty
201
- // header — MarkdownParser strips the marker and drops only that synthetic row,
202
- // so a real Confluence <thead> with empty <th>s round-trips intact.
203
- const columnCount = node.header?.cells.length ?? node.rows[0]?.cells.length ?? 0
204
- const synthMarker = "<!--cf:synth-thead-->"
205
- let prefix = ""
206
-
207
- if (node.header) {
208
- const headerCells: Array<string> = []
209
- for (const cell of node.header.cells) {
210
- headerCells.push(yield* serializeInlineNodes(cell.children))
211
- }
212
- lines.push(`| ${headerCells.join(" | ")} |`)
213
- lines.push(`| ${headerCells.map(() => "---").join(" | ")} |`)
214
- } else if (columnCount > 0) {
215
- prefix = `${synthMarker}\n\n`
216
- lines.push(`| ${Array(columnCount).fill("").join(" | ")} |`)
217
- lines.push(`| ${Array(columnCount).fill("---").join(" | ")} |`)
218
- }
219
-
220
- // Body rows
221
- for (const row of node.rows) {
222
- const cells: Array<string> = []
223
- for (const cell of row.cells) {
224
- cells.push(yield* serializeInlineNodes(cell.children))
225
- }
226
- lines.push(`| ${cells.join(" | ")} |`)
227
- }
228
-
229
- return `${prefix}${lines.join("\n")}`
230
- })
231
-
232
- // Simple block type for list items (allows nested Lists for sub-bullets).
233
- type SimpleBlock =
234
- | Heading
235
- | Paragraph
236
- | CodeBlock
237
- | ThematicBreak
238
- | Image
239
- | Table
240
- | UnsupportedBlock
241
- | NestedList
242
-
243
- // Structural shape of a nested list inside a list item.
244
- type NestedList = {
245
- readonly _tag: "List"
246
- readonly ordered: boolean
247
- readonly start?: number | undefined
248
- readonly children: ReadonlyArray<ListItemType>
249
- }
250
-
251
- // List item type
252
- type ListItemType = {
253
- readonly _tag: "ListItem"
254
- readonly checked?: boolean | undefined
255
- readonly children: ReadonlyArray<SimpleBlock>
256
- }
257
-
258
- /**
259
- * Serialize list.
260
- */
261
- const serializeList = (
262
- node: { ordered: boolean; start?: number | undefined; children: ReadonlyArray<ListItemType> }
263
- ): Effect.Effect<string, SerializeError> =>
264
- Effect.gen(function*() {
265
- const lines: Array<string> = []
266
- let counter = node.start || 1
267
-
268
- for (const item of node.children) {
269
- const prefix = node.ordered ? `${counter}.` : "-"
270
- const checkbox = item.checked !== undefined ? (item.checked ? "[x] " : "[ ] ") : ""
271
-
272
- // Serialize item content
273
- const itemParts: Array<string> = []
274
- for (const child of item.children) {
275
- const serialized = yield* serializeSimpleBlock(child)
276
- itemParts.push(serialized)
277
- }
278
-
279
- const content = itemParts.join("\n")
280
- const indentedContent = content
281
- .split("\n")
282
- .map((line, i) => (i === 0 ? `${prefix} ${checkbox}${line}` : ` ${line}`))
283
- .join("\n")
284
-
285
- lines.push(indentedContent)
286
- counter++
287
- }
288
-
289
- return lines.join("\n")
290
- })
291
-
292
- /**
293
- * Serialize simple block (for nested content).
294
- */
295
- const serializeSimpleBlock = (node: SimpleBlock): Effect.Effect<string, SerializeError> =>
296
- Effect.gen(function*() {
297
- switch (node._tag) {
298
- case "Heading":
299
- return yield* serializeHeading(
300
- node as unknown as { level: 1 | 2 | 3 | 4 | 5 | 6; children: ReadonlyArray<InlineNode> }
301
- )
302
- case "Paragraph":
303
- return yield* serializeParagraph(node as unknown as { children: ReadonlyArray<InlineNode> })
304
- case "CodeBlock":
305
- return serializeCodeBlock(node as unknown as { code: string; language?: string | undefined })
306
- case "ThematicBreak":
307
- return "---"
308
- case "Image":
309
- return serializeImage(node as unknown as { src: string; alt?: string | undefined; title?: string | undefined })
310
- case "Table":
311
- return yield* serializeTable(
312
- node as unknown as {
313
- header?: { cells: ReadonlyArray<{ children: ReadonlyArray<InlineNode> }> } | undefined
314
- rows: ReadonlyArray<{ cells: ReadonlyArray<{ children: ReadonlyArray<InlineNode> }> }>
315
- }
316
- )
317
- case "UnsupportedBlock": {
318
- const unsupported = node as unknown as { rawMarkdown?: string; rawHtml?: string }
319
- return unsupported.rawMarkdown || unsupported.rawHtml || ""
320
- }
321
- case "List":
322
- return yield* serializeList(node)
323
- default:
324
- return ""
325
- }
326
- })
327
-
328
- /**
329
- * Serialize block quote.
330
- */
331
- const serializeBlockQuote = (
332
- node: { children: ReadonlyArray<SimpleBlock> }
333
- ): Effect.Effect<string, SerializeError> =>
334
- Effect.gen(function*() {
335
- const lines: Array<string> = []
336
- for (const child of node.children) {
337
- const serialized = yield* serializeSimpleBlock(child as SimpleBlock)
338
- const quoted = serialized.split("\n").map((line) => `> ${line}`).join("\n")
339
- lines.push(quoted)
340
- }
341
- return lines.join("\n>\n")
342
- })
343
-
344
- /**
345
- * Serialize info panel to container syntax.
346
- */
347
- const serializeInfoPanel = (
348
- node: { panelType: string; title?: string | undefined; children: ReadonlyArray<SimpleBlock> }
349
- ): Effect.Effect<string, SerializeError> =>
350
- Effect.gen(function*() {
351
- const type = node.panelType
352
- const title = node.title ? ` ${node.title}` : ""
353
- const lines: Array<string> = [`:::${type}${title}`]
354
-
355
- for (const child of node.children) {
356
- const serialized = yield* serializeSimpleBlock(child as SimpleBlock)
357
- lines.push(serialized)
358
- }
359
-
360
- lines.push(":::")
361
- return lines.join("\n")
362
- })
363
-
364
- /**
365
- * Serialize expand macro as a GFM-compatible <details> block.
366
- *
367
- * The opening and closing HTML tags are recognised on round-trip by
368
- * MarkdownParser to rebuild the ExpandMacro AST node. Body content is rendered
369
- * as ordinary markdown so it shows up in viewers (Obsidian, GitHub, etc.).
370
- */
371
- const serializeExpandMacro = (
372
- node: { title?: string | undefined; children: ReadonlyArray<SimpleBlock> }
373
- ): Effect.Effect<string, SerializeError> =>
374
- Effect.gen(function*() {
375
- const title = node.title || ""
376
- const contentParts: Array<string> = []
377
-
378
- for (const child of node.children) {
379
- const serialized = yield* serializeSimpleBlock(child as SimpleBlock)
380
- contentParts.push(serialized)
381
- }
382
-
383
- const body = contentParts.join("\n\n")
384
- const summary = `<summary>${escapeHtml(title)}</summary>`
385
- return `<details>\n${summary}\n\n${body}\n\n</details>`
386
- })
387
-
388
- const escapeHtml = (s: string): string => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
389
-
390
- /**
391
- * Serialize TOC macro.
392
- */
393
- const serializeTocMacro = (_node: { minLevel?: number | undefined; maxLevel?: number | undefined }): string => {
394
- return "[[toc]]"
395
- }
396
-
397
- /**
398
- * Serialize code macro (similar to code block but may have title).
399
- */
400
- const serializeCodeMacro = (
401
- node: { language?: string | undefined; title?: string | undefined; code: string }
402
- ): string => {
403
- const lang = node.language || ""
404
- const title = node.title ? ` title="${node.title}"` : ""
405
- return `\`\`\`${lang}${title}\n${node.code}\n\`\`\``
406
- }
407
-
408
- /**
409
- * Serialize status macro.
410
- */
411
- const serializeStatusMacro = (node: { text: string; color: string }): string => {
412
- return `**[${node.text}]**`
413
- }
414
-
415
- /**
416
- * Serialize task list - preserve as comment-encoded for roundtrip (single line).
417
- */
418
- const serializeTaskList = (
419
- children: ReadonlyArray<{
420
- _tag: "TaskItem"
421
- id: string
422
- uuid: string
423
- status: "incomplete" | "complete"
424
- body: ReadonlyArray<InlineNode>
425
- }>
426
- ): Effect.Effect<string, SerializeError> =>
427
- Effect.gen(function*() {
428
- const items: Array<string> = []
429
- for (const item of children) {
430
- const body = yield* serializeInlineNodes(item.body)
431
- // Encode task item - use | separator to avoid : in content issues
432
- items.push(`${item.id}|${item.uuid}|${item.status}|${encodeURIComponent(body)}`)
433
- }
434
- // Single line comment to prevent remark from splitting
435
- return `<!--cf:tasklist:${items.join(";")}-->`
436
- })
437
-
438
- /**
439
- * Serialize inline nodes to Markdown.
440
- */
441
- const serializeInlineNodes = (
442
- nodes: ReadonlyArray<InlineNode>
443
- ): Effect.Effect<string, SerializeError> =>
444
- Effect.gen(function*() {
445
- const parts: Array<string> = []
446
- for (const node of nodes) {
447
- parts.push(yield* serializeInlineNode(node))
448
- }
449
- return parts.join("")
450
- })
451
-
452
- /**
453
- * Serialize inline node to Markdown.
454
- */
455
- const serializeInlineNode = (node: InlineNode): Effect.Effect<string, SerializeError> =>
456
- Effect.gen(function*() {
457
- switch (node._tag) {
458
- case "Text":
459
- return node.value
460
- case "Strong": {
461
- const content = yield* serializeInlineNodes(node.children)
462
- return `**${content}**`
463
- }
464
- case "Emphasis": {
465
- const content = yield* serializeInlineNodes(node.children)
466
- return `*${content}*`
467
- }
468
- case "Underline": {
469
- // No native markdown support, use HTML
470
- const content = yield* serializeInlineNodes(node.children)
471
- return `<u>${content}</u>`
472
- }
473
- case "Strikethrough": {
474
- const content = yield* serializeInlineNodes(node.children)
475
- return `~~${content}~~`
476
- }
477
- case "Subscript": {
478
- // No native markdown support, use HTML
479
- const content = yield* serializeInlineNodes(node.children)
480
- return `<sub>${content}</sub>`
481
- }
482
- case "Superscript": {
483
- // No native markdown support, use HTML
484
- const content = yield* serializeInlineNodes(node.children)
485
- return `<sup>${content}</sup>`
486
- }
487
- case "InlineCode":
488
- return `\`${node.value}\``
489
- case "Link": {
490
- const content = yield* serializeInlineNodes(node.children)
491
- const title = node.title ? ` "${node.title}"` : ""
492
- return `[${content}](${node.href}${title})`
493
- }
494
- case "LineBreak":
495
- return " \n"
496
- case "Emoticon":
497
- // Wrap in HTML comment with URL-encoded values
498
- return `<!--cf:emoticon:${encodeURIComponent(node.shortname)}|${encodeURIComponent(node.emojiId)}|${
499
- encodeURIComponent(node.fallback)
500
- }-->`
501
- case "UserMention":
502
- // Render as a markdown link so the mention is visible in viewers.
503
- // The #cf-user: URL fragment is the round-trip carrier — MarkdownParser
504
- // rebuilds the UserMention node when it sees a link with that prefix.
505
- return `[@${node.accountId}](#cf-user:${encodeURIComponent(node.accountId)})`
506
- case "DateTime":
507
- // Wrap in HTML comment to prevent remark from parsing
508
- return `<!--cf:date:${node.datetime}-->`
509
- case "ColoredText": {
510
- // Preserve as HTML for roundtrip
511
- const content = yield* serializeInlineNodes(node.children)
512
- return `<span style="color: ${node.color};">${content}</span>`
513
- }
514
- case "Highlight": {
515
- // Preserve as HTML for roundtrip
516
- const content = yield* serializeInlineNodes(node.children)
517
- return `<span style="background-color: ${node.backgroundColor};">${content}</span>`
518
- }
519
- case "UnsupportedInline": {
520
- // Some inline macros are stored as UnsupportedInline carrying a comment-
521
- // encoded round-trip marker. Rewrite the round-trippable ones as visible
522
- // markdown links so they show up in viewers; MarkdownParser reverses this.
523
- // The raw payload is already URL-encoded (ConfluenceParser uses
524
- // encodeURIComponent), so we decode the title for human-readable link
525
- // text and pass the encoded value through to the URL fragment as-is.
526
- const statusMatch = node.raw.match(/^<!--cf:status:([^;]*);([^;]*)-->$/)
527
- if (statusMatch) {
528
- const text = decodeURIComponent(statusMatch[1] ?? "")
529
- const color = statusMatch[2] ?? ""
530
- return `[${text}](#cf-status:${color})`
531
- }
532
- const tocMatch = node.raw.match(/^<!--cf:toc:([^;]*);([^;]*)-->$/)
533
- if (tocMatch) {
534
- const min = tocMatch[1] ?? ""
535
- const max = tocMatch[2] ?? ""
536
- return `[Table of Contents](#cf-toc:${min}:${max})`
537
- }
538
- return node.raw
539
- }
540
- default:
541
- return ""
542
- }
543
- })
@@ -1,8 +0,0 @@
1
- /**
2
- * Serializers for AST to Confluence HTML and Markdown.
3
- *
4
- * @module
5
- */
6
-
7
- export { serializeToConfluence } from "./ConfluenceSerializer.js"
8
- export { serializeToMarkdown } from "./MarkdownSerializer.js"