@knpkv/confluence-to-markdown 0.2.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +282 -14
- package/dist/ConfluenceAuth.d.ts +76 -0
- package/dist/ConfluenceAuth.d.ts.map +1 -0
- package/dist/ConfluenceAuth.js +356 -0
- package/dist/ConfluenceAuth.js.map +1 -0
- package/dist/ConfluenceClient.d.ts +26 -2
- package/dist/ConfluenceClient.d.ts.map +1 -1
- package/dist/ConfluenceClient.js +98 -92
- package/dist/ConfluenceClient.js.map +1 -1
- package/dist/ConfluenceConfig.d.ts +4 -24
- package/dist/ConfluenceConfig.d.ts.map +1 -1
- package/dist/ConfluenceConfig.js +45 -7
- package/dist/ConfluenceConfig.js.map +1 -1
- package/dist/ConfluenceError.d.ts +89 -6
- package/dist/ConfluenceError.d.ts.map +1 -1
- package/dist/ConfluenceError.js +88 -5
- package/dist/ConfluenceError.js.map +1 -1
- package/dist/GitError.d.ts +103 -0
- package/dist/GitError.d.ts.map +1 -0
- package/dist/GitError.js +85 -0
- package/dist/GitError.js.map +1 -0
- package/dist/GitService.d.ts +175 -0
- package/dist/GitService.d.ts.map +1 -0
- package/dist/GitService.js +431 -0
- package/dist/GitService.js.map +1 -0
- package/dist/LocalFileSystem.d.ts +29 -4
- package/dist/LocalFileSystem.d.ts.map +1 -1
- package/dist/LocalFileSystem.js +80 -6
- package/dist/LocalFileSystem.js.map +1 -1
- package/dist/MarkdownConverter.d.ts +49 -2
- package/dist/MarkdownConverter.d.ts.map +1 -1
- package/dist/MarkdownConverter.js +73 -111
- package/dist/MarkdownConverter.js.map +1 -1
- package/dist/SchemaConverterError.d.ts +108 -0
- package/dist/SchemaConverterError.d.ts.map +1 -0
- package/dist/SchemaConverterError.js +84 -0
- package/dist/SchemaConverterError.js.map +1 -0
- package/dist/Schemas.d.ts +225 -1
- package/dist/Schemas.d.ts.map +1 -1
- package/dist/Schemas.js +155 -6
- package/dist/Schemas.js.map +1 -1
- package/dist/SyncEngine.d.ts +30 -20
- package/dist/SyncEngine.d.ts.map +1 -1
- package/dist/SyncEngine.js +566 -117
- package/dist/SyncEngine.js.map +1 -1
- package/dist/ast/BlockNode.d.ts +468 -0
- package/dist/ast/BlockNode.d.ts.map +1 -0
- package/dist/ast/BlockNode.js +319 -0
- package/dist/ast/BlockNode.js.map +1 -0
- package/dist/ast/Document.d.ts +244 -0
- package/dist/ast/Document.d.ts.map +1 -0
- package/dist/ast/Document.js +69 -0
- package/dist/ast/Document.js.map +1 -0
- package/dist/ast/InlineNode.d.ts +477 -0
- package/dist/ast/InlineNode.d.ts.map +1 -0
- package/dist/ast/InlineNode.js +263 -0
- package/dist/ast/InlineNode.js.map +1 -0
- package/dist/ast/MacroNode.d.ts +267 -0
- package/dist/ast/MacroNode.d.ts.map +1 -0
- package/dist/ast/MacroNode.js +164 -0
- package/dist/ast/MacroNode.js.map +1 -0
- package/dist/ast/index.d.ts +10 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +14 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/bin.js +33 -149
- package/dist/bin.js.map +1 -1
- package/dist/commands/auth.d.ts +15 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +86 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/clone.d.ts +12 -0
- package/dist/commands/clone.d.ts.map +1 -0
- package/dist/commands/clone.js +93 -0
- package/dist/commands/clone.js.map +1 -0
- package/dist/commands/delete.d.ts +13 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +48 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/errorHandler.d.ts +14 -0
- package/dist/commands/errorHandler.d.ts.map +1 -0
- package/dist/commands/errorHandler.js +33 -0
- package/dist/commands/errorHandler.js.map +1 -0
- package/dist/commands/git.d.ts +22 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +72 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/index.d.ts +11 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +11 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/layers.d.ts +31 -0
- package/dist/commands/layers.d.ts.map +1 -0
- package/dist/commands/layers.js +137 -0
- package/dist/commands/layers.js.map +1 -0
- package/dist/commands/new.d.ts +9 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +80 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pageTree.d.ts +18 -0
- package/dist/commands/pageTree.d.ts.map +1 -0
- package/dist/commands/pageTree.js +20 -0
- package/dist/commands/pageTree.js.map +1 -0
- package/dist/commands/shared.d.ts +15 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +27 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/sync.d.ts +15 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +101 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/NodeLayers.d.ts +7 -0
- package/dist/internal/NodeLayers.d.ts.map +1 -0
- package/dist/internal/NodeLayers.js +19 -0
- package/dist/internal/NodeLayers.js.map +1 -0
- package/dist/internal/frontmatter.d.ts +10 -0
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +16 -0
- package/dist/internal/frontmatter.js.map +1 -1
- package/dist/internal/gitCommands.d.ts +78 -0
- package/dist/internal/gitCommands.d.ts.map +1 -0
- package/dist/internal/gitCommands.js +156 -0
- package/dist/internal/gitCommands.js.map +1 -0
- package/dist/internal/hashUtils.d.ts +42 -1
- package/dist/internal/hashUtils.d.ts.map +1 -1
- package/dist/internal/hashUtils.js +38 -2
- package/dist/internal/hashUtils.js.map +1 -1
- package/dist/internal/oauthServer.d.ts +55 -0
- package/dist/internal/oauthServer.d.ts.map +1 -0
- package/dist/internal/oauthServer.js +110 -0
- package/dist/internal/oauthServer.js.map +1 -0
- package/dist/internal/pathUtils.d.ts +21 -4
- package/dist/internal/pathUtils.d.ts.map +1 -1
- package/dist/internal/pathUtils.js +24 -13
- package/dist/internal/pathUtils.js.map +1 -1
- package/dist/internal/tokenStorage.d.ts +75 -0
- package/dist/internal/tokenStorage.d.ts.map +1 -0
- package/dist/internal/tokenStorage.js +149 -0
- package/dist/internal/tokenStorage.js.map +1 -0
- package/dist/internal/userCache.d.ts +42 -0
- package/dist/internal/userCache.d.ts.map +1 -0
- package/dist/internal/userCache.js +51 -0
- package/dist/internal/userCache.js.map +1 -0
- package/dist/parsers/ConfluenceParser.d.ts +26 -0
- package/dist/parsers/ConfluenceParser.d.ts.map +1 -0
- package/dist/parsers/ConfluenceParser.js +792 -0
- package/dist/parsers/ConfluenceParser.js.map +1 -0
- package/dist/parsers/MarkdownParser.d.ts +26 -0
- package/dist/parsers/MarkdownParser.d.ts.map +1 -0
- package/dist/parsers/MarkdownParser.js +873 -0
- package/dist/parsers/MarkdownParser.js.map +1 -0
- package/dist/parsers/index.d.ts +8 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +8 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/schemas/ConfluenceSchema.d.ts +21 -0
- package/dist/schemas/ConfluenceSchema.d.ts.map +1 -0
- package/dist/schemas/ConfluenceSchema.js +38 -0
- package/dist/schemas/ConfluenceSchema.js.map +1 -0
- package/dist/schemas/ConversionSchema.d.ts +35 -0
- package/dist/schemas/ConversionSchema.d.ts.map +1 -0
- package/dist/schemas/ConversionSchema.js +208 -0
- package/dist/schemas/ConversionSchema.js.map +1 -0
- package/dist/schemas/MarkdownSchema.d.ts +21 -0
- package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
- package/dist/schemas/MarkdownSchema.js +38 -0
- package/dist/schemas/MarkdownSchema.js.map +1 -0
- package/dist/schemas/hast/HastFromHtml.d.ts +27 -0
- package/dist/schemas/hast/HastFromHtml.d.ts.map +1 -0
- package/dist/schemas/hast/HastFromHtml.js +107 -0
- package/dist/schemas/hast/HastFromHtml.js.map +1 -0
- package/dist/schemas/hast/HastSchema.d.ts +195 -0
- package/dist/schemas/hast/HastSchema.d.ts.map +1 -0
- package/dist/schemas/hast/HastSchema.js +183 -0
- package/dist/schemas/hast/HastSchema.js.map +1 -0
- package/dist/schemas/hast/index.d.ts +9 -0
- package/dist/schemas/hast/index.d.ts.map +1 -0
- package/dist/schemas/hast/index.js +3 -0
- package/dist/schemas/hast/index.js.map +1 -0
- package/dist/schemas/index.d.ts +14 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +16 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/mdast/MdastFromMarkdown.d.ts +30 -0
- package/dist/schemas/mdast/MdastFromMarkdown.d.ts.map +1 -0
- package/dist/schemas/mdast/MdastFromMarkdown.js +79 -0
- package/dist/schemas/mdast/MdastFromMarkdown.js.map +1 -0
- package/dist/schemas/mdast/MdastSchema.d.ts +385 -0
- package/dist/schemas/mdast/MdastSchema.d.ts.map +1 -0
- package/dist/schemas/mdast/MdastSchema.js +266 -0
- package/dist/schemas/mdast/MdastSchema.js.map +1 -0
- package/dist/schemas/mdast/index.d.ts +10 -0
- package/dist/schemas/mdast/index.d.ts.map +1 -0
- package/dist/schemas/mdast/index.js +4 -0
- package/dist/schemas/mdast/index.js.map +1 -0
- package/dist/schemas/mdast/mdastToString.d.ts +13 -0
- package/dist/schemas/mdast/mdastToString.d.ts.map +1 -0
- package/dist/schemas/mdast/mdastToString.js +85 -0
- package/dist/schemas/mdast/mdastToString.js.map +1 -0
- package/dist/schemas/nodes/block/BlockSchema.d.ts +43 -0
- package/dist/schemas/nodes/block/BlockSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/block/BlockSchema.js +634 -0
- package/dist/schemas/nodes/block/BlockSchema.js.map +1 -0
- package/dist/schemas/nodes/block/index.d.ts +7 -0
- package/dist/schemas/nodes/block/index.d.ts.map +1 -0
- package/dist/schemas/nodes/block/index.js +7 -0
- package/dist/schemas/nodes/block/index.js.map +1 -0
- package/dist/schemas/nodes/index.d.ts +9 -0
- package/dist/schemas/nodes/index.d.ts.map +1 -0
- package/dist/schemas/nodes/index.js +12 -0
- package/dist/schemas/nodes/index.js.map +1 -0
- package/dist/schemas/nodes/inline/InlineSchema.d.ts +48 -0
- package/dist/schemas/nodes/inline/InlineSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/inline/InlineSchema.js +436 -0
- package/dist/schemas/nodes/inline/InlineSchema.js.map +1 -0
- package/dist/schemas/nodes/inline/index.d.ts +7 -0
- package/dist/schemas/nodes/inline/index.d.ts.map +1 -0
- package/dist/schemas/nodes/inline/index.js +7 -0
- package/dist/schemas/nodes/inline/index.js.map +1 -0
- package/dist/schemas/nodes/macro/MacroSchema.d.ts +27 -0
- package/dist/schemas/nodes/macro/MacroSchema.d.ts.map +1 -0
- package/dist/schemas/nodes/macro/MacroSchema.js +162 -0
- package/dist/schemas/nodes/macro/MacroSchema.js.map +1 -0
- package/dist/schemas/nodes/macro/index.d.ts +7 -0
- package/dist/schemas/nodes/macro/index.d.ts.map +1 -0
- package/dist/schemas/nodes/macro/index.js +7 -0
- package/dist/schemas/nodes/macro/index.js.map +1 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +24 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +1 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js +351 -0
- package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +1 -0
- package/dist/schemas/preprocessing/index.d.ts +8 -0
- package/dist/schemas/preprocessing/index.d.ts.map +1 -0
- package/dist/schemas/preprocessing/index.js +2 -0
- package/dist/schemas/preprocessing/index.js.map +1 -0
- package/dist/serializers/ConfluenceSerializer.d.ts +30 -0
- package/dist/serializers/ConfluenceSerializer.d.ts.map +1 -0
- package/dist/serializers/ConfluenceSerializer.js +551 -0
- package/dist/serializers/ConfluenceSerializer.js.map +1 -0
- package/dist/serializers/MarkdownSerializer.d.ts +34 -0
- package/dist/serializers/MarkdownSerializer.d.ts.map +1 -0
- package/dist/serializers/MarkdownSerializer.js +355 -0
- package/dist/serializers/MarkdownSerializer.js.map +1 -0
- package/dist/serializers/index.d.ts +8 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/index.js +8 -0
- package/dist/serializers/index.js.map +1 -0
- package/package.json +27 -16
- package/src/ConfluenceAuth.ts +571 -0
- package/src/ConfluenceClient.ts +188 -156
- package/src/ConfluenceConfig.ts +63 -7
- package/src/ConfluenceError.ts +110 -14
- package/src/GitError.ts +92 -0
- package/src/GitService.ts +859 -0
- package/src/LocalFileSystem.ts +179 -9
- package/src/MarkdownConverter.ts +126 -122
- package/src/SchemaConverterError.ts +108 -0
- package/src/Schemas.ts +223 -6
- package/src/SyncEngine.ts +745 -162
- package/src/ast/BlockNode.ts +425 -0
- package/src/ast/Document.ts +90 -0
- package/src/ast/InlineNode.ts +323 -0
- package/src/ast/MacroNode.ts +245 -0
- package/src/ast/index.ts +83 -0
- package/src/bin.ts +50 -249
- package/src/commands/auth.ts +117 -0
- package/src/commands/clone.ts +145 -0
- package/src/commands/delete.ts +57 -0
- package/src/commands/errorHandler.ts +32 -0
- package/src/commands/git.ts +114 -0
- package/src/commands/index.ts +10 -0
- package/src/commands/layers.ts +211 -0
- package/src/commands/new.ts +99 -0
- package/src/commands/pageTree.ts +40 -0
- package/src/commands/shared.ts +35 -0
- package/src/commands/sync.ts +129 -0
- package/src/index.ts +21 -1
- package/src/internal/NodeLayers.ts +21 -0
- package/src/internal/frontmatter.ts +21 -0
- package/src/internal/gitCommands.ts +229 -0
- package/src/internal/hashUtils.ts +65 -3
- package/src/internal/oauthServer.ts +199 -0
- package/src/internal/pathUtils.ts +34 -17
- package/src/internal/tokenStorage.ts +240 -0
- package/src/internal/userCache.ts +90 -0
- package/src/parsers/ConfluenceParser.ts +950 -0
- package/src/parsers/MarkdownParser.ts +1198 -0
- package/src/parsers/index.ts +8 -0
- package/src/schemas/ConfluenceSchema.ts +56 -0
- package/src/schemas/ConversionSchema.ts +318 -0
- package/src/schemas/MarkdownSchema.ts +56 -0
- package/src/schemas/hast/HastFromHtml.ts +153 -0
- package/src/schemas/hast/HastSchema.ts +274 -0
- package/src/schemas/hast/index.ts +35 -0
- package/src/schemas/index.ts +20 -0
- package/src/schemas/mdast/MdastFromMarkdown.ts +118 -0
- package/src/schemas/mdast/MdastSchema.ts +566 -0
- package/src/schemas/mdast/index.ts +59 -0
- package/src/schemas/mdast/mdastToString.ts +102 -0
- package/src/schemas/nodes/block/BlockSchema.ts +773 -0
- package/src/schemas/nodes/block/index.ts +13 -0
- package/src/schemas/nodes/index.ts +20 -0
- package/src/schemas/nodes/inline/InlineSchema.ts +523 -0
- package/src/schemas/nodes/inline/index.ts +14 -0
- package/src/schemas/nodes/macro/MacroSchema.ts +226 -0
- package/src/schemas/nodes/macro/index.ts +6 -0
- package/src/schemas/preprocessing/ConfluencePreprocessor.ts +446 -0
- package/src/schemas/preprocessing/index.ts +8 -0
- package/src/serializers/ConfluenceSerializer.ts +717 -0
- package/src/serializers/MarkdownSerializer.ts +493 -0
- package/src/serializers/index.ts +8 -0
- package/test/GitService.test.ts +209 -0
- package/test/MarkdownConverter.test.ts +37 -3
- package/test/Schemas.test.ts +97 -2
- package/test/ast/BlockNode.test.ts +265 -0
- package/test/ast/Document.test.ts +126 -0
- package/test/ast/InlineNode.test.ts +161 -0
- package/test/fixtures/integration-test.html.fixture +103 -0
- package/test/fixtures/integration-test.md.expected +257 -0
- package/test/integration.test.ts +269 -0
- package/test/oauthServer.test.ts +50 -0
- package/test/parsers/ConfluenceParser.test.ts +283 -0
- package/test/schemas/ConfluencePreprocessor.test.ts +180 -0
- package/test/schemas/ConversionSchema.test.ts +159 -0
- package/test/schemas/HastSchema.test.ts +138 -0
- package/test/schemas/MdastSchema.test.ts +145 -0
- package/test/schemas/nodes/block/BlockSchema.test.ts +173 -0
- package/test/schemas/nodes/inline/InlineSchema.test.ts +198 -0
- package/test/schemas/nodes/macro/MacroSchema.test.ts +142 -0
- package/test/tokenStorage.test.ts +99 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token storage for OAuth credentials.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import * as FileSystem from "@effect/platform/FileSystem"
|
|
7
|
+
import * as Path from "@effect/platform/Path"
|
|
8
|
+
import * as Context from "effect/Context"
|
|
9
|
+
import * as Effect from "effect/Effect"
|
|
10
|
+
import * as Layer from "effect/Layer"
|
|
11
|
+
import * as Schema from "effect/Schema"
|
|
12
|
+
import { FileSystemError } from "../ConfluenceError.js"
|
|
13
|
+
import { type OAuthConfig, OAuthConfigSchema, type OAuthToken, OAuthTokenSchema } from "../Schemas.js"
|
|
14
|
+
|
|
15
|
+
const TOKEN_DIR_NAME = ".confluence"
|
|
16
|
+
const TOKEN_FILE_NAME = "auth.json"
|
|
17
|
+
const CONFIG_FILE_NAME = "config.json"
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Service for getting the home directory.
|
|
21
|
+
* This allows mocking in tests.
|
|
22
|
+
*
|
|
23
|
+
* @category Services
|
|
24
|
+
*/
|
|
25
|
+
export interface HomeDirectory {
|
|
26
|
+
readonly get: () => Effect.Effect<string>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tag for the HomeDirectory service.
|
|
31
|
+
*
|
|
32
|
+
* @category Services
|
|
33
|
+
*/
|
|
34
|
+
export class HomeDirectoryTag extends Context.Tag("@knpkv/confluence-to-markdown/HomeDirectory")<
|
|
35
|
+
HomeDirectoryTag,
|
|
36
|
+
HomeDirectory
|
|
37
|
+
>() {}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Default implementation using process.env.HOME.
|
|
41
|
+
*
|
|
42
|
+
* @category Layers
|
|
43
|
+
*/
|
|
44
|
+
export const HomeDirectoryLive: Layer.Layer<HomeDirectoryTag> = Layer.succeed(
|
|
45
|
+
HomeDirectoryTag,
|
|
46
|
+
{
|
|
47
|
+
get: () => Effect.sync(() => process.env.HOME ?? process.env.USERPROFILE ?? "/")
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the token directory path.
|
|
53
|
+
*/
|
|
54
|
+
const getTokenDir = (): Effect.Effect<string, never, HomeDirectoryTag | Path.Path> =>
|
|
55
|
+
Effect.gen(function*() {
|
|
56
|
+
const homeDir = yield* HomeDirectoryTag
|
|
57
|
+
const path = yield* Path.Path
|
|
58
|
+
const home = yield* homeDir.get()
|
|
59
|
+
return path.join(home, TOKEN_DIR_NAME)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the token file path.
|
|
64
|
+
*/
|
|
65
|
+
const getTokenPath = (): Effect.Effect<string, never, HomeDirectoryTag | Path.Path> =>
|
|
66
|
+
Effect.gen(function*() {
|
|
67
|
+
const path = yield* Path.Path
|
|
68
|
+
const tokenDir = yield* getTokenDir()
|
|
69
|
+
return path.join(tokenDir, TOKEN_FILE_NAME)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get the config file path.
|
|
74
|
+
*/
|
|
75
|
+
const getConfigPath = (): Effect.Effect<string, never, HomeDirectoryTag | Path.Path> =>
|
|
76
|
+
Effect.gen(function*() {
|
|
77
|
+
const path = yield* Path.Path
|
|
78
|
+
const tokenDir = yield* getTokenDir()
|
|
79
|
+
return path.join(tokenDir, CONFIG_FILE_NAME)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Load stored OAuth token from disk.
|
|
84
|
+
*
|
|
85
|
+
* @returns The stored token or null if not found/invalid
|
|
86
|
+
*
|
|
87
|
+
* @category Token Storage
|
|
88
|
+
*/
|
|
89
|
+
export const loadToken = (): Effect.Effect<
|
|
90
|
+
OAuthToken | null,
|
|
91
|
+
FileSystemError,
|
|
92
|
+
FileSystem.FileSystem | Path.Path | HomeDirectoryTag
|
|
93
|
+
> =>
|
|
94
|
+
Effect.gen(function*() {
|
|
95
|
+
const fs = yield* FileSystem.FileSystem
|
|
96
|
+
const tokenPath = yield* getTokenPath()
|
|
97
|
+
|
|
98
|
+
const exists = yield* fs.exists(tokenPath).pipe(
|
|
99
|
+
Effect.catchAll(() => Effect.succeed(false))
|
|
100
|
+
)
|
|
101
|
+
if (!exists) {
|
|
102
|
+
return null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const content = yield* fs.readFileString(tokenPath).pipe(
|
|
106
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "read", path: tokenPath, cause }))
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
let parsed: unknown
|
|
110
|
+
try {
|
|
111
|
+
parsed = JSON.parse(content)
|
|
112
|
+
} catch {
|
|
113
|
+
return null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const decoded = yield* Schema.decodeUnknown(OAuthTokenSchema)(parsed).pipe(
|
|
117
|
+
Effect.catchAll(() => Effect.succeed(null))
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return decoded
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Save OAuth token to disk with secure permissions.
|
|
125
|
+
*
|
|
126
|
+
* @param token - The token to save
|
|
127
|
+
*
|
|
128
|
+
* @category Token Storage
|
|
129
|
+
*/
|
|
130
|
+
export const saveToken = (
|
|
131
|
+
token: OAuthToken
|
|
132
|
+
): Effect.Effect<void, FileSystemError, FileSystem.FileSystem | Path.Path | HomeDirectoryTag> =>
|
|
133
|
+
Effect.gen(function*() {
|
|
134
|
+
const fs = yield* FileSystem.FileSystem
|
|
135
|
+
const tokenDir = yield* getTokenDir()
|
|
136
|
+
const tokenPath = yield* getTokenPath()
|
|
137
|
+
|
|
138
|
+
yield* fs.makeDirectory(tokenDir, { recursive: true }).pipe(
|
|
139
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "mkdir", path: tokenDir, cause }))
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
yield* fs.writeFileString(tokenPath, JSON.stringify(token, null, 2)).pipe(
|
|
143
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "write", path: tokenPath, cause }))
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
// Set secure permissions (owner only)
|
|
147
|
+
yield* fs.chmod(tokenPath, 0o600).pipe(
|
|
148
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "write", path: tokenPath, cause }))
|
|
149
|
+
)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Delete stored OAuth token.
|
|
154
|
+
*
|
|
155
|
+
* @category Token Storage
|
|
156
|
+
*/
|
|
157
|
+
export const deleteToken = (): Effect.Effect<
|
|
158
|
+
void,
|
|
159
|
+
FileSystemError,
|
|
160
|
+
FileSystem.FileSystem | Path.Path | HomeDirectoryTag
|
|
161
|
+
> =>
|
|
162
|
+
Effect.gen(function*() {
|
|
163
|
+
const fs = yield* FileSystem.FileSystem
|
|
164
|
+
const tokenPath = yield* getTokenPath()
|
|
165
|
+
|
|
166
|
+
yield* fs.remove(tokenPath).pipe(
|
|
167
|
+
Effect.catchAll(() => Effect.void),
|
|
168
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "delete", path: tokenPath, cause }))
|
|
169
|
+
)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Load OAuth client configuration from disk.
|
|
174
|
+
*
|
|
175
|
+
* @returns The stored config or null if not found/invalid
|
|
176
|
+
*
|
|
177
|
+
* @category OAuth Config
|
|
178
|
+
*/
|
|
179
|
+
export const loadOAuthConfig = (): Effect.Effect<
|
|
180
|
+
OAuthConfig | null,
|
|
181
|
+
FileSystemError,
|
|
182
|
+
FileSystem.FileSystem | Path.Path | HomeDirectoryTag
|
|
183
|
+
> =>
|
|
184
|
+
Effect.gen(function*() {
|
|
185
|
+
const fs = yield* FileSystem.FileSystem
|
|
186
|
+
const configPath = yield* getConfigPath()
|
|
187
|
+
|
|
188
|
+
const exists = yield* fs.exists(configPath).pipe(
|
|
189
|
+
Effect.catchAll(() => Effect.succeed(false))
|
|
190
|
+
)
|
|
191
|
+
if (!exists) {
|
|
192
|
+
return null
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const content = yield* fs.readFileString(configPath).pipe(
|
|
196
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "read", path: configPath, cause }))
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
let parsed: unknown
|
|
200
|
+
try {
|
|
201
|
+
parsed = JSON.parse(content)
|
|
202
|
+
} catch {
|
|
203
|
+
return null
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const decoded = yield* Schema.decodeUnknown(OAuthConfigSchema)(parsed).pipe(
|
|
207
|
+
Effect.catchAll(() => Effect.succeed(null))
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return decoded
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Save OAuth client configuration to disk with secure permissions.
|
|
215
|
+
*
|
|
216
|
+
* @param config - The config to save
|
|
217
|
+
*
|
|
218
|
+
* @category OAuth Config
|
|
219
|
+
*/
|
|
220
|
+
export const saveOAuthConfig = (
|
|
221
|
+
config: OAuthConfig
|
|
222
|
+
): Effect.Effect<void, FileSystemError, FileSystem.FileSystem | Path.Path | HomeDirectoryTag> =>
|
|
223
|
+
Effect.gen(function*() {
|
|
224
|
+
const fs = yield* FileSystem.FileSystem
|
|
225
|
+
const tokenDir = yield* getTokenDir()
|
|
226
|
+
const configPath = yield* getConfigPath()
|
|
227
|
+
|
|
228
|
+
yield* fs.makeDirectory(tokenDir, { recursive: true }).pipe(
|
|
229
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "mkdir", path: tokenDir, cause }))
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
yield* fs.writeFileString(configPath, JSON.stringify(config, null, 2)).pipe(
|
|
233
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "write", path: configPath, cause }))
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
// Set secure permissions (owner only)
|
|
237
|
+
yield* fs.chmod(configPath, 0o600).pipe(
|
|
238
|
+
Effect.mapError((cause) => new FileSystemError({ operation: "write", path: configPath, cause }))
|
|
239
|
+
)
|
|
240
|
+
})
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory cache for Atlassian user info.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import * as Context from "effect/Context"
|
|
7
|
+
import * as Effect from "effect/Effect"
|
|
8
|
+
import * as Layer from "effect/Layer"
|
|
9
|
+
import * as Ref from "effect/Ref"
|
|
10
|
+
import type { AtlassianUser } from "../Schemas.js"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* User cache service for caching Atlassian user lookups.
|
|
14
|
+
*
|
|
15
|
+
* @category Cache
|
|
16
|
+
*/
|
|
17
|
+
export class UserCache extends Context.Tag("@knpkv/confluence-to-markdown/UserCache")<
|
|
18
|
+
UserCache,
|
|
19
|
+
{
|
|
20
|
+
/**
|
|
21
|
+
* Get user from cache, or fetch and cache if not present.
|
|
22
|
+
*/
|
|
23
|
+
readonly getOrFetch: (
|
|
24
|
+
accountId: string,
|
|
25
|
+
fetch: (accountId: string) => Effect.Effect<AtlassianUser, unknown>
|
|
26
|
+
) => Effect.Effect<AtlassianUser, unknown>
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get user from cache only (no fetch).
|
|
30
|
+
*/
|
|
31
|
+
readonly get: (accountId: string) => Effect.Effect<AtlassianUser | undefined>
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Put user into cache.
|
|
35
|
+
*/
|
|
36
|
+
readonly put: (accountId: string, user: AtlassianUser) => Effect.Effect<void>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Clear the cache.
|
|
40
|
+
*/
|
|
41
|
+
readonly clear: () => Effect.Effect<void>
|
|
42
|
+
}
|
|
43
|
+
>() {}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create the user cache service.
|
|
47
|
+
*/
|
|
48
|
+
const make = Effect.gen(function*() {
|
|
49
|
+
const cache = yield* Ref.make<Map<string, AtlassianUser>>(new Map())
|
|
50
|
+
|
|
51
|
+
const get = (accountId: string): Effect.Effect<AtlassianUser | undefined> =>
|
|
52
|
+
Ref.get(cache).pipe(Effect.map((m) => m.get(accountId)))
|
|
53
|
+
|
|
54
|
+
const put = (accountId: string, user: AtlassianUser): Effect.Effect<void> =>
|
|
55
|
+
Ref.update(cache, (m) => {
|
|
56
|
+
const newMap = new Map(m)
|
|
57
|
+
newMap.set(accountId, user)
|
|
58
|
+
return newMap
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const getOrFetch = <E>(
|
|
62
|
+
accountId: string,
|
|
63
|
+
fetch: (accountId: string) => Effect.Effect<AtlassianUser, E>
|
|
64
|
+
): Effect.Effect<AtlassianUser, E> =>
|
|
65
|
+
Effect.gen(function*() {
|
|
66
|
+
const cached = yield* get(accountId)
|
|
67
|
+
if (cached) {
|
|
68
|
+
return cached
|
|
69
|
+
}
|
|
70
|
+
const user = yield* fetch(accountId)
|
|
71
|
+
yield* put(accountId, user)
|
|
72
|
+
return user
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const clear = (): Effect.Effect<void> => Ref.set(cache, new Map())
|
|
76
|
+
|
|
77
|
+
return UserCache.of({
|
|
78
|
+
getOrFetch,
|
|
79
|
+
get,
|
|
80
|
+
put,
|
|
81
|
+
clear
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Layer that provides UserCache.
|
|
87
|
+
*
|
|
88
|
+
* @category Layers
|
|
89
|
+
*/
|
|
90
|
+
export const UserCacheLayer: Layer.Layer<UserCache> = Layer.effect(UserCache, make)
|