@bestend/confluence-cli 1.15.1 → 1.15.4
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/.github/workflows/ci.yml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name: CI
|
|
1
|
+
name: CI
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -9,59 +9,20 @@ on:
|
|
|
9
9
|
jobs:
|
|
10
10
|
test:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
strategy:
|
|
14
14
|
matrix:
|
|
15
|
-
node-version: [
|
|
16
|
-
|
|
15
|
+
node-version: [18.x, 20.x]
|
|
16
|
+
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
19
|
-
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
20
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
-
uses: actions/setup-node@
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
22
|
with:
|
|
23
23
|
node-version: ${{ matrix.node-version }}
|
|
24
24
|
cache: 'npm'
|
|
25
|
-
|
|
26
|
-
- run: npm ci
|
|
27
|
-
- run: npm run lint
|
|
28
|
-
- run: npm test
|
|
29
|
-
|
|
30
|
-
security:
|
|
31
|
-
runs-on: ubuntu-latest
|
|
32
|
-
steps:
|
|
33
|
-
- uses: actions/checkout@v3
|
|
34
|
-
- name: Run npm audit
|
|
35
|
-
run: npm audit --audit-level moderate
|
|
36
25
|
|
|
37
|
-
publish:
|
|
38
|
-
needs: [test, security]
|
|
39
|
-
runs-on: ubuntu-latest
|
|
40
|
-
if: github.ref == 'refs/heads/main'
|
|
41
|
-
permissions:
|
|
42
|
-
contents: write
|
|
43
|
-
issues: write
|
|
44
|
-
pull-requests: write
|
|
45
|
-
|
|
46
|
-
steps:
|
|
47
|
-
- uses: actions/checkout@v3
|
|
48
|
-
with:
|
|
49
|
-
fetch-depth: 0
|
|
50
|
-
token: ${{ secrets.GITHUB_TOKEN }}
|
|
51
|
-
|
|
52
|
-
- name: Setup Node.js
|
|
53
|
-
uses: actions/setup-node@v3
|
|
54
|
-
with:
|
|
55
|
-
node-version: '18'
|
|
56
|
-
registry-url: 'https://registry.npmjs.org'
|
|
57
|
-
env:
|
|
58
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
59
|
-
|
|
60
26
|
- run: npm ci
|
|
27
|
+
- run: npm run lint
|
|
61
28
|
- run: npm test
|
|
62
|
-
|
|
63
|
-
- name: Semantic Release
|
|
64
|
-
uses: cycjimmy/semantic-release-action@v3
|
|
65
|
-
env:
|
|
66
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
67
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -16,9 +16,19 @@ jobs:
|
|
|
16
16
|
|
|
17
17
|
- uses: actions/setup-node@v4
|
|
18
18
|
with:
|
|
19
|
-
node-version: '
|
|
19
|
+
node-version: '24.x'
|
|
20
20
|
registry-url: 'https://registry.npmjs.org'
|
|
21
21
|
|
|
22
|
+
- name: Ensure package version matches tag
|
|
23
|
+
run: |
|
|
24
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
25
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
26
|
+
echo "Tag: $TAG / package.json: $PKG_VERSION"
|
|
27
|
+
if [ "$TAG" != "$PKG_VERSION" ]; then
|
|
28
|
+
echo "package.json version mismatch: $PKG_VERSION (expected $TAG)" >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
22
32
|
- name: Install dependencies
|
|
23
33
|
run: npm ci
|
|
24
34
|
|
package/README.md
CHANGED
|
@@ -20,12 +20,12 @@ A powerful command-line interface for Atlassian Confluence that allows you to re
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm install -g @bestend/confluence-cli
|
|
23
|
+
npm install -g @bestend/confluence-cli@1.15.2
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Or run directly with npx:
|
|
27
27
|
```bash
|
|
28
|
-
npx @bestend/confluence-cli
|
|
28
|
+
npx @bestend/confluence-cli@1.15.2
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## Quick Start
|
package/lib/confluence-client.js
CHANGED
|
@@ -61,6 +61,12 @@ class ConfluenceClient {
|
|
|
61
61
|
if (pageIdMatch) {
|
|
62
62
|
return pageIdMatch[1];
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
// Handle /spaces/SPACEKEY/pages/PAGEID/Title format
|
|
66
|
+
const spacesMatch = pageIdOrUrl.match(/\/spaces\/[^/]+\/pages\/(\d+)/);
|
|
67
|
+
if (spacesMatch) {
|
|
68
|
+
return spacesMatch[1];
|
|
69
|
+
}
|
|
64
70
|
|
|
65
71
|
// Handle display URLs - search by space and title
|
|
66
72
|
const displayMatch = pageIdOrUrl.match(/\/display\/([^/]+)\/(.+)/);
|
|
@@ -842,9 +848,18 @@ class ConfluenceClient {
|
|
|
842
848
|
// Convert code blocks to Confluence code macro
|
|
843
849
|
storage = storage.replace(/<pre><code(?:\s+class="language-(\w+)")?>(.*?)<\/code><\/pre>/gs, (_, lang, code) => {
|
|
844
850
|
const language = lang || 'text';
|
|
851
|
+
// Decode HTML entities inside code blocks before wrapping in CDATA
|
|
852
|
+
let decoded = code
|
|
853
|
+
.replace(/&/g, '&')
|
|
854
|
+
.replace(/</g, '<')
|
|
855
|
+
.replace(/>/g, '>')
|
|
856
|
+
.replace(/"/g, '"')
|
|
857
|
+
.replace(/'/g, "'");
|
|
858
|
+
decoded = decoded.replace(/\]\]>/g, ']]]]><![CDATA[>');
|
|
859
|
+
|
|
845
860
|
return `<ac:structured-macro ac:name="code">
|
|
846
861
|
<ac:parameter ac:name="language">${language}</ac:parameter>
|
|
847
|
-
<ac:plain-text-body><![CDATA[${
|
|
862
|
+
<ac:plain-text-body><![CDATA[${decoded}]]></ac:plain-text-body>
|
|
848
863
|
</ac:structured-macro>`;
|
|
849
864
|
});
|
|
850
865
|
|
|
@@ -885,8 +900,7 @@ class ConfluenceClient {
|
|
|
885
900
|
storage = storage.replace(/<th>(.*?)<\/th>/g, '<th><p>$1</p></th>');
|
|
886
901
|
storage = storage.replace(/<td>(.*?)<\/td>/g, '<td><p>$1</p></td>');
|
|
887
902
|
|
|
888
|
-
//
|
|
889
|
-
storage = storage.replace(/<a href="(.*?)">(.*?)<\/a>/g, '<ac:link><ri:url ri:value="$1" /><ac:plain-text-link-body><![CDATA[$2]]></ac:plain-text-link-body></ac:link>');
|
|
903
|
+
// Links: keep <a href> as-is (compatible with both Cloud and Server/Data Center)
|
|
890
904
|
|
|
891
905
|
// Convert horizontal rules
|
|
892
906
|
storage = storage.replace(/<hr\s*\/?>/g, '<hr />');
|
package/package.json
CHANGED
|
@@ -141,7 +141,7 @@ describe('ConfluenceClient', () => {
|
|
|
141
141
|
|
|
142
142
|
expect(result).toContain('<ac:structured-macro ac:name="code">');
|
|
143
143
|
expect(result).toContain('<ac:parameter ac:name="language">javascript</ac:parameter>');
|
|
144
|
-
expect(result).toContain('console.log(
|
|
144
|
+
expect(result).toContain('console.log("Hello World");');
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
test('should convert lists to native Confluence format', () => {
|
|
@@ -171,12 +171,11 @@ describe('ConfluenceClient', () => {
|
|
|
171
171
|
expect(result).toContain('<td><p>Cell 1</p></td>');
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
test('should
|
|
174
|
+
test('should keep links as standard HTML anchors', () => {
|
|
175
175
|
const markdown = '[Example Link](https://example.com)';
|
|
176
176
|
const result = client.markdownToStorage(markdown);
|
|
177
177
|
|
|
178
|
-
expect(result).toContain('<
|
|
179
|
-
expect(result).toContain('ri:value="https://example.com"');
|
|
178
|
+
expect(result).toContain('<a href="https://example.com">');
|
|
180
179
|
expect(result).toContain('Example Link');
|
|
181
180
|
});
|
|
182
181
|
});
|