@knpkv/confluence-to-markdown 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +45 -10
  3. package/dist/ConfluenceAuth.d.ts.map +1 -1
  4. package/dist/ConfluenceAuth.js +12 -22
  5. package/dist/ConfluenceAuth.js.map +1 -1
  6. package/dist/ConfluenceClient.d.ts +13 -3
  7. package/dist/ConfluenceClient.d.ts.map +1 -1
  8. package/dist/ConfluenceClient.js +34 -70
  9. package/dist/ConfluenceClient.js.map +1 -1
  10. package/dist/ConfluenceError.d.ts +12 -12
  11. package/dist/GitError.d.ts +5 -5
  12. package/dist/GitService.d.ts.map +1 -1
  13. package/dist/GitService.js +0 -3
  14. package/dist/GitService.js.map +1 -1
  15. package/dist/SchemaConverterError.d.ts +3 -3
  16. package/dist/ast/BlockNode.d.ts +48 -33
  17. package/dist/ast/BlockNode.d.ts.map +1 -1
  18. package/dist/ast/BlockNode.js +11 -2
  19. package/dist/ast/BlockNode.js.map +1 -1
  20. package/dist/ast/Document.d.ts +30 -2
  21. package/dist/ast/Document.d.ts.map +1 -1
  22. package/dist/parsers/ConfluenceParser.d.ts.map +1 -1
  23. package/dist/parsers/ConfluenceParser.js +7 -12
  24. package/dist/parsers/ConfluenceParser.js.map +1 -1
  25. package/dist/parsers/MarkdownParser.js +8 -117
  26. package/dist/parsers/MarkdownParser.js.map +1 -1
  27. package/dist/parsers/preprocessing/ConfluencePreprocessing.d.ts +23 -0
  28. package/dist/parsers/preprocessing/ConfluencePreprocessing.d.ts.map +1 -0
  29. package/dist/parsers/preprocessing/ConfluencePreprocessing.js +323 -0
  30. package/dist/parsers/preprocessing/ConfluencePreprocessing.js.map +1 -0
  31. package/dist/parsers/preprocessing/index.d.ts +7 -0
  32. package/dist/parsers/preprocessing/index.d.ts.map +1 -0
  33. package/dist/parsers/preprocessing/index.js +7 -0
  34. package/dist/parsers/preprocessing/index.js.map +1 -0
  35. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +29 -0
  36. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +1 -1
  37. package/dist/schemas/preprocessing/ConfluencePreprocessor.js +5 -15
  38. package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +1 -1
  39. package/dist/serializers/ConfluenceSerializer.js +0 -9
  40. package/dist/serializers/ConfluenceSerializer.js.map +1 -1
  41. package/dist/serializers/MarkdownSerializer.js +9 -49
  42. package/dist/serializers/MarkdownSerializer.js.map +1 -1
  43. package/package.json +35 -26
  44. package/src/AdfPlaceholders.ts +266 -0
  45. package/src/AdfSchemaValidator.ts +67 -0
  46. package/src/AdfWalker.ts +511 -0
  47. package/src/AtlaskitTransformers.ts +72 -0
  48. package/src/ConfluenceClient.ts +4 -4
  49. package/src/ConfluenceError.ts +65 -3
  50. package/src/MarkdownConverter.ts +106 -139
  51. package/src/Schemas.ts +4 -4
  52. package/src/SyncEngine.ts +130 -83
  53. package/src/atlaskit-adf-schema.d.ts +3 -0
  54. package/src/commands/clone.ts +8 -1
  55. package/src/commands/layers.ts +11 -4
  56. package/src/index.ts +3 -18
  57. package/test/AdfPlaceholders.test.ts +295 -0
  58. package/test/AdfSchemaValidator.test.ts +34 -0
  59. package/test/AdfWalker.test.ts +530 -0
  60. package/test/AtlaskitTransformers.test.ts +25 -0
  61. package/test/MarkdownConverter.test.ts +120 -105
  62. package/test/RoundTrip.test.ts +266 -0
  63. package/LICENSE +0 -21
  64. package/src/SchemaConverterError.ts +0 -108
  65. package/src/ast/BlockNode.ts +0 -469
  66. package/src/ast/Document.ts +0 -90
  67. package/src/ast/InlineNode.ts +0 -323
  68. package/src/ast/MacroNode.ts +0 -245
  69. package/src/ast/index.ts +0 -83
  70. package/src/parsers/ConfluenceParser.ts +0 -956
  71. package/src/parsers/MarkdownParser.ts +0 -1338
  72. package/src/parsers/index.ts +0 -8
  73. package/src/schemas/ConfluenceSchema.ts +0 -56
  74. package/src/schemas/ConversionSchema.ts +0 -318
  75. package/src/schemas/MarkdownSchema.ts +0 -56
  76. package/src/schemas/hast/HastFromHtml.ts +0 -153
  77. package/src/schemas/hast/HastSchema.ts +0 -274
  78. package/src/schemas/hast/index.ts +0 -35
  79. package/src/schemas/index.ts +0 -20
  80. package/src/schemas/mdast/MdastFromMarkdown.ts +0 -118
  81. package/src/schemas/mdast/MdastSchema.ts +0 -566
  82. package/src/schemas/mdast/index.ts +0 -59
  83. package/src/schemas/mdast/mdastToString.ts +0 -102
  84. package/src/schemas/nodes/block/BlockSchema.ts +0 -773
  85. package/src/schemas/nodes/block/index.ts +0 -13
  86. package/src/schemas/nodes/index.ts +0 -20
  87. package/src/schemas/nodes/inline/InlineSchema.ts +0 -523
  88. package/src/schemas/nodes/inline/index.ts +0 -14
  89. package/src/schemas/nodes/macro/MacroSchema.ts +0 -226
  90. package/src/schemas/nodes/macro/index.ts +0 -6
  91. package/src/schemas/preprocessing/ConfluencePreprocessor.ts +0 -455
  92. package/src/schemas/preprocessing/index.ts +0 -8
  93. package/src/serializers/ConfluenceSerializer.ts +0 -737
  94. package/src/serializers/MarkdownSerializer.ts +0 -543
  95. package/src/serializers/index.ts +0 -8
  96. package/test/ast/BlockNode.test.ts +0 -265
  97. package/test/ast/Document.test.ts +0 -126
  98. package/test/ast/InlineNode.test.ts +0 -161
  99. package/test/fixtures/integration-test.html.fixture +0 -103
  100. package/test/fixtures/integration-test.md.expected +0 -257
  101. package/test/parsers/ConfluenceParser.test.ts +0 -452
  102. package/test/schemas/ConfluencePreprocessor.test.ts +0 -180
  103. package/test/schemas/ConversionSchema.test.ts +0 -159
  104. package/test/schemas/HastSchema.test.ts +0 -138
  105. package/test/schemas/MdastSchema.test.ts +0 -145
  106. package/test/schemas/nodes/block/BlockSchema.test.ts +0 -173
  107. package/test/schemas/nodes/inline/InlineSchema.test.ts +0 -198
  108. package/test/schemas/nodes/macro/MacroSchema.test.ts +0 -142
package/src/SyncEngine.ts CHANGED
@@ -101,6 +101,26 @@ type SyncError =
101
101
  | GitServiceError
102
102
  | StructureError
103
103
 
104
+ /**
105
+ * Pretty-print an ADF JSON wire string for the `.source.json` companion file.
106
+ * Falls back to the raw string if it can't be parsed as JSON.
107
+ */
108
+ const prettyAdf = (raw: string): string => {
109
+ try {
110
+ return JSON.stringify(JSON.parse(raw), null, 2)
111
+ } catch {
112
+ return raw
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Hash a markdown body in the form `readMarkdownFile` will later return it.
118
+ * `parseMarkdown` trims the body when reading, so the hash we store on
119
+ * frontmatter must hash the trimmed body too — otherwise every subsequent
120
+ * read sees a "changed" file and `push` keeps pushing a no-op update.
121
+ */
122
+ const hashBody = (markdown: string) => computeHash(markdown.trim()).pipe(Effect.provide(HashServiceLive))
123
+
104
124
  /**
105
125
  * Sync engine service for Confluence <-> Markdown operations.
106
126
  *
@@ -334,11 +354,9 @@ export const layer: Layer.Layer<
334
354
  position?: number
335
355
  ): Effect.Effect<{ markdown: string; frontMatter: PageFrontMatter }, SyncError> =>
336
356
  Effect.gen(function*() {
337
- const htmlContent = version.body?.storage?.value ?? ""
338
- const markdown = yield* converter.htmlToMarkdown(htmlContent, {
339
- includeRawSource: config.saveSource
340
- })
341
- const contentHash = yield* computeHash(markdown).pipe(Effect.provide(HashServiceLive))
357
+ const adfJson = version.body?.atlas_doc_format?.value ?? ""
358
+ const markdown = yield* converter.adfToMarkdown(adfJson)
359
+ const contentHash = yield* hashBody(markdown)
342
360
 
343
361
  // Get author info
344
362
  const author = version.authorId ? yield* getUser(version.authorId) : undefined
@@ -434,7 +452,7 @@ export const layer: Layer.Layer<
434
452
  }
435
453
 
436
454
  // Check if body content is available from the versions list
437
- const bodyContent = versionInfo.page?.body?.storage?.value
455
+ const bodyContent = versionInfo.page?.body?.atlas_doc_format?.value
438
456
  if (!bodyContent) {
439
457
  // No body content available - history replay not supported
440
458
  historyReplayFailed = true
@@ -448,9 +466,9 @@ export const layer: Layer.Layer<
448
466
  createdAt: versionInfo.createdAt,
449
467
  message: versionInfo.message,
450
468
  body: {
451
- storage: {
469
+ atlas_doc_format: {
452
470
  value: bodyContent,
453
- representation: "storage" as const
471
+ representation: "atlas_doc_format" as const
454
472
  }
455
473
  }
456
474
  }
@@ -465,10 +483,10 @@ export const layer: Layer.Layer<
465
483
  // Write file
466
484
  yield* localFs.writeMarkdownFile(filePath, frontMatter, markdown)
467
485
 
468
- // Save source HTML if configured
469
- if (config.saveSource && versionContent.body?.storage?.value) {
470
- const sourceFilePath = filePath.replace(/\.md$/, ".html")
471
- yield* localFs.writeFile(sourceFilePath, versionContent.body.storage.value)
486
+ // Save source ADF JSON if configured
487
+ if (config.saveSource && versionContent.body?.atlas_doc_format?.value) {
488
+ const sourceFilePath = filePath.replace(/\.md$/, ".source.json")
489
+ yield* localFs.writeFile(sourceFilePath, prettyAdf(versionContent.body.atlas_doc_format.value))
472
490
  }
473
491
 
474
492
  // Commit this version
@@ -501,10 +519,8 @@ export const layer: Layer.Layer<
501
519
  }
502
520
 
503
521
  // Simple pull without history replay
504
- const htmlContent = fullPage.body?.storage?.value ?? ""
505
- let markdown = yield* converter.htmlToMarkdown(htmlContent, {
506
- includeRawSource: config.saveSource
507
- })
522
+ const adfJson = fullPage.body?.atlas_doc_format?.value ?? ""
523
+ let markdown = yield* converter.adfToMarkdown(adfJson)
508
524
 
509
525
  // Add child page links for index pages
510
526
  if (hasChildren && config.spaceKey) {
@@ -517,7 +533,7 @@ export const layer: Layer.Layer<
517
533
  markdown = markdown.trim() + "\n\n## Child Pages\n\n" + childLinks + "\n"
518
534
  }
519
535
 
520
- const contentHash = yield* computeHash(markdown).pipe(Effect.provide(HashServiceLive))
536
+ const contentHash = yield* hashBody(markdown)
521
537
 
522
538
  // Get author info
523
539
  const author = fullPage.version.authorId ? yield* getUser(fullPage.version.authorId) : undefined
@@ -538,10 +554,10 @@ export const layer: Layer.Layer<
538
554
 
539
555
  yield* localFs.writeMarkdownFile(filePath, frontMatter, markdown)
540
556
 
541
- // Save source HTML if configured
542
- if (config.saveSource && htmlContent) {
543
- const sourceFilePath = filePath.replace(/\.md$/, ".html")
544
- yield* localFs.writeFile(sourceFilePath, htmlContent)
557
+ // Save source ADF JSON if configured
558
+ if (config.saveSource && adfJson) {
559
+ const sourceFilePath = filePath.replace(/\.md$/, ".source.json")
560
+ yield* localFs.writeFile(sourceFilePath, prettyAdf(adfJson))
545
561
  }
546
562
  }
547
563
 
@@ -576,31 +592,55 @@ export const layer: Layer.Layer<
576
592
  yield* git.checkout("origin/confluence")
577
593
  }
578
594
 
579
- const rootPage = yield* client.getPage(config.rootPageId)
580
- const result = yield* pullPage(rootPage, docsPath, options, gitInitialized)
595
+ const pullAndMerge = Effect.gen(function*() {
596
+ const rootPage = yield* client.getPage(config.rootPageId)
597
+ const result = yield* pullPage(rootPage, docsPath, options, gitInitialized)
581
598
 
582
- // If git is initialized and we have changes but didn't replay history, auto-commit
583
- if (gitInitialized && !options.replayHistory && result.pulled > 0) {
584
- yield* git.addAll()
585
- yield* git.commit({
586
- message: `Pull from Confluence (${result.pulled} page${result.pulled !== 1 ? "s" : ""})`
587
- }).pipe(Effect.catchTag("GitNoChangesError", () => Effect.void))
588
- }
599
+ // If git is initialized and we have changes but didn't replay history, auto-commit
600
+ if (gitInitialized && !options.replayHistory && result.pulled > 0) {
601
+ yield* git.addAll()
602
+ yield* git.commit({
603
+ message: `Pull from Confluence (${result.pulled} page${result.pulled !== 1 ? "s" : ""})`
604
+ }).pipe(Effect.catchTag("GitNoChangesError", () => Effect.void))
605
+ }
589
606
 
590
- // Two-branch model: merge origin/confluence into current branch
591
- if (hasRemoteBranch && originalBranch && originalBranch !== "origin/confluence") {
592
- yield* git.checkout(originalBranch)
593
- yield* git.merge("origin/confluence", {
594
- message: `Merge remote changes from Confluence`
595
- }).pipe(Effect.catchAll(() => Effect.void)) // May fail if no changes
596
- }
607
+ // Two-branch model: merge origin/confluence into current branch
608
+ if (hasRemoteBranch && originalBranch && originalBranch !== "origin/confluence") {
609
+ yield* git.checkout(originalBranch)
610
+ yield* git.merge("origin/confluence", {
611
+ message: `Merge remote changes from Confluence`
612
+ }).pipe(Effect.catchAll(() => Effect.void)) // May fail if no changes
613
+ }
597
614
 
598
- return {
599
- pulled: result.pulled,
600
- skipped: 0,
601
- commits: result.commits,
602
- errors: [] as ReadonlyArray<string>
603
- }
615
+ return {
616
+ pulled: result.pulled,
617
+ skipped: 0,
618
+ commits: result.commits,
619
+ errors: [] as ReadonlyArray<string>
620
+ }
621
+ })
622
+
623
+ // Any failure after the origin/confluence checkout (API, conversion,
624
+ // git) must not strand the repo on a detached HEAD — same protection
625
+ // as findUnpushedCommits. On success this re-checkout is a no-op.
626
+ // The restore itself can fail (a half-written pull leaves dirty files
627
+ // that differ between branches); that must be loud, not swallowed.
628
+ return yield* pullAndMerge.pipe(
629
+ Effect.ensuring(
630
+ hasRemoteBranch && originalBranch
631
+ ? git.checkout(originalBranch).pipe(
632
+ Effect.catchAll((error) =>
633
+ Effect.logWarning(
634
+ `pull: could not restore branch '${originalBranch}' — the repo may still be on origin/confluence. ` +
635
+ `Restore manually with \`git checkout ${originalBranch}\` (stash local changes first if needed). Cause: ${
636
+ String(error)
637
+ }`
638
+ )
639
+ )
640
+ )
641
+ : Effect.void
642
+ )
643
+ )
604
644
  })
605
645
 
606
646
  /**
@@ -641,8 +681,8 @@ export const layer: Layer.Layer<
641
681
  // Resolve parent from directory structure
642
682
  const parentId = yield* resolveParent(filePath, pageIdMap)
643
683
 
644
- // Convert markdown to HTML
645
- const html = yield* converter.markdownToHtml(localFile.content)
684
+ // Convert markdown to ADF
685
+ const adfValue = yield* converter.markdownToAdf(localFile.content)
646
686
 
647
687
  // Create the page
648
688
  const createdPage = yield* client.createPage({
@@ -650,8 +690,8 @@ export const layer: Layer.Layer<
650
690
  parentId,
651
691
  title,
652
692
  body: {
653
- representation: "storage",
654
- value: html
693
+ representation: "atlas_doc_format",
694
+ value: adfValue
655
695
  }
656
696
  })
657
697
 
@@ -665,11 +705,9 @@ export const layer: Layer.Layer<
665
705
 
666
706
  // Fetch canonical content back from Confluence
667
707
  const canonicalPage = yield* client.getPage(createdPage.id as PageId)
668
- const canonicalHtml = canonicalPage.body?.storage?.value ?? ""
669
- const canonicalMarkdown = yield* converter.htmlToMarkdown(canonicalHtml, {
670
- includeRawSource: config.saveSource
671
- })
672
- const canonicalHash = yield* computeHash(canonicalMarkdown).pipe(Effect.provide(HashServiceLive))
708
+ const canonicalAdf = canonicalPage.body?.atlas_doc_format?.value ?? ""
709
+ const canonicalMarkdown = yield* converter.adfToMarkdown(canonicalAdf)
710
+ const canonicalHash = yield* hashBody(canonicalMarkdown)
673
711
 
674
712
  // Write canonical content with full front-matter
675
713
  const newFrontMatter: PageFrontMatter = {
@@ -698,7 +736,7 @@ export const layer: Layer.Layer<
698
736
 
699
737
  // Fetch current version to avoid conflicts
700
738
  const remotePage = yield* client.getPage(fm.pageId)
701
- const html = yield* converter.markdownToHtml(localFile.content)
739
+ const adfValue = yield* converter.markdownToAdf(localFile.content)
702
740
  const updatedPage = yield* client.updatePage({
703
741
  id: fm.pageId,
704
742
  title: fm.title,
@@ -708,18 +746,16 @@ export const layer: Layer.Layer<
708
746
  message: revisionMessage
709
747
  },
710
748
  body: {
711
- representation: "storage",
712
- value: html
749
+ representation: "atlas_doc_format",
750
+ value: adfValue
713
751
  }
714
752
  })
715
753
 
716
754
  // Fetch canonical content back from Confluence
717
755
  const canonicalPage = yield* client.getPage(fm.pageId)
718
- const canonicalHtml = canonicalPage.body?.storage?.value ?? ""
719
- const canonicalMarkdown = yield* converter.htmlToMarkdown(canonicalHtml, {
720
- includeRawSource: config.saveSource
721
- })
722
- const canonicalHash = yield* computeHash(canonicalMarkdown).pipe(Effect.provide(HashServiceLive))
756
+ const canonicalAdf = canonicalPage.body?.atlas_doc_format?.value ?? ""
757
+ const canonicalMarkdown = yield* converter.adfToMarkdown(canonicalAdf)
758
+ const canonicalHash = yield* hashBody(canonicalMarkdown)
723
759
 
724
760
  // Write canonical content with updated front-matter
725
761
  const newFrontMatter: PageFrontMatter = {
@@ -759,34 +795,45 @@ export const layer: Layer.Layer<
759
795
  const allCommits = yield* git.log({ n: 100 })
760
796
  if (allCommits.length === 0) return []
761
797
 
762
- const unpushed: Array<{ hash: string; message: string }> = []
763
-
764
- for (const commit of allCommits) {
765
- yield* git.checkout(commit.hash)
766
-
767
- let hasChanges = false
768
- for (const filePath of files) {
769
- const exists = yield* localFs.exists(filePath)
770
- if (!exists) continue
798
+ // We checkout each commit to compare content; restore HEAD before returning
799
+ // so subsequent pushFile() calls see the working-tree content the user staged,
800
+ // not whatever commit we last inspected.
801
+ const originalBranch = yield* git.getCurrentBranch()
802
+
803
+ const collect = Effect.gen(function*() {
804
+ const unpushed: Array<{ hash: string; message: string }> = []
805
+ for (const commit of allCommits) {
806
+ yield* git.checkout(commit.hash)
807
+
808
+ let hasChanges = false
809
+ for (const filePath of files) {
810
+ const exists = yield* localFs.exists(filePath)
811
+ if (!exists) continue
812
+
813
+ const localFile = yield* localFs.readMarkdownFile(filePath)
814
+ if (!localFile.frontMatter) {
815
+ hasChanges = true
816
+ break
817
+ }
771
818
 
772
- const localFile = yield* localFs.readMarkdownFile(filePath)
773
- if (!localFile.frontMatter) {
774
- hasChanges = true
775
- break
819
+ const currentHash = yield* computeHash(localFile.content).pipe(Effect.provide(HashServiceLive))
820
+ if (currentHash !== localFile.frontMatter.contentHash) {
821
+ hasChanges = true
822
+ break
823
+ }
776
824
  }
777
825
 
778
- const currentHash = yield* computeHash(localFile.content).pipe(Effect.provide(HashServiceLive))
779
- if (currentHash !== localFile.frontMatter.contentHash) {
780
- hasChanges = true
781
- break
782
- }
826
+ if (!hasChanges) break
827
+ unpushed.push({ hash: commit.hash, message: commit.message })
783
828
  }
829
+ return unpushed.reverse()
830
+ })
784
831
 
785
- if (!hasChanges) break
786
- unpushed.push({ hash: commit.hash, message: commit.message })
787
- }
788
-
789
- return unpushed.reverse()
832
+ return yield* collect.pipe(
833
+ Effect.ensuring(
834
+ originalBranch ? git.checkout(originalBranch).pipe(Effect.ignore) : Effect.void
835
+ )
836
+ )
790
837
  })
791
838
 
792
839
  const push = (options: { dryRun: boolean; message?: string }): Effect.Effect<PushResult, SyncError> =>
@@ -0,0 +1,3 @@
1
+ declare module "@atlaskit/adf-schema/dist/cjs/schema/default-schema.js" {
2
+ export { defaultSchema, defaultSchemaConfig } from "@atlaskit/adf-schema/schema-default"
3
+ }
@@ -8,6 +8,8 @@ import * as Console from "effect/Console"
8
8
  import * as Effect from "effect/Effect"
9
9
  import * as Layer from "effect/Layer"
10
10
  import * as Option from "effect/Option"
11
+ import { layer as AdfSchemaValidatorLayer } from "../AdfSchemaValidator.js"
12
+ import { layer as AtlaskitTransformersLayer } from "../AtlaskitTransformers.js"
11
13
  import type { PageId } from "../Brand.js"
12
14
  import { type ConfluenceClientConfig, layer as ConfluenceClientLayer } from "../ConfluenceClient.js"
13
15
  import { createConfigFile, layerFromValues as ConfluenceConfigLayerFromValues } from "../ConfluenceConfig.js"
@@ -19,6 +21,11 @@ import { layer as MarkdownConverterLayer } from "../MarkdownConverter.js"
19
21
  import { layer as SyncEngineLayer, SyncEngine } from "../SyncEngine.js"
20
22
  import { getAuth } from "./shared.js"
21
23
 
24
+ const ConverterPipeline = MarkdownConverterLayer.pipe(
25
+ Layer.provide(AtlaskitTransformersLayer),
26
+ Layer.provide(AdfSchemaValidatorLayer)
27
+ )
28
+
22
29
  const rootPageIdOption = Options.text("root-page-id").pipe(
23
30
  Options.withDescription("Confluence root page ID to sync from"),
24
31
  Options.optional
@@ -115,7 +122,7 @@ export const cloneCommand = Command.make(
115
122
  Layer.provideMerge(UserCacheLayer),
116
123
  Layer.provideMerge(GitServiceLayer),
117
124
  Layer.provideMerge(clientLayer),
118
- Layer.provideMerge(MarkdownConverterLayer),
125
+ Layer.provideMerge(ConverterPipeline),
119
126
  Layer.provideMerge(LocalFileSystemLayer),
120
127
  Layer.provideMerge(configLayer),
121
128
  Layer.provideMerge(NodeContext.layer)
@@ -6,6 +6,8 @@ import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"
6
6
  import * as NodeTerminal from "@effect/platform-node/NodeTerminal"
7
7
  import * as Effect from "effect/Effect"
8
8
  import * as Layer from "effect/Layer"
9
+ import { layer as AdfSchemaValidatorLayer } from "../AdfSchemaValidator.js"
10
+ import { layer as AtlaskitTransformersLayer } from "../AtlaskitTransformers.js"
9
11
  import type { PageId } from "../Brand.js"
10
12
  import { ConfluenceAuth, layer as ConfluenceAuthLayer } from "../ConfluenceAuth.js"
11
13
  import { ConfluenceClient, type ConfluenceClientConfig, layer as ConfluenceClientLayer } from "../ConfluenceClient.js"
@@ -21,6 +23,11 @@ import { layer as MarkdownConverterLayer } from "../MarkdownConverter.js"
21
23
  import { layer as SyncEngineLayer, SyncEngine } from "../SyncEngine.js"
22
24
  import { getAuth } from "./shared.js"
23
25
 
26
+ const ConverterPipeline = MarkdownConverterLayer.pipe(
27
+ Layer.provide(AtlaskitTransformersLayer),
28
+ Layer.provide(AdfSchemaValidatorLayer)
29
+ )
30
+
24
31
  // Dummy config layer for help/init
25
32
  const DummyConfigLayer = ConfluenceConfigLayerFromValues({
26
33
  rootPageId: "dummy" as PageId,
@@ -136,7 +143,7 @@ export const AppLayer = SyncEngineLayer.pipe(
136
143
  Layer.provideMerge(UserCacheLayer),
137
144
  Layer.provideMerge(GitServiceLayer),
138
145
  Layer.provideMerge(ConfluenceClientLive),
139
- Layer.provideMerge(MarkdownConverterLayer),
146
+ Layer.provideMerge(ConverterPipeline),
140
147
  Layer.provideMerge(LocalFileSystemLayer),
141
148
  Layer.provideMerge(ConfluenceConfigLayer()),
142
149
  Layer.provideMerge(AuthLive),
@@ -152,7 +159,7 @@ export const AuthOnlyLayer = DummySyncEngineLayer.pipe(
152
159
  Layer.provideMerge(DummyGitServiceLayer),
153
160
  Layer.provideMerge(DummyConfluenceClientLayer),
154
161
  Layer.provideMerge(AuthLive),
155
- Layer.provideMerge(MarkdownConverterLayer),
162
+ Layer.provideMerge(ConverterPipeline),
156
163
  Layer.provideMerge(LocalFileSystemLayer),
157
164
  Layer.provideMerge(DummyConfigLayer),
158
165
  Layer.provideMerge(NodeHttpClient.layer),
@@ -167,7 +174,7 @@ export const MinimalLayer = DummySyncEngineLayer.pipe(
167
174
  Layer.provideMerge(GitServiceLayer),
168
175
  Layer.provideMerge(DummyConfluenceClientLayer),
169
176
  Layer.provideMerge(DummyConfluenceAuthLayer),
170
- Layer.provideMerge(MarkdownConverterLayer),
177
+ Layer.provideMerge(ConverterPipeline),
171
178
  Layer.provideMerge(LocalFileSystemLayer),
172
179
  Layer.provideMerge(DummyConfigLayer),
173
180
  Layer.provideMerge(NodeTerminal.layer),
@@ -182,7 +189,7 @@ export const CloneLayer = DummySyncEngineLayer.pipe(
182
189
  Layer.provideMerge(GitServiceLayer),
183
190
  Layer.provideMerge(DummyConfluenceClientLayer),
184
191
  Layer.provideMerge(AuthLive),
185
- Layer.provideMerge(MarkdownConverterLayer),
192
+ Layer.provideMerge(ConverterPipeline),
186
193
  Layer.provideMerge(LocalFileSystemLayer),
187
194
  Layer.provideMerge(DummyConfigLayer),
188
195
  Layer.provideMerge(NodeHttpClient.layer),
package/src/index.ts CHANGED
@@ -6,6 +6,9 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
 
9
+ export { AdfSchemaValidator, layer as AdfSchemaValidatorLayer } from "./AdfSchemaValidator.js"
10
+ export { type WalkerWarning, type WalkResult } from "./AdfWalker.js"
11
+ export { AtlaskitTransformers, layer as AtlaskitTransformersLayer, type Transformers } from "./AtlaskitTransformers.js"
9
12
  export * from "./Brand.js"
10
13
  export { ConfluenceAuth, type ConfluenceAuthService, layer as ConfluenceAuthLayer } from "./ConfluenceAuth.js"
11
14
  export {
@@ -35,21 +38,3 @@ export {
35
38
  SyncEngine,
36
39
  type SyncStatus
37
40
  } from "./SyncEngine.js"
38
-
39
- // AST types
40
- export * from "./ast/index.js"
41
-
42
- // Parsers
43
- export { parseConfluenceHtml } from "./parsers/ConfluenceParser.js"
44
- export { parseMarkdown } from "./parsers/MarkdownParser.js"
45
-
46
- // Serializers
47
- export { serializeToConfluence } from "./serializers/ConfluenceSerializer.js"
48
- export { serializeToMarkdown } from "./serializers/MarkdownSerializer.js"
49
-
50
- // Bi-directional schemas
51
- export { DocumentFromConfluence } from "./schemas/ConfluenceSchema.js"
52
- export { DocumentFromMarkdown } from "./schemas/MarkdownSchema.js"
53
-
54
- // Schema converter errors
55
- export { MigrationError, ParseError, SerializeError } from "./SchemaConverterError.js"