@baiyibai-antora/atlassian-client 1.0.0-beta.5
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/lib/index.js +75 -0
- package/package.json +34 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Minimal Atlassian Cloud REST client shared by the Confluora packages:
|
|
4
|
+
// basic auth from an email + API token, JSON in/out, multipart form upload,
|
|
5
|
+
// and cursor pagination for the Confluence v2 API. Node's built-in fetch;
|
|
6
|
+
// injectable for tests. Zero dependencies.
|
|
7
|
+
|
|
8
|
+
class AtlassianClient {
|
|
9
|
+
constructor ({ baseUrl, email, apiToken, fetch: fetchImpl, serviceName } = {}) {
|
|
10
|
+
if (!baseUrl || !email || !apiToken) {
|
|
11
|
+
throw new Error(`${serviceName || 'Atlassian'} client requires baseUrl, email, and apiToken`)
|
|
12
|
+
}
|
|
13
|
+
this.baseUrl = baseUrl.replace(/\/$/, '')
|
|
14
|
+
this.fetch = fetchImpl || globalThis.fetch
|
|
15
|
+
this.authHeader = 'Basic ' + Buffer.from(`${email}:${apiToken}`).toString('base64')
|
|
16
|
+
this.serviceName = serviceName || 'Atlassian'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async request (method, path, { body, headers, form } = {}) {
|
|
20
|
+
const opts = { method, headers: { Authorization: this.authHeader, Accept: 'application/json', ...headers } }
|
|
21
|
+
if (form) {
|
|
22
|
+
opts.body = form
|
|
23
|
+
opts.headers['X-Atlassian-Token'] = 'nocheck'
|
|
24
|
+
} else if (body !== undefined) {
|
|
25
|
+
opts.headers['Content-Type'] = 'application/json'
|
|
26
|
+
opts.body = JSON.stringify(body)
|
|
27
|
+
}
|
|
28
|
+
const response = await this.fetch(`${this.baseUrl}${path}`, opts)
|
|
29
|
+
if (response.status === 404) return null
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const detail = await response.text().catch(() => '')
|
|
32
|
+
throw new Error(`${this.serviceName} ${method} ${path} failed: ${response.status} ${detail.slice(0, 500)}`)
|
|
33
|
+
}
|
|
34
|
+
if (response.status === 204) return {}
|
|
35
|
+
return response.json()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Raw body download (attachments, exports); returns a Buffer or null on 404.
|
|
39
|
+
async download (path) {
|
|
40
|
+
const response = await this.fetch(`${this.baseUrl}${path}`, {
|
|
41
|
+
headers: { Authorization: this.authHeader },
|
|
42
|
+
redirect: 'follow',
|
|
43
|
+
})
|
|
44
|
+
if (response.status === 404) return null
|
|
45
|
+
if (!response.ok) throw new Error(`${this.serviceName} GET ${path} failed: ${response.status}`)
|
|
46
|
+
return Buffer.from(await response.arrayBuffer())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Collect every result of a Confluence v2 cursor-paginated collection
|
|
50
|
+
// (the response carries `_links.next` until the last page).
|
|
51
|
+
async getAll (path) {
|
|
52
|
+
const results = []
|
|
53
|
+
let next = path
|
|
54
|
+
while (next) {
|
|
55
|
+
const page = await this.request('GET', next)
|
|
56
|
+
if (!page) break
|
|
57
|
+
results.push(...(page.results || []))
|
|
58
|
+
next = (page._links && page._links.next) || null
|
|
59
|
+
}
|
|
60
|
+
return results
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Credentials come from the environment (CI-friendly, never on the command
|
|
65
|
+
// line). ATLASSIAN_BASE_URL covers both products; the product-specific names
|
|
66
|
+
// are accepted for back compatibility.
|
|
67
|
+
function credentialsFromEnv (env = process.env) {
|
|
68
|
+
return {
|
|
69
|
+
baseUrl: env.ATLASSIAN_BASE_URL || env.CONFLUENCE_BASE_URL || env.JIRA_BASE_URL,
|
|
70
|
+
email: env.ATLASSIAN_EMAIL || env.CONFLUENCE_USER_EMAIL,
|
|
71
|
+
apiToken: env.ATLASSIAN_API_TOKEN || env.CONFLUENCE_API_TOKEN,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = { AtlassianClient, credentialsFromEnv }
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@baiyibai-antora/atlassian-client",
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
|
+
"description": "Minimal zero-dependency Atlassian Cloud REST client (basic auth, JSON, multipart, v2 cursor pagination) shared by the Confluora packages",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "baiyibai",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://gitlab.com/baiyibai-antora/confluora.git",
|
|
10
|
+
"directory": "packages/atlassian-client"
|
|
11
|
+
},
|
|
12
|
+
"type": "commonjs",
|
|
13
|
+
"main": "lib/index.js",
|
|
14
|
+
"files": [
|
|
15
|
+
"lib"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "node --test test/*-test.js"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"confluora",
|
|
22
|
+
"atlassian",
|
|
23
|
+
"confluence",
|
|
24
|
+
"jira",
|
|
25
|
+
"rest",
|
|
26
|
+
"client"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
}
|
|
34
|
+
}
|