@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
package/src/Brand.ts CHANGED
@@ -26,9 +26,8 @@ export type PageId = string & Brand.Brand<"PageId">
26
26
  *
27
27
  * @category Brand
28
28
  */
29
- export const PageId = Brand.refined<PageId>(
30
- (s): s is PageId => typeof s === "string" && s.length > 0,
31
- (s) => Brand.error(`Invalid page ID: "${s}" (must be non-empty string)`)
29
+ export const PageId = Brand.make<PageId>((s) =>
30
+ typeof s === "string" && s.length > 0 || `Invalid page ID: "${s}" (must be non-empty string)`
32
31
  )
33
32
 
34
33
  /**
@@ -36,10 +35,7 @@ export const PageId = Brand.refined<PageId>(
36
35
  *
37
36
  * @category Schema
38
37
  */
39
- export const PageIdSchema = Schema.String.pipe(
40
- Schema.nonEmptyString(),
41
- Schema.brand("PageId")
42
- )
38
+ export const PageIdSchema = Schema.NonEmptyString.pipe(Schema.brand("PageId"))
43
39
 
44
40
  /**
45
41
  * Branded type for Confluence space keys.
@@ -60,9 +56,9 @@ export type SpaceKey = string & Brand.Brand<"SpaceKey">
60
56
  *
61
57
  * @category Brand
62
58
  */
63
- export const SpaceKey = Brand.refined<SpaceKey>(
64
- (s): s is SpaceKey => typeof s === "string" && s.length > 0 && /^[A-Z0-9]+$/.test(s),
65
- (s) => Brand.error(`Invalid space key: "${s}" (must be uppercase alphanumeric)`)
59
+ export const SpaceKey = Brand.make<SpaceKey>((s) =>
60
+ typeof s === "string" && s.length > 0 && /^[A-Z0-9]+$/.test(s)
61
+ || `Invalid space key: "${s}" (must be uppercase alphanumeric)`
66
62
  )
67
63
 
68
64
  /**
@@ -71,8 +67,7 @@ export const SpaceKey = Brand.refined<SpaceKey>(
71
67
  * @category Schema
72
68
  */
73
69
  export const SpaceKeySchema = Schema.String.pipe(
74
- Schema.nonEmptyString(),
75
- Schema.pattern(/^[A-Z0-9]+$/),
70
+ Schema.check(Schema.isNonEmpty(), Schema.isPattern(/^[A-Z0-9]+$/)),
76
71
  Schema.brand("SpaceKey")
77
72
  )
78
73
 
@@ -88,9 +83,9 @@ export type ContentHash = string & Brand.Brand<"ContentHash">
88
83
  *
89
84
  * @category Brand
90
85
  */
91
- export const ContentHash = Brand.refined<ContentHash>(
92
- (s): s is ContentHash => typeof s === "string" && /^[a-f0-9]{64}$/.test(s),
93
- (s) => Brand.error(`Invalid content hash: "${s}" (must be 64-char hex string)`)
86
+ export const ContentHash = Brand.make<ContentHash>((s) =>
87
+ typeof s === "string" && /^[a-f0-9]{64}$/.test(s)
88
+ || `Invalid content hash: "${s}" (must be 64-char hex string)`
94
89
  )
95
90
 
96
91
  /**
@@ -99,6 +94,6 @@ export const ContentHash = Brand.refined<ContentHash>(
99
94
  * @category Schema
100
95
  */
101
96
  export const ContentHashSchema = Schema.String.pipe(
102
- Schema.pattern(/^[a-f0-9]{64}$/),
97
+ Schema.check(Schema.isPattern(/^[a-f0-9]{64}$/)),
103
98
  Schema.brand("ContentHash")
104
99
  )
@@ -11,12 +11,7 @@
11
11
  *
12
12
  * @module
13
13
  */
14
- import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem"
15
- import * as NodePath from "@effect/platform-node/NodePath"
16
- import * as Command from "@effect/platform/Command"
17
- import * as CommandExecutor from "@effect/platform/CommandExecutor"
18
- import * as HttpClient from "@effect/platform/HttpClient"
19
- import * as HttpClientRequest from "@effect/platform/HttpClientRequest"
14
+ import * as NodeServices from "@effect/platform-node/NodeServices"
20
15
  import * as Console from "effect/Console"
21
16
  import * as Context from "effect/Context"
22
17
  import * as Deferred from "effect/Deferred"
@@ -25,6 +20,9 @@ import * as Layer from "effect/Layer"
25
20
  import * as Option from "effect/Option"
26
21
  import * as Ref from "effect/Ref"
27
22
  import * as Schema from "effect/Schema"
23
+ import { HttpClient, HttpClientRequest } from "effect/unstable/http"
24
+ import { ChildProcessSpawner } from "effect/unstable/process"
25
+ import * as ChildProcess from "effect/unstable/process/ChildProcess"
28
26
  import type { FileSystemError } from "./ConfluenceError.js"
29
27
  import { AuthMissingError, OAuthError } from "./ConfluenceError.js"
30
28
  import { HttpServerFactoryLive } from "./internal/NodeLayers.js"
@@ -41,8 +39,7 @@ import type { OAuthConfig, OAuthToken, OAuthUser } from "./Schemas.js"
41
39
 
42
40
  // Layer for token storage operations (FileSystem + Path + HomeDirectory)
43
41
  const TokenStorageLive = Layer.mergeAll(
44
- NodeFileSystem.layer,
45
- NodePath.layer,
42
+ NodeServices.layer,
46
43
  HomeDirectoryLive
47
44
  )
48
45
 
@@ -168,10 +165,10 @@ export interface ConfluenceAuthService {
168
165
  *
169
166
  * @category Services
170
167
  */
171
- export class ConfluenceAuth extends Context.Tag("@knpkv/confluence-to-markdown/ConfluenceAuth")<
168
+ export class ConfluenceAuth extends Context.Service<
172
169
  ConfluenceAuth,
173
170
  ConfluenceAuthService
174
- >() {}
171
+ >()("@knpkv/confluence-to-markdown/ConfluenceAuth") {}
175
172
 
176
173
  const buildAuthUrl = (clientId: string, state: string, port: number): string => {
177
174
  const params = new URLSearchParams({
@@ -195,7 +192,7 @@ const saveOAuthConfigOp = (config: OAuthConfig) => saveOAuthConfig(config).pipe(
195
192
 
196
193
  const make = Effect.gen(function*() {
197
194
  const httpClient = yield* HttpClient.HttpClient
198
- const commandExecutor = yield* CommandExecutor.CommandExecutor
195
+ const childProcessSpawner = yield* ChildProcessSpawner.ChildProcessSpawner
199
196
 
200
197
  // Ref to track ongoing refresh operation to prevent concurrent refreshes
201
198
  const refreshLock = yield* Ref.make<Option.Option<Deferred.Deferred<OAuthToken, OAuthError | FileSystemError>>>(
@@ -204,19 +201,14 @@ const make = Effect.gen(function*() {
204
201
 
205
202
  const openBrowserImpl = (url: string): Effect.Effect<void, OAuthError> =>
206
203
  Effect.gen(function*() {
207
- const platform = process.platform
208
- let command: Command.Command
209
-
210
- if (platform === "darwin") {
211
- command = Command.make("open", url)
212
- } else if (platform === "win32") {
213
- command = Command.make("cmd", "/c", "start", "", url)
214
- } else {
215
- command = Command.make("xdg-open", url)
216
- }
204
+ const run = (command: ChildProcess.Command) =>
205
+ childProcessSpawner.exitCode(command).pipe(
206
+ Effect.flatMap((code) => code === 0 ? Effect.void : Effect.fail(code))
207
+ )
217
208
 
218
- yield* Command.exitCode(command).pipe(
219
- Effect.provide(Layer.succeed(CommandExecutor.CommandExecutor, commandExecutor))
209
+ yield* run(ChildProcess.make("open", [url])).pipe(
210
+ Effect.catchIf(() => true, () => run(ChildProcess.make("xdg-open", [url]))),
211
+ Effect.catchIf(() => true, () => run(ChildProcess.make("rundll32.exe", ["url.dll,FileProtocolHandler", url])))
220
212
  )
221
213
  }).pipe(
222
214
  Effect.mapError((cause) => new OAuthError({ step: "authorize", cause }))
@@ -256,7 +248,7 @@ const make = Effect.gen(function*() {
256
248
  const response = yield* httpClient.execute(request)
257
249
  const body = yield* response.json
258
250
 
259
- return yield* Schema.decodeUnknown(TokenResponseSchema)(body)
251
+ return yield* Schema.decodeUnknownEffect(TokenResponseSchema)(body)
260
252
  }).pipe(
261
253
  Effect.mapError((cause) => new OAuthError({ step: "token", cause }))
262
254
  )
@@ -273,7 +265,7 @@ const make = Effect.gen(function*() {
273
265
  const response = yield* httpClient.execute(request)
274
266
  const body = yield* response.json
275
267
 
276
- return yield* Schema.decodeUnknown(Schema.Array(AccessibleResourceSchema))(body)
268
+ return yield* Schema.decodeUnknownEffect(Schema.Array(AccessibleResourceSchema))(body)
277
269
  }).pipe(
278
270
  Effect.mapError((cause) => new OAuthError({ step: "authorize", cause }))
279
271
  )
@@ -290,7 +282,7 @@ const make = Effect.gen(function*() {
290
282
  const response = yield* httpClient.execute(request)
291
283
  const body = yield* response.json
292
284
 
293
- return yield* Schema.decodeUnknown(UserInfoSchema)(body)
285
+ return yield* Schema.decodeUnknownEffect(UserInfoSchema)(body)
294
286
  }).pipe(
295
287
  Effect.mapError((cause) => new OAuthError({ step: "authorize", cause }))
296
288
  )
@@ -317,7 +309,7 @@ const make = Effect.gen(function*() {
317
309
  const body = yield* response.json.pipe(
318
310
  Effect.mapError((cause) => new OAuthError({ step: "refresh", cause }))
319
311
  )
320
- const tokenResponse = yield* Schema.decodeUnknown(TokenResponseSchema)(body).pipe(
312
+ const tokenResponse = yield* Schema.decodeUnknownEffect(TokenResponseSchema)(body).pipe(
321
313
  Effect.mapError((cause) => new OAuthError({ step: "refresh", cause }))
322
314
  )
323
315
 
@@ -389,7 +381,7 @@ const make = Effect.gen(function*() {
389
381
 
390
382
  const code = yield* codePromise.pipe(
391
383
  Effect.timeout("5 minutes"),
392
- Effect.catchTag("TimeoutException", () =>
384
+ Effect.catchTag("TimeoutError", () =>
393
385
  Effect.fail(new OAuthError({ step: "authorize", cause: "Authorization timed out" })))
394
386
  )
395
387
 
@@ -476,7 +468,7 @@ const make = Effect.gen(function*() {
476
468
  if (config !== null) {
477
469
  yield* revokeToken(token, config).pipe(
478
470
  Effect.tap(() => Effect.log("Token revoked with Atlassian")),
479
- Effect.catchAll((error) => Effect.log(`Warning: Failed to revoke token: ${error.message}`))
471
+ Effect.catchIf(() => true, (error) => Effect.log(`Warning: Failed to revoke token: ${error.message}`))
480
472
  )
481
473
  }
482
474
 
@@ -577,5 +569,5 @@ const make = Effect.gen(function*() {
577
569
  export const layer: Layer.Layer<
578
570
  ConfluenceAuth,
579
571
  never,
580
- HttpClient.HttpClient | CommandExecutor.CommandExecutor
572
+ HttpClient.HttpClient | ChildProcessSpawner.ChildProcessSpawner
581
573
  > = Layer.effect(ConfluenceAuth, make)
@@ -26,7 +26,7 @@ export interface CreatePageRequest {
26
26
  readonly title: string
27
27
  readonly parentId?: string
28
28
  readonly body: {
29
- readonly representation: "storage"
29
+ readonly representation: "atlas_doc_format"
30
30
  readonly value: string
31
31
  }
32
32
  }
@@ -45,7 +45,7 @@ export interface UpdatePageRequest {
45
45
  readonly message?: string
46
46
  }
47
47
  readonly body: {
48
- readonly representation: "storage"
48
+ readonly representation: "atlas_doc_format"
49
49
  readonly value: string
50
50
  }
51
51
  }
@@ -67,9 +67,7 @@ export interface UpdatePageRequest {
67
67
  *
68
68
  * @category Client
69
69
  */
70
- export class ConfluenceClient extends Context.Tag(
71
- "@knpkv/confluence-to-markdown/ConfluenceClient"
72
- )<
70
+ export class ConfluenceClient extends Context.Service<
73
71
  ConfluenceClient,
74
72
  {
75
73
  /**
@@ -126,7 +124,7 @@ export class ConfluenceClient extends Context.Tag(
126
124
  */
127
125
  readonly setEditorVersion: (pageId: PageId, version: "v1" | "v2") => Effect.Effect<void, ApiError | RateLimitError>
128
126
  }
129
- >() {}
127
+ >()("@knpkv/confluence-to-markdown/ConfluenceClient") {}
130
128
 
131
129
  /**
132
130
  * Configuration for the Confluence client.
@@ -155,11 +153,17 @@ const VERSIONS_PAGE_SIZE = 50
155
153
  /**
156
154
  * Rate limit retry schedule with exponential backoff.
157
155
  */
158
- const rateLimitSchedule = Schedule.exponential("1 second").pipe(
159
- Schedule.union(Schedule.spaced("30 seconds")),
160
- Schedule.whileInput<RateLimitError | ApiError>((error) => error._tag === "RateLimitError"),
161
- Schedule.intersect(Schedule.recurs(3))
162
- )
156
+ const rateLimitRetry = {
157
+ schedule: Schedule.exponential("1 second").pipe(
158
+ Schedule.either(Schedule.spaced("30 seconds"))
159
+ ),
160
+ times: 3,
161
+ while: (error: unknown) =>
162
+ typeof error === "object" &&
163
+ error !== null &&
164
+ "_tag" in error &&
165
+ error._tag === "RateLimitError"
166
+ } as const
163
167
 
164
168
  /**
165
169
  * Map API client errors to domain errors.
@@ -177,7 +181,7 @@ const mapApiError = (error: FetchClientError, endpoint: string, pageId?: string)
177
181
  */
178
182
  const make = (
179
183
  config: ConfluenceClientConfig
180
- ): Effect.Effect<Context.Tag.Service<typeof ConfluenceClient>> =>
184
+ ): Effect.Effect<Context.Service.Shape<typeof ConfluenceClient>> =>
181
185
  Effect.gen(function*() {
182
186
  // Create underlying API client
183
187
  const apiConfigLayer = Layer.succeed(ConfluenceApiConfig, {
@@ -194,10 +198,10 @@ const make = (
194
198
 
195
199
  const getPage = (id: PageId): Effect.Effect<PageResponse, ApiError | RateLimitError> =>
196
200
  toEffect(apiClient.v2.client.GET("/pages/{id}", {
197
- params: { path: { id: Number(id) }, query: { "body-format": "storage" } }
201
+ params: { path: { id: Number(id) }, query: { "body-format": "atlas_doc_format" } }
198
202
  })).pipe(
199
203
  Effect.mapError((e) => mapApiError(e, `/pages/${id}`, id)),
200
- Effect.retry(rateLimitSchedule)
204
+ Effect.retry(rateLimitRetry)
201
205
  ) as Effect.Effect<PageResponse, ApiError | RateLimitError>
202
206
 
203
207
  const getChildren = (id: PageId): Effect.Effect<PageChildrenResponse, ApiError | RateLimitError> =>
@@ -205,7 +209,7 @@ const make = (
205
209
  params: { path: { id: Number(id) } }
206
210
  })).pipe(
207
211
  Effect.mapError((e) => mapApiError(e, `/pages/${id}/children`, id)),
208
- Effect.retry(rateLimitSchedule)
212
+ Effect.retry(rateLimitRetry)
209
213
  ) as Effect.Effect<PageChildrenResponse, ApiError | RateLimitError>
210
214
 
211
215
  const getAllChildren = (id: PageId): Effect.Effect<ReadonlyArray<PageListItem>, ApiError | RateLimitError> =>
@@ -230,7 +234,7 @@ const make = (
230
234
  params: { path: { id: Number(id) }, query: { ...(cursor ? { cursor } : {}) } }
231
235
  })).pipe(
232
236
  Effect.mapError((e) => mapApiError(e, `/pages/${id}/children`, id)),
233
- Effect.retry(rateLimitSchedule)
237
+ Effect.retry(rateLimitRetry)
234
238
  )
235
239
 
236
240
  for (const child of (response as { results?: Array<PageListItem> }).results ?? []) {
@@ -260,7 +264,7 @@ const make = (
260
264
  }
261
265
  })).pipe(
262
266
  Effect.mapError((e) => mapApiError(e, "/pages")),
263
- Effect.retry(rateLimitSchedule)
267
+ Effect.retry(rateLimitRetry)
264
268
  ) as Effect.Effect<PageResponse, ApiError | RateLimitError>
265
269
 
266
270
  const updatePage = (req: UpdatePageRequest): Effect.Effect<PageResponse, ApiError | RateLimitError> =>
@@ -275,7 +279,7 @@ const make = (
275
279
  }
276
280
  })).pipe(
277
281
  Effect.mapError((e) => mapApiError(e, `/pages/${req.id}`, req.id)),
278
- Effect.retry(rateLimitSchedule)
282
+ Effect.retry(rateLimitRetry)
279
283
  ) as Effect.Effect<PageResponse, ApiError | RateLimitError>
280
284
 
281
285
  const deletePage = (id: PageId): Effect.Effect<void, ApiError | RateLimitError> =>
@@ -284,7 +288,7 @@ const make = (
284
288
  })).pipe(
285
289
  Effect.map(() => void 0),
286
290
  Effect.mapError((e) => mapApiError(e, `/pages/${id}`, id)),
287
- Effect.retry(rateLimitSchedule)
291
+ Effect.retry(rateLimitRetry)
288
292
  )
289
293
 
290
294
  const getPageVersions = (
@@ -312,14 +316,14 @@ const make = (
312
316
  params: {
313
317
  path: { id: Number(id) },
314
318
  query: {
315
- ...(options?.includeBody ? { "body-format": "storage" as const } : {}),
319
+ ...(options?.includeBody ? { "body-format": "atlas_doc_format" as const } : {}),
316
320
  ...(cursor ? { cursor } : {}),
317
321
  limit: VERSIONS_PAGE_SIZE
318
322
  }
319
323
  }
320
324
  })).pipe(
321
325
  Effect.mapError((e) => mapApiError(e, `/pages/${id}/versions`, id)),
322
- Effect.retry(rateLimitSchedule)
326
+ Effect.retry(rateLimitRetry)
323
327
  )
324
328
 
325
329
  for (const version of (response as { results?: Array<PageVersion> }).results ?? []) {
@@ -345,7 +349,7 @@ const make = (
345
349
  params: { query: { accountId } }
346
350
  })).pipe(
347
351
  Effect.mapError((e) => mapApiError(e, `/user?accountId=${accountId}`)),
348
- Effect.retry(rateLimitSchedule)
352
+ Effect.retry(rateLimitRetry)
349
353
  ) as Effect.Effect<AtlassianUser, ApiError | RateLimitError>
350
354
 
351
355
  const getSpaceId = (pageId: PageId): Effect.Effect<string, ApiError | RateLimitError> =>
@@ -401,7 +405,7 @@ const make = (
401
405
  Effect.mapError((e) => mapApiError(e, `/pages/${pageId}/properties/editor`, pageId))
402
406
  )
403
407
  }
404
- }).pipe(Effect.retry(rateLimitSchedule))
408
+ }).pipe(Effect.retry(rateLimitRetry))
405
409
 
406
410
  return ConfluenceClient.of({
407
411
  getPage,
@@ -438,7 +442,7 @@ const make = (
438
442
  * auth: {
439
443
  * type: "token",
440
444
  * email: "you@example.com",
441
- * token: process.env.CONFLUENCE_API_KEY
445
+ * token: "<api-token>"
442
446
  * }
443
447
  * }))
444
448
  * )
@@ -3,11 +3,11 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import * as FileSystem from "@effect/platform/FileSystem"
7
- import * as Path from "@effect/platform/Path"
8
6
  import * as Context from "effect/Context"
9
7
  import * as Effect from "effect/Effect"
8
+ import * as FileSystem from "effect/FileSystem"
10
9
  import * as Layer from "effect/Layer"
10
+ import * as Path from "effect/Path"
11
11
  import * as Schema from "effect/Schema"
12
12
  import type { PageId } from "./Brand.js"
13
13
  import { ConfigNotFoundError, ConfigParseError } from "./ConfluenceError.js"
@@ -31,9 +31,7 @@ import { ConfluenceConfigFileSchema } from "./Schemas.js"
31
31
  *
32
32
  * @category Config
33
33
  */
34
- export class ConfluenceConfig extends Context.Tag(
35
- "@knpkv/confluence-to-markdown/ConfluenceConfig"
36
- )<
34
+ export class ConfluenceConfig extends Context.Service<
37
35
  ConfluenceConfig,
38
36
  {
39
37
  /** Root page ID to sync from */
@@ -51,7 +49,7 @@ export class ConfluenceConfig extends Context.Tag(
51
49
  /** Glob patterns for files to track in git */
52
50
  readonly trackedPaths: ReadonlyArray<string>
53
51
  }
54
- >() {}
52
+ >()("@knpkv/confluence-to-markdown/ConfluenceConfig") {}
55
53
 
56
54
  /**
57
55
  * Default config directory.
@@ -73,7 +71,7 @@ const loadConfig = (
73
71
  const fs = yield* FileSystem.FileSystem
74
72
 
75
73
  const exists = yield* fs.exists(configPath).pipe(
76
- Effect.catchAll(() => Effect.succeed(false))
74
+ Effect.catchCause(() => Effect.succeed(false))
77
75
  )
78
76
  if (!exists) {
79
77
  return yield* Effect.fail(new ConfigNotFoundError({ path: configPath }))
@@ -88,7 +86,7 @@ const loadConfig = (
88
86
  catch: (cause) => new ConfigParseError({ path: configPath, cause })
89
87
  })
90
88
 
91
- return yield* Schema.decodeUnknown(ConfluenceConfigFileSchema)(json).pipe(
89
+ return yield* Schema.decodeUnknownEffect(ConfluenceConfigFileSchema)(json).pipe(
92
90
  Effect.mapError((cause) => new ConfigParseError({ path: configPath, cause }))
93
91
  )
94
92
  })
@@ -99,7 +97,7 @@ const loadConfig = (
99
97
  * @example
100
98
  * ```typescript
101
99
  * import { ConfluenceConfig } from "@knpkv/confluence-to-markdown/ConfluenceConfig"
102
- * import { NodeFileSystem } from "@effect/platform-node"
100
+ * import { NodeContext } from "@effect/platform-node"
103
101
  * import { Effect } from "effect"
104
102
  *
105
103
  * const program = Effect.gen(function* () {
@@ -110,7 +108,7 @@ const loadConfig = (
110
108
  * Effect.runPromise(
111
109
  * program.pipe(
112
110
  * Effect.provide(ConfluenceConfig.layer()),
113
- * Effect.provide(NodeFileSystem.layer)
111
+ * Effect.provide(NodeContext.layer)
114
112
  * )
115
113
  * )
116
114
  * ```
@@ -153,7 +151,8 @@ export const layer = (
153
151
  ConfluenceConfig,
154
152
  Effect.gen(function*() {
155
153
  const path = yield* Path.Path
156
- const resolvedPath = configPath ?? path.join(process.cwd(), CONFIG_DIR, CONFIG_FILE_NAME)
154
+ const cwd = path.resolve(".")
155
+ const resolvedPath = configPath ?? path.join(cwd, CONFIG_DIR, CONFIG_FILE_NAME)
157
156
  const config = yield* loadConfig(resolvedPath)
158
157
 
159
158
  // Validate docsPath
@@ -206,7 +205,8 @@ export const createConfigFile = (
206
205
  const fs = yield* FileSystem.FileSystem
207
206
  const pathService = yield* Path.Path
208
207
 
209
- const configDir = pathService.join(process.cwd(), CONFIG_DIR)
208
+ const cwd = pathService.resolve(".")
209
+ const configDir = pathService.join(cwd, CONFIG_DIR)
210
210
  const resolvedPath = configPath ?? pathService.join(configDir, CONFIG_FILE_NAME)
211
211
 
212
212
  const config: ConfluenceConfigFile = {
@@ -219,12 +219,12 @@ export const createConfigFile = (
219
219
  }
220
220
 
221
221
  // Validate the config
222
- yield* Schema.decodeUnknown(ConfluenceConfigFileSchema)(config).pipe(
222
+ yield* Schema.decodeUnknownEffect(ConfluenceConfigFileSchema)(config).pipe(
223
223
  Effect.mapError((cause) => new ConfigParseError({ path: resolvedPath, cause }))
224
224
  )
225
225
 
226
226
  // Create .confluence directory if it doesn't exist
227
- const dirExists = yield* fs.exists(configDir).pipe(Effect.catchAll(() => Effect.succeed(false)))
227
+ const dirExists = yield* fs.exists(configDir).pipe(Effect.catchCause(() => Effect.succeed(false)))
228
228
  if (!dirExists) {
229
229
  yield* fs.makeDirectory(configDir, { recursive: true }).pipe(
230
230
  Effect.mapError((cause) => new ConfigParseError({ path: configDir, cause }))
@@ -124,16 +124,23 @@ export class RateLimitError extends Data.TaggedError("RateLimitError")<{
124
124
  }
125
125
 
126
126
  /**
127
- * Error thrown when HTML/Markdown conversion fails.
127
+ * Direction of an ADF/Markdown conversion.
128
+ *
129
+ * @category Errors
130
+ */
131
+ export type ConversionDirection = "adfToMarkdown" | "markdownToAdf"
132
+
133
+ /**
134
+ * Error thrown when ADF/Markdown conversion fails.
128
135
  *
129
136
  * @category Errors
130
137
  */
131
138
  export class ConversionError extends Data.TaggedError("ConversionError")<{
132
- readonly direction: "htmlToMarkdown" | "markdownToHtml"
139
+ readonly direction: ConversionDirection
133
140
  readonly cause: unknown
134
141
  readonly message: string
135
142
  }> {
136
- constructor(params: { direction: "htmlToMarkdown" | "markdownToHtml"; cause: unknown }) {
143
+ constructor(params: { direction: ConversionDirection; cause: unknown }) {
137
144
  super({
138
145
  direction: params.direction,
139
146
  cause: params.cause,
@@ -142,6 +149,57 @@ export class ConversionError extends Data.TaggedError("ConversionError")<{
142
149
  }
143
150
  }
144
151
 
152
+ /**
153
+ * Issue produced by ADF JSON Schema validation.
154
+ *
155
+ * @category Errors
156
+ */
157
+ export interface AdfSchemaIssue {
158
+ readonly instancePath?: string
159
+ readonly schemaPath?: string
160
+ readonly keyword?: string
161
+ readonly message?: string
162
+ readonly params?: Record<string, unknown>
163
+ }
164
+
165
+ /**
166
+ * Error thrown when an ADF document fails JSON Schema validation.
167
+ *
168
+ * @category Errors
169
+ */
170
+ export class AdfSchemaError extends Data.TaggedError("AdfSchemaError")<{
171
+ readonly direction: "incoming" | "outgoing"
172
+ readonly issues: ReadonlyArray<AdfSchemaIssue>
173
+ readonly message: string
174
+ }> {
175
+ constructor(params: { direction: "incoming" | "outgoing"; issues: ReadonlyArray<AdfSchemaIssue> }) {
176
+ super({
177
+ direction: params.direction,
178
+ issues: params.issues,
179
+ message: `ADF schema validation failed (${params.direction}): ${params.issues.length} issue(s)`
180
+ })
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Error thrown when the wrapped @atlaskit transformer libraries throw.
186
+ *
187
+ * @category Errors
188
+ */
189
+ export class AtlaskitTransformersError extends Data.TaggedError("AtlaskitTransformersError")<{
190
+ readonly cause: unknown
191
+ readonly message: string
192
+ }> {
193
+ constructor(params: { cause: unknown }) {
194
+ super({
195
+ cause: params.cause,
196
+ message: `Atlaskit transformer failed: ${
197
+ params.cause instanceof Error ? params.cause.message : String(params.cause)
198
+ }`
199
+ })
200
+ }
201
+ }
202
+
145
203
  /**
146
204
  * Error thrown when sync conflict is detected.
147
205
  *
@@ -255,6 +313,8 @@ export type ConfluenceError =
255
313
  | ApiError
256
314
  | RateLimitError
257
315
  | ConversionError
316
+ | AdfSchemaError
317
+ | AtlaskitTransformersError
258
318
  | ConflictError
259
319
  | FileSystemError
260
320
  | OAuthError
@@ -281,6 +341,8 @@ export const isConfluenceError = (error: unknown): error is ConfluenceError =>
281
341
  "ApiError",
282
342
  "RateLimitError",
283
343
  "ConversionError",
344
+ "AdfSchemaError",
345
+ "AtlaskitTransformersError",
284
346
  "ConflictError",
285
347
  "FileSystemError",
286
348
  "OAuthError",