@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.
@@ -1,4 +1,4 @@
1
- name: CI/CD
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.x, 18.x, 20.x]
16
-
15
+ node-version: [18.x, 20.x]
16
+
17
17
  steps:
18
- - uses: actions/checkout@v3
19
-
18
+ - uses: actions/checkout@v4
19
+
20
20
  - name: Use Node.js ${{ matrix.node-version }}
21
- uses: actions/setup-node@v3
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: '20.x'
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
@@ -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(/&amp;/g, '&')
854
+ .replace(/&lt;/g, '<')
855
+ .replace(/&gt;/g, '>')
856
+ .replace(/&quot;/g, '"')
857
+ .replace(/&#39;/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[${code}]]></ac:plain-text-body>
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
- // Convert links
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bestend/confluence-cli",
3
- "version": "1.15.1",
3
+ "version": "1.15.4",
4
4
  "description": "A command-line interface for Atlassian Confluence with page creation and editing capabilities",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -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(&quot;Hello World&quot;);');
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 convert links to Confluence link format', () => {
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('<ac:link>');
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
  });