@knpkv/atlassian-common 0.2.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.
- package/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/Brand.d.ts +118 -0
- package/dist/Brand.d.ts.map +1 -0
- package/dist/Brand.js +107 -0
- package/dist/Brand.js.map +1 -0
- package/dist/Hash.d.ts +53 -0
- package/dist/Hash.d.ts.map +1 -0
- package/dist/Hash.js +63 -0
- package/dist/Hash.js.map +1 -0
- package/dist/SerializeError.d.ts +48 -0
- package/dist/SerializeError.d.ts.map +1 -0
- package/dist/SerializeError.js +42 -0
- package/dist/SerializeError.js.map +1 -0
- package/dist/ast/BlockNode.d.ts +429 -0
- package/dist/ast/BlockNode.d.ts.map +1 -0
- package/dist/ast/BlockNode.js +279 -0
- package/dist/ast/BlockNode.js.map +1 -0
- package/dist/ast/Document.d.ts +255 -0
- package/dist/ast/Document.d.ts.map +1 -0
- package/dist/ast/Document.js +80 -0
- package/dist/ast/Document.js.map +1 -0
- package/dist/ast/InlineNode.d.ts +483 -0
- package/dist/ast/InlineNode.d.ts.map +1 -0
- package/dist/ast/InlineNode.js +268 -0
- package/dist/ast/InlineNode.js.map +1 -0
- package/dist/ast/MacroNode.d.ts +214 -0
- package/dist/ast/MacroNode.d.ts.map +1 -0
- package/dist/ast/MacroNode.js +110 -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/auth/OAuthEndpoints.d.ts +95 -0
- package/dist/auth/OAuthEndpoints.d.ts.map +1 -0
- package/dist/auth/OAuthEndpoints.js +112 -0
- package/dist/auth/OAuthEndpoints.js.map +1 -0
- package/dist/auth/OAuthErrors.d.ts +76 -0
- package/dist/auth/OAuthErrors.d.ts.map +1 -0
- package/dist/auth/OAuthErrors.js +85 -0
- package/dist/auth/OAuthErrors.js.map +1 -0
- package/dist/auth/OAuthOperations.d.ts +87 -0
- package/dist/auth/OAuthOperations.d.ts.map +1 -0
- package/dist/auth/OAuthOperations.js +169 -0
- package/dist/auth/OAuthOperations.js.map +1 -0
- package/dist/auth/OAuthResponseSchemas.d.ts +65 -0
- package/dist/auth/OAuthResponseSchemas.d.ts.map +1 -0
- package/dist/auth/OAuthResponseSchemas.js +47 -0
- package/dist/auth/OAuthResponseSchemas.js.map +1 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +16 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/uuid.d.ts +14 -0
- package/dist/auth/uuid.d.ts.map +1 -0
- package/dist/auth/uuid.js +14 -0
- package/dist/auth/uuid.js.map +1 -0
- package/dist/config/ConfigPaths.d.ts +95 -0
- package/dist/config/ConfigPaths.d.ts.map +1 -0
- package/dist/config/ConfigPaths.js +102 -0
- package/dist/config/ConfigPaths.js.map +1 -0
- package/dist/config/OAuthSchemas.d.ts +144 -0
- package/dist/config/OAuthSchemas.d.ts.map +1 -0
- package/dist/config/OAuthSchemas.js +107 -0
- package/dist/config/OAuthSchemas.js.map +1 -0
- package/dist/config/TokenStorage.d.ts +96 -0
- package/dist/config/TokenStorage.d.ts.map +1 -0
- package/dist/config/TokenStorage.js +128 -0
- package/dist/config/TokenStorage.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/index.d.ts +7 -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/serializers/MarkdownSerializer.d.ts +63 -0
- package/dist/serializers/MarkdownSerializer.d.ts.map +1 -0
- package/dist/serializers/MarkdownSerializer.js +367 -0
- package/dist/serializers/MarkdownSerializer.js.map +1 -0
- package/dist/serializers/index.d.ts +7 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/index.js +7 -0
- package/dist/serializers/index.js.map +1 -0
- package/package.json +86 -0
- package/src/Brand.ts +142 -0
- package/src/Hash.ts +68 -0
- package/src/SerializeError.ts +50 -0
- package/src/ast/BlockNode.ts +386 -0
- package/src/ast/Document.ts +101 -0
- package/src/ast/InlineNode.ts +328 -0
- package/src/ast/MacroNode.ts +172 -0
- package/src/ast/index.ts +87 -0
- package/src/auth/OAuthEndpoints.ts +142 -0
- package/src/auth/OAuthErrors.ts +101 -0
- package/src/auth/OAuthOperations.ts +276 -0
- package/src/auth/OAuthResponseSchemas.ts +70 -0
- package/src/auth/index.ts +47 -0
- package/src/auth/uuid.ts +14 -0
- package/src/config/ConfigPaths.ts +179 -0
- package/src/config/OAuthSchemas.ts +146 -0
- package/src/config/TokenStorage.ts +228 -0
- package/src/config/index.ts +43 -0
- package/src/index.ts +34 -0
- package/src/parsers/index.ts +8 -0
- package/src/serializers/MarkdownSerializer.ts +498 -0
- package/src/serializers/index.ts +7 -0
- package/test/Brand.test.ts +90 -0
- package/test/MarkdownSerializer.test.ts +82 -0
- package/test/OAuthEndpoints.test.ts +109 -0
- package/test/OAuthOperations.test.ts +315 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline-level AST nodes for text content (emphasis, links, mentions, etc.).
|
|
3
|
+
*
|
|
4
|
+
* **Mental model**
|
|
5
|
+
*
|
|
6
|
+
* - **Leaf and recursive nodes**: `Text`, `InlineCode`, `LineBreak` are leaves;
|
|
7
|
+
* `Strong`, `Emphasis`, `Highlight` contain nested `InlineNode` children via `Schema.suspend`.
|
|
8
|
+
* - **Unsupported preservation**: {@link UnsupportedInline} captures raw content that can't be
|
|
9
|
+
* mapped, enabling non-destructive roundtrips.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import * as Schema from "effect/Schema"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Optional raw source HTML for exact roundtrip preservation.
|
|
17
|
+
*
|
|
18
|
+
* @category InlineNode
|
|
19
|
+
*/
|
|
20
|
+
export const RawSource = Schema.optional(Schema.String)
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Plain text content.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { Text } from "@knpkv/atlassian-common/ast"
|
|
28
|
+
*
|
|
29
|
+
* const text = new Text({ value: "Hello world" })
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @category InlineNode
|
|
33
|
+
*/
|
|
34
|
+
export class Text extends Schema.TaggedClass<Text>()("Text", {
|
|
35
|
+
value: Schema.String
|
|
36
|
+
}) {}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Inline code span.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { InlineCode } from "@knpkv/atlassian-common/ast"
|
|
44
|
+
*
|
|
45
|
+
* const code = new InlineCode({ value: "const x = 1" })
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @category InlineNode
|
|
49
|
+
*/
|
|
50
|
+
export class InlineCode extends Schema.TaggedClass<InlineCode>()("InlineCode", {
|
|
51
|
+
value: Schema.String
|
|
52
|
+
}) {}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Line break element.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* import { LineBreak } from "@knpkv/atlassian-common/ast"
|
|
60
|
+
*
|
|
61
|
+
* const br = new LineBreak({})
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @category InlineNode
|
|
65
|
+
*/
|
|
66
|
+
export class LineBreak extends Schema.TaggedClass<LineBreak>()("LineBreak", {}) {}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Unsupported inline element - preserves raw content for round-tripping.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* import { UnsupportedInline } from "@knpkv/atlassian-common/ast"
|
|
74
|
+
*
|
|
75
|
+
* const unknown = new UnsupportedInline({
|
|
76
|
+
* raw: "<custom-tag>content</custom-tag>",
|
|
77
|
+
* source: "confluence"
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @category InlineNode
|
|
82
|
+
*/
|
|
83
|
+
export class UnsupportedInline extends Schema.TaggedClass<UnsupportedInline>()("UnsupportedInline", {
|
|
84
|
+
raw: Schema.String,
|
|
85
|
+
source: Schema.Literal("confluence", "markdown", "adf")
|
|
86
|
+
}) {}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Emoticon/emoji element.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* import { Emoticon } from "@knpkv/atlassian-common/ast"
|
|
94
|
+
*
|
|
95
|
+
* const emoji = new Emoticon({
|
|
96
|
+
* shortname: ":grinning:",
|
|
97
|
+
* emojiId: "1f600",
|
|
98
|
+
* fallback: "grinning"
|
|
99
|
+
* })
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @category InlineNode
|
|
103
|
+
*/
|
|
104
|
+
export class Emoticon extends Schema.TaggedClass<Emoticon>()("Emoticon", {
|
|
105
|
+
shortname: Schema.String,
|
|
106
|
+
emojiId: Schema.String,
|
|
107
|
+
fallback: Schema.String,
|
|
108
|
+
rawSource: RawSource
|
|
109
|
+
}) {}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* User mention element.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* import { UserMention } from "@knpkv/atlassian-common/ast"
|
|
117
|
+
*
|
|
118
|
+
* const mention = new UserMention({ accountId: "557058:..." })
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @category InlineNode
|
|
122
|
+
*/
|
|
123
|
+
export class UserMention extends Schema.TaggedClass<UserMention>()("UserMention", {
|
|
124
|
+
accountId: Schema.String,
|
|
125
|
+
rawSource: RawSource
|
|
126
|
+
}) {}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Date/time element.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import { DateTime } from "@knpkv/atlassian-common/ast"
|
|
134
|
+
*
|
|
135
|
+
* const date = new DateTime({ datetime: "2026-01-01" })
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @category InlineNode
|
|
139
|
+
*/
|
|
140
|
+
export class DateTime extends Schema.TaggedClass<DateTime>()("DateTime", {
|
|
141
|
+
datetime: Schema.String,
|
|
142
|
+
rawSource: RawSource
|
|
143
|
+
}) {}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Underlined text.
|
|
147
|
+
*
|
|
148
|
+
* @category InlineNode
|
|
149
|
+
*/
|
|
150
|
+
export class Underline extends Schema.TaggedClass<Underline>()("Underline", {
|
|
151
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
152
|
+
}) {}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Subscript text.
|
|
156
|
+
*
|
|
157
|
+
* @category InlineNode
|
|
158
|
+
*/
|
|
159
|
+
export class Subscript extends Schema.TaggedClass<Subscript>()("Subscript", {
|
|
160
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
161
|
+
}) {}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Superscript text.
|
|
165
|
+
*
|
|
166
|
+
* @category InlineNode
|
|
167
|
+
*/
|
|
168
|
+
export class Superscript extends Schema.TaggedClass<Superscript>()("Superscript", {
|
|
169
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
170
|
+
}) {}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Strikethrough text.
|
|
174
|
+
*
|
|
175
|
+
* @category InlineNode
|
|
176
|
+
*/
|
|
177
|
+
export class Strikethrough extends Schema.TaggedClass<Strikethrough>()("Strikethrough", {
|
|
178
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
179
|
+
}) {}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Colored text with CSS color value.
|
|
183
|
+
*
|
|
184
|
+
* @category InlineNode
|
|
185
|
+
*/
|
|
186
|
+
export class ColoredText extends Schema.TaggedClass<ColoredText>()("ColoredText", {
|
|
187
|
+
color: Schema.String,
|
|
188
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
189
|
+
}) {}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Highlighted text with background color.
|
|
193
|
+
*
|
|
194
|
+
* @category InlineNode
|
|
195
|
+
*/
|
|
196
|
+
export class Highlight extends Schema.TaggedClass<Highlight>()("Highlight", {
|
|
197
|
+
backgroundColor: Schema.String,
|
|
198
|
+
children: Schema.suspend(() => Schema.Array(InlineNodeBase))
|
|
199
|
+
}) {}
|
|
200
|
+
|
|
201
|
+
// Forward declaration for recursive types
|
|
202
|
+
const InlineNodeBase = Schema.Union(
|
|
203
|
+
Text,
|
|
204
|
+
InlineCode,
|
|
205
|
+
LineBreak,
|
|
206
|
+
Emoticon,
|
|
207
|
+
UserMention,
|
|
208
|
+
DateTime,
|
|
209
|
+
UnsupportedInline
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Inline node children schema - use this for recursive inline content.
|
|
214
|
+
*
|
|
215
|
+
* @category InlineNode
|
|
216
|
+
*/
|
|
217
|
+
export const InlineNodeChildren: Schema.Schema<ReadonlyArray<InlineNode>> = Schema.suspend(
|
|
218
|
+
() => Schema.Array(InlineNode)
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Strong/bold text.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* import { Strong, Text } from "@knpkv/atlassian-common/ast"
|
|
227
|
+
*
|
|
228
|
+
* const bold = new Strong({ children: [new Text({ value: "important" })] })
|
|
229
|
+
* ```
|
|
230
|
+
*
|
|
231
|
+
* @category InlineNode
|
|
232
|
+
*/
|
|
233
|
+
export class Strong extends Schema.TaggedClass<Strong>()("Strong", {
|
|
234
|
+
children: Schema.suspend((): Schema.Schema<ReadonlyArray<InlineNode>> => Schema.Array(InlineNode))
|
|
235
|
+
}) {}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Emphasized/italic text.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* import { Emphasis, Text } from "@knpkv/atlassian-common/ast"
|
|
243
|
+
*
|
|
244
|
+
* const italic = new Emphasis({ children: [new Text({ value: "emphasized" })] })
|
|
245
|
+
* ```
|
|
246
|
+
*
|
|
247
|
+
* @category InlineNode
|
|
248
|
+
*/
|
|
249
|
+
export class Emphasis extends Schema.TaggedClass<Emphasis>()("Emphasis", {
|
|
250
|
+
children: Schema.suspend((): Schema.Schema<ReadonlyArray<InlineNode>> => Schema.Array(InlineNode))
|
|
251
|
+
}) {}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Hyperlink with optional title.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* import { Link, Text } from "@knpkv/atlassian-common/ast"
|
|
259
|
+
*
|
|
260
|
+
* const link = new Link({
|
|
261
|
+
* href: "https://example.com",
|
|
262
|
+
* title: "Example",
|
|
263
|
+
* children: [new Text({ value: "Click here" })]
|
|
264
|
+
* })
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* @category InlineNode
|
|
268
|
+
*/
|
|
269
|
+
export class Link extends Schema.TaggedClass<Link>()("Link", {
|
|
270
|
+
href: Schema.String,
|
|
271
|
+
title: Schema.optional(Schema.String),
|
|
272
|
+
children: Schema.suspend((): Schema.Schema<ReadonlyArray<InlineNode>> => Schema.Array(InlineNode)),
|
|
273
|
+
rawSource: RawSource
|
|
274
|
+
}) {}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Union of all inline node types.
|
|
278
|
+
*
|
|
279
|
+
* @category InlineNode
|
|
280
|
+
*/
|
|
281
|
+
export const InlineNode = Schema.Union(
|
|
282
|
+
Text,
|
|
283
|
+
Strong,
|
|
284
|
+
Emphasis,
|
|
285
|
+
InlineCode,
|
|
286
|
+
Link,
|
|
287
|
+
LineBreak,
|
|
288
|
+
Emoticon,
|
|
289
|
+
UserMention,
|
|
290
|
+
DateTime,
|
|
291
|
+
Underline,
|
|
292
|
+
Subscript,
|
|
293
|
+
Superscript,
|
|
294
|
+
Strikethrough,
|
|
295
|
+
ColoredText,
|
|
296
|
+
Highlight,
|
|
297
|
+
UnsupportedInline
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Type for inline nodes.
|
|
302
|
+
*
|
|
303
|
+
* @category Types
|
|
304
|
+
*/
|
|
305
|
+
export type InlineNode =
|
|
306
|
+
| Text
|
|
307
|
+
| Strong
|
|
308
|
+
| Emphasis
|
|
309
|
+
| InlineCode
|
|
310
|
+
| Link
|
|
311
|
+
| LineBreak
|
|
312
|
+
| Emoticon
|
|
313
|
+
| UserMention
|
|
314
|
+
| DateTime
|
|
315
|
+
| Underline
|
|
316
|
+
| Subscript
|
|
317
|
+
| Superscript
|
|
318
|
+
| Strikethrough
|
|
319
|
+
| ColoredText
|
|
320
|
+
| Highlight
|
|
321
|
+
| UnsupportedInline
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Schema type helper for InlineNode.
|
|
325
|
+
*
|
|
326
|
+
* @category Types
|
|
327
|
+
*/
|
|
328
|
+
export type InlineNodeSchema = typeof InlineNode
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confluence macro AST nodes (panels, expand, TOC, code, status).
|
|
3
|
+
*
|
|
4
|
+
* **Mental model**
|
|
5
|
+
*
|
|
6
|
+
* - **Macro = structured metadata + block children**: Each macro wraps Confluence-specific
|
|
7
|
+
* semantics (panel type, code language, status color) around standard block content.
|
|
8
|
+
* - **Serialization-friendly**: Macros carry enough metadata for Markdown comment encoding
|
|
9
|
+
* and ADF reconstruction.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import * as Schema from "effect/Schema"
|
|
14
|
+
import { RawSource, SchemaVersion, SimpleBlockNode } from "./BlockNode.js"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Supported panel type names.
|
|
18
|
+
*
|
|
19
|
+
* @category MacroNode
|
|
20
|
+
*/
|
|
21
|
+
export const PanelTypes = ["info", "warning", "note", "tip", "error", "panel"] as const
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Panel type for info/warning/note macros.
|
|
25
|
+
*
|
|
26
|
+
* @category MacroNode
|
|
27
|
+
*/
|
|
28
|
+
export const PanelType = Schema.Literal(...PanelTypes)
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Type for panel type.
|
|
32
|
+
*
|
|
33
|
+
* @category Types
|
|
34
|
+
*/
|
|
35
|
+
export type PanelType = Schema.Schema.Type<typeof PanelType>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Info/Warning/Note panel macro.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { InfoPanel, Paragraph, Text } from "@knpkv/atlassian-common/ast"
|
|
43
|
+
*
|
|
44
|
+
* const panel = {
|
|
45
|
+
* _tag: "InfoPanel" as const,
|
|
46
|
+
* panelType: "warning" as const,
|
|
47
|
+
* title: "Important",
|
|
48
|
+
* children: [new Paragraph({ children: [new Text({ value: "Be careful!" })] })]
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @category MacroNode
|
|
53
|
+
*/
|
|
54
|
+
export const InfoPanel = Schema.Struct({
|
|
55
|
+
_tag: Schema.Literal("InfoPanel"),
|
|
56
|
+
version: SchemaVersion,
|
|
57
|
+
panelType: PanelType,
|
|
58
|
+
title: Schema.optional(Schema.String),
|
|
59
|
+
children: Schema.Array(SimpleBlockNode),
|
|
60
|
+
rawSource: RawSource
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Type for InfoPanel.
|
|
65
|
+
*
|
|
66
|
+
* @category Types
|
|
67
|
+
*/
|
|
68
|
+
export type InfoPanel = Schema.Schema.Type<typeof InfoPanel>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Expand/collapse macro.
|
|
72
|
+
*
|
|
73
|
+
* @category MacroNode
|
|
74
|
+
*/
|
|
75
|
+
export const ExpandMacro = Schema.Struct({
|
|
76
|
+
_tag: Schema.Literal("ExpandMacro"),
|
|
77
|
+
version: SchemaVersion,
|
|
78
|
+
title: Schema.optional(Schema.String),
|
|
79
|
+
children: Schema.Array(SimpleBlockNode),
|
|
80
|
+
rawSource: RawSource
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Type for ExpandMacro.
|
|
85
|
+
*
|
|
86
|
+
* @category Types
|
|
87
|
+
*/
|
|
88
|
+
export type ExpandMacro = Schema.Schema.Type<typeof ExpandMacro>
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Table of contents macro.
|
|
92
|
+
*
|
|
93
|
+
* @category MacroNode
|
|
94
|
+
*/
|
|
95
|
+
export const TocMacro = Schema.Struct({
|
|
96
|
+
_tag: Schema.Literal("TocMacro"),
|
|
97
|
+
version: SchemaVersion,
|
|
98
|
+
minLevel: Schema.optional(Schema.Number),
|
|
99
|
+
maxLevel: Schema.optional(Schema.Number),
|
|
100
|
+
rawSource: RawSource
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Type for TocMacro.
|
|
105
|
+
*
|
|
106
|
+
* @category Types
|
|
107
|
+
*/
|
|
108
|
+
export type TocMacro = Schema.Schema.Type<typeof TocMacro>
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Code macro with syntax highlighting.
|
|
112
|
+
*
|
|
113
|
+
* @category MacroNode
|
|
114
|
+
*/
|
|
115
|
+
export const CodeMacro = Schema.Struct({
|
|
116
|
+
_tag: Schema.Literal("CodeMacro"),
|
|
117
|
+
version: SchemaVersion,
|
|
118
|
+
language: Schema.optional(Schema.String),
|
|
119
|
+
title: Schema.optional(Schema.String),
|
|
120
|
+
code: Schema.String,
|
|
121
|
+
lineNumbers: Schema.optionalWith(Schema.Boolean, { default: () => false }),
|
|
122
|
+
collapse: Schema.optionalWith(Schema.Boolean, { default: () => false }),
|
|
123
|
+
firstLine: Schema.optional(Schema.Number),
|
|
124
|
+
rawSource: RawSource
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Type for CodeMacro.
|
|
129
|
+
*
|
|
130
|
+
* @category Types
|
|
131
|
+
*/
|
|
132
|
+
export type CodeMacro = Schema.Schema.Type<typeof CodeMacro>
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Status macro (colored label).
|
|
136
|
+
*
|
|
137
|
+
* @category MacroNode
|
|
138
|
+
*/
|
|
139
|
+
export const StatusMacro = Schema.Struct({
|
|
140
|
+
_tag: Schema.Literal("StatusMacro"),
|
|
141
|
+
version: SchemaVersion,
|
|
142
|
+
text: Schema.String,
|
|
143
|
+
color: Schema.Literal("Grey", "Red", "Yellow", "Green", "Blue"),
|
|
144
|
+
rawSource: RawSource
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Type for StatusMacro.
|
|
149
|
+
*
|
|
150
|
+
* @category Types
|
|
151
|
+
*/
|
|
152
|
+
export type StatusMacro = Schema.Schema.Type<typeof StatusMacro>
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Union of all macro node types.
|
|
156
|
+
*
|
|
157
|
+
* @category MacroNode
|
|
158
|
+
*/
|
|
159
|
+
export const MacroNode = Schema.Union(
|
|
160
|
+
InfoPanel,
|
|
161
|
+
ExpandMacro,
|
|
162
|
+
TocMacro,
|
|
163
|
+
CodeMacro,
|
|
164
|
+
StatusMacro
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Type for macro nodes.
|
|
169
|
+
*
|
|
170
|
+
* @category Types
|
|
171
|
+
*/
|
|
172
|
+
export type MacroNode = InfoPanel | ExpandMacro | TocMacro | CodeMacro | StatusMacro
|
package/src/ast/index.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel export for Atlassian AST node types and constructors.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Inline nodes
|
|
8
|
+
export {
|
|
9
|
+
ColoredText,
|
|
10
|
+
DateTime,
|
|
11
|
+
Emoticon,
|
|
12
|
+
Emphasis,
|
|
13
|
+
Highlight,
|
|
14
|
+
InlineCode,
|
|
15
|
+
InlineNode,
|
|
16
|
+
type InlineNode as InlineNodeType,
|
|
17
|
+
InlineNodeChildren,
|
|
18
|
+
LineBreak,
|
|
19
|
+
Link,
|
|
20
|
+
RawSource as InlineRawSource,
|
|
21
|
+
Strikethrough,
|
|
22
|
+
Strong,
|
|
23
|
+
Subscript,
|
|
24
|
+
Superscript,
|
|
25
|
+
Text,
|
|
26
|
+
Underline,
|
|
27
|
+
UnsupportedInline,
|
|
28
|
+
UserMention
|
|
29
|
+
} from "./InlineNode.js"
|
|
30
|
+
|
|
31
|
+
// Block nodes
|
|
32
|
+
export {
|
|
33
|
+
BlockNode,
|
|
34
|
+
type BlockNode as BlockNodeType,
|
|
35
|
+
BlockQuote,
|
|
36
|
+
CodeBlock,
|
|
37
|
+
Heading,
|
|
38
|
+
Image,
|
|
39
|
+
ImageAttachment,
|
|
40
|
+
type ImageAttachment as ImageAttachmentType,
|
|
41
|
+
List,
|
|
42
|
+
ListItem,
|
|
43
|
+
Paragraph,
|
|
44
|
+
RawSource,
|
|
45
|
+
SchemaVersion,
|
|
46
|
+
SimpleBlockNode,
|
|
47
|
+
Table,
|
|
48
|
+
TableCell,
|
|
49
|
+
TableRow,
|
|
50
|
+
TaskItem,
|
|
51
|
+
type TaskItem as TaskItemType,
|
|
52
|
+
TaskList,
|
|
53
|
+
type TaskList as TaskListType,
|
|
54
|
+
TextAlignment,
|
|
55
|
+
type TextAlignment as TextAlignmentValue,
|
|
56
|
+
ThematicBreak,
|
|
57
|
+
UnsupportedBlock
|
|
58
|
+
} from "./BlockNode.js"
|
|
59
|
+
|
|
60
|
+
// Macro nodes
|
|
61
|
+
export {
|
|
62
|
+
CodeMacro,
|
|
63
|
+
type CodeMacro as CodeMacroType,
|
|
64
|
+
ExpandMacro,
|
|
65
|
+
type ExpandMacro as ExpandMacroType,
|
|
66
|
+
InfoPanel,
|
|
67
|
+
type InfoPanel as InfoPanelType,
|
|
68
|
+
MacroNode,
|
|
69
|
+
type MacroNode as MacroNodeType,
|
|
70
|
+
PanelType,
|
|
71
|
+
type PanelType as PanelTypeValue,
|
|
72
|
+
PanelTypes,
|
|
73
|
+
StatusMacro,
|
|
74
|
+
type StatusMacro as StatusMacroType,
|
|
75
|
+
TocMacro,
|
|
76
|
+
type TocMacro as TocMacroType
|
|
77
|
+
} from "./MacroNode.js"
|
|
78
|
+
|
|
79
|
+
// Document
|
|
80
|
+
export {
|
|
81
|
+
Document,
|
|
82
|
+
type Document as DocumentType,
|
|
83
|
+
DocumentNode,
|
|
84
|
+
type DocumentNode as DocumentNodeType,
|
|
85
|
+
isDocument,
|
|
86
|
+
makeDocument
|
|
87
|
+
} from "./Document.js"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlassian OAuth2 endpoint URLs, scope constants, authorization URL builder, and PKCE.
|
|
3
|
+
*
|
|
4
|
+
* **Mental model**
|
|
5
|
+
*
|
|
6
|
+
* - **Constants + builder**: Endpoint URLs are plain strings; {@link buildAuthUrl}
|
|
7
|
+
* assembles the full authorization URL with audience, scopes, CSRF state, and PKCE.
|
|
8
|
+
* - **Scope sets**: {@link CONFLUENCE_SCOPES} and {@link JIRA_SCOPES} define the
|
|
9
|
+
* minimum permissions for each product's OAuth flow.
|
|
10
|
+
* - **PKCE**: {@link generateCodeVerifier} and {@link computeCodeChallenge} implement
|
|
11
|
+
* RFC 7636 S256 to protect the authorization code grant from interception.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import * as Effect from "effect/Effect"
|
|
16
|
+
import * as Encoding from "effect/Encoding"
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* OAuth2 authorization endpoint.
|
|
20
|
+
*
|
|
21
|
+
* @category Endpoints
|
|
22
|
+
*/
|
|
23
|
+
export const AUTH_URL = "https://auth.atlassian.com/authorize"
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* OAuth2 token endpoint.
|
|
27
|
+
*
|
|
28
|
+
* @category Endpoints
|
|
29
|
+
*/
|
|
30
|
+
export const TOKEN_URL = "https://auth.atlassian.com/oauth/token"
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* OAuth2 token revocation endpoint.
|
|
34
|
+
*
|
|
35
|
+
* @category Endpoints
|
|
36
|
+
*/
|
|
37
|
+
export const REVOKE_URL = "https://auth.atlassian.com/oauth/revoke"
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Accessible resources endpoint (to get cloud IDs).
|
|
41
|
+
*
|
|
42
|
+
* @category Endpoints
|
|
43
|
+
*/
|
|
44
|
+
export const RESOURCES_URL = "https://api.atlassian.com/oauth/token/accessible-resources"
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* User info endpoint.
|
|
48
|
+
*
|
|
49
|
+
* @category Endpoints
|
|
50
|
+
*/
|
|
51
|
+
export const ME_URL = "https://api.atlassian.com/me"
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Confluence scopes for OAuth2.
|
|
55
|
+
*
|
|
56
|
+
* @category Scopes
|
|
57
|
+
*/
|
|
58
|
+
export const CONFLUENCE_SCOPES = [
|
|
59
|
+
"read:page:confluence",
|
|
60
|
+
"write:page:confluence",
|
|
61
|
+
"delete:page:confluence",
|
|
62
|
+
"read:me",
|
|
63
|
+
"offline_access"
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Jira scopes for OAuth2.
|
|
68
|
+
*
|
|
69
|
+
* @category Scopes
|
|
70
|
+
*/
|
|
71
|
+
export const JIRA_SCOPES = [
|
|
72
|
+
"read:jira-work",
|
|
73
|
+
"write:jira-work",
|
|
74
|
+
"read:jira-user",
|
|
75
|
+
"manage:jira-project",
|
|
76
|
+
"manage:jira-configuration",
|
|
77
|
+
"read:me",
|
|
78
|
+
"offline_access"
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Options for building OAuth2 authorization URL.
|
|
83
|
+
*
|
|
84
|
+
* @category Types
|
|
85
|
+
*/
|
|
86
|
+
export interface BuildAuthUrlOptions {
|
|
87
|
+
/** OAuth2 client ID */
|
|
88
|
+
readonly clientId: string
|
|
89
|
+
/** State parameter for CSRF protection */
|
|
90
|
+
readonly state: string
|
|
91
|
+
/** Local callback server port */
|
|
92
|
+
readonly port: number
|
|
93
|
+
/** OAuth2 scopes */
|
|
94
|
+
readonly scopes: ReadonlyArray<string>
|
|
95
|
+
/** PKCE code_challenge (S256). Omit to skip PKCE. */
|
|
96
|
+
readonly codeChallenge?: string | undefined
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Build OAuth2 authorization URL.
|
|
101
|
+
*
|
|
102
|
+
* @category Utilities
|
|
103
|
+
*/
|
|
104
|
+
export const buildAuthUrl = (options: BuildAuthUrlOptions): string => {
|
|
105
|
+
const params = new URLSearchParams({
|
|
106
|
+
audience: "api.atlassian.com",
|
|
107
|
+
client_id: options.clientId,
|
|
108
|
+
scope: options.scopes.join(" "),
|
|
109
|
+
redirect_uri: `http://localhost:${options.port}/callback`,
|
|
110
|
+
state: options.state,
|
|
111
|
+
response_type: "code",
|
|
112
|
+
prompt: "consent"
|
|
113
|
+
})
|
|
114
|
+
if (options.codeChallenge) {
|
|
115
|
+
params.set("code_challenge", options.codeChallenge)
|
|
116
|
+
params.set("code_challenge_method", "S256")
|
|
117
|
+
}
|
|
118
|
+
return `${AUTH_URL}?${params.toString()}`
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Generate a cryptographically random PKCE code verifier (RFC 7636).
|
|
123
|
+
* Uses Web Crypto API (available in Node 18+, Deno, browsers).
|
|
124
|
+
*
|
|
125
|
+
* @category PKCE
|
|
126
|
+
*/
|
|
127
|
+
export const generateCodeVerifier = (): string => {
|
|
128
|
+
const bytes = new Uint8Array(32)
|
|
129
|
+
globalThis.crypto.getRandomValues(bytes)
|
|
130
|
+
return Encoding.encodeBase64Url(bytes)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Compute S256 code challenge from a code verifier (RFC 7636).
|
|
135
|
+
* Uses Web Crypto `subtle.digest` — returns Effect since digest is async.
|
|
136
|
+
*
|
|
137
|
+
* @category PKCE
|
|
138
|
+
*/
|
|
139
|
+
export const computeCodeChallenge = (verifier: string): Effect.Effect<string> =>
|
|
140
|
+
Effect.promise(() => globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier))).pipe(
|
|
141
|
+
Effect.map((hash) => Encoding.encodeBase64Url(new Uint8Array(hash)))
|
|
142
|
+
)
|