confluence-cli 1.27.4 → 1.27.6
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.
|
@@ -197,16 +197,17 @@ confluence find "API Reference" --space MYSPACE
|
|
|
197
197
|
Search pages using a keyword or CQL expression.
|
|
198
198
|
|
|
199
199
|
```sh
|
|
200
|
-
confluence search <query> [--limit <number>]
|
|
200
|
+
confluence search <query> [--limit <number>] [--cql]
|
|
201
201
|
```
|
|
202
202
|
|
|
203
203
|
| Option | Default | Description |
|
|
204
204
|
|---|---|---|
|
|
205
205
|
| `--limit` | `10` | Maximum number of results |
|
|
206
|
+
| `--cql` | false | Pass query as raw CQL instead of text search |
|
|
206
207
|
|
|
207
208
|
```sh
|
|
208
209
|
confluence search "deployment pipeline"
|
|
209
|
-
confluence search "
|
|
210
|
+
confluence search --cql 'siteSearch ~ "deployment pipeline" and space = "MYSPACE"' --limit 50
|
|
210
211
|
```
|
|
211
212
|
|
|
212
213
|
---
|
|
@@ -697,7 +698,7 @@ confluence children 123456789 --recursive --format json | jq '.[].id'
|
|
|
697
698
|
### Search and process results
|
|
698
699
|
|
|
699
700
|
```sh
|
|
700
|
-
confluence search "release notes" --limit 20
|
|
701
|
+
confluence search --cql 'siteSearch ~ "release notes" and space = "MYSPACE"' --limit 20
|
|
701
702
|
```
|
|
702
703
|
|
|
703
704
|
---
|
package/bin/confluence.js
CHANGED
|
@@ -8,11 +8,6 @@ const { getConfig, initConfig, listProfiles, setActiveProfile, deleteProfile, is
|
|
|
8
8
|
const Analytics = require('../lib/analytics');
|
|
9
9
|
const pkg = require('../package.json');
|
|
10
10
|
|
|
11
|
-
function buildPageUrl(config, path) {
|
|
12
|
-
const protocol = config.protocol || 'https';
|
|
13
|
-
return `${protocol}://${config.domain}${path}`;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
11
|
function assertWritable(config) {
|
|
17
12
|
if (config.readOnly) {
|
|
18
13
|
console.error(chalk.red('Error: This profile is in read-only mode. Write operations are not allowed.'));
|
|
@@ -240,8 +235,8 @@ program
|
|
|
240
235
|
console.log(`Title: ${chalk.blue(result.title)}`);
|
|
241
236
|
console.log(`ID: ${chalk.blue(result.id)}`);
|
|
242
237
|
console.log(`Space: ${chalk.blue(result.space.name)} (${result.space.key})`);
|
|
243
|
-
console.log(`URL: ${chalk.gray(`${
|
|
244
|
-
|
|
238
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${result._links.webui}`)}`)}`);
|
|
239
|
+
|
|
245
240
|
analytics.track('create', true);
|
|
246
241
|
} catch (error) {
|
|
247
242
|
analytics.track('create', false);
|
|
@@ -289,8 +284,8 @@ program
|
|
|
289
284
|
console.log(`ID: ${chalk.blue(result.id)}`);
|
|
290
285
|
console.log(`Parent: ${chalk.blue(parentInfo.title)} (${parentId})`);
|
|
291
286
|
console.log(`Space: ${chalk.blue(result.space.name)} (${result.space.key})`);
|
|
292
|
-
console.log(`URL: ${chalk.gray(`${
|
|
293
|
-
|
|
287
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${result._links.webui}`)}`)}`);
|
|
288
|
+
|
|
294
289
|
analytics.track('create_child', true);
|
|
295
290
|
} catch (error) {
|
|
296
291
|
analytics.track('create_child', false);
|
|
@@ -337,8 +332,8 @@ program
|
|
|
337
332
|
console.log(`Title: ${chalk.blue(result.title)}`);
|
|
338
333
|
console.log(`ID: ${chalk.blue(result.id)}`);
|
|
339
334
|
console.log(`Version: ${chalk.blue(result.version.number)}`);
|
|
340
|
-
console.log(`URL: ${chalk.gray(`${
|
|
341
|
-
|
|
335
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${result._links.webui}`)}`)}`);
|
|
336
|
+
|
|
342
337
|
analytics.track('update', true);
|
|
343
338
|
} catch (error) {
|
|
344
339
|
analytics.track('update', false);
|
|
@@ -365,7 +360,7 @@ program
|
|
|
365
360
|
console.log(`ID: ${chalk.blue(result.id)}`);
|
|
366
361
|
console.log(`New Parent: ${chalk.blue(newParentId)}`);
|
|
367
362
|
console.log(`Version: ${chalk.blue(result.version.number)}`);
|
|
368
|
-
console.log(`URL: ${chalk.gray(`${
|
|
363
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${result._links.webui}`)}`)}`);
|
|
369
364
|
|
|
370
365
|
analytics.track('move', true);
|
|
371
366
|
} catch (error) {
|
|
@@ -473,8 +468,8 @@ program
|
|
|
473
468
|
console.log(`Title: ${chalk.green(pageInfo.title)}`);
|
|
474
469
|
console.log(`ID: ${chalk.green(pageInfo.id)}`);
|
|
475
470
|
console.log(`Space: ${chalk.green(pageInfo.space.name)} (${pageInfo.space.key})`);
|
|
476
|
-
console.log(`URL: ${chalk.gray(`${
|
|
477
|
-
|
|
471
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${pageInfo.url}`)}`)}`);
|
|
472
|
+
|
|
478
473
|
analytics.track('find', true);
|
|
479
474
|
} catch (error) {
|
|
480
475
|
analytics.track('find', false);
|
|
@@ -1713,7 +1708,7 @@ program
|
|
|
1713
1708
|
console.log(` - ...and ${result.failures.length - 10} more`);
|
|
1714
1709
|
}
|
|
1715
1710
|
}
|
|
1716
|
-
console.log(`URL: ${chalk.gray(`${
|
|
1711
|
+
console.log(`URL: ${chalk.gray(`${client.buildUrl(`${client.webUrlPrefix}${result.rootPage._links.webui}`)}`)}`);
|
|
1717
1712
|
if (options.failOnError && result.failures?.length) {
|
|
1718
1713
|
analytics.track('copy_tree', false);
|
|
1719
1714
|
console.error(chalk.red('Completed with failures and --fail-on-error is set.'));
|
|
@@ -1775,7 +1770,7 @@ program
|
|
|
1775
1770
|
type: page.type,
|
|
1776
1771
|
status: page.status,
|
|
1777
1772
|
spaceKey: page.space?.key,
|
|
1778
|
-
url: `${
|
|
1773
|
+
url: `${client.buildUrl(`${client.webUrlPrefix}/spaces/${page.space?.key}/pages/${page.id}`)}`,
|
|
1779
1774
|
parentId: page.parentId || resolvedPageId
|
|
1780
1775
|
}))
|
|
1781
1776
|
};
|
|
@@ -1787,7 +1782,7 @@ program
|
|
|
1787
1782
|
|
|
1788
1783
|
// Build tree structure
|
|
1789
1784
|
const tree = buildTree(children, resolvedPageId);
|
|
1790
|
-
printTree(tree, config, options, 1);
|
|
1785
|
+
printTree(tree, client, config, options, 1);
|
|
1791
1786
|
|
|
1792
1787
|
console.log('');
|
|
1793
1788
|
console.log(chalk.gray(`Total: ${children.length} child page${children.length === 1 ? '' : 's'}`));
|
|
@@ -1804,7 +1799,7 @@ program
|
|
|
1804
1799
|
}
|
|
1805
1800
|
|
|
1806
1801
|
if (options.showUrl) {
|
|
1807
|
-
const url = `${
|
|
1802
|
+
const url = `${client.buildUrl(`${client.webUrlPrefix}/spaces/${page.space?.key}/pages/${page.id}`)}`;
|
|
1808
1803
|
output += `\n ${chalk.gray(url)}`;
|
|
1809
1804
|
}
|
|
1810
1805
|
|
|
@@ -1856,7 +1851,7 @@ function buildTree(pages, rootId) {
|
|
|
1856
1851
|
}
|
|
1857
1852
|
|
|
1858
1853
|
// Helper function to print tree
|
|
1859
|
-
function printTree(nodes, config, options, depth = 1) {
|
|
1854
|
+
function printTree(nodes, client, config, options, depth = 1) {
|
|
1860
1855
|
nodes.forEach((node, index) => {
|
|
1861
1856
|
const isLast = index === nodes.length - 1;
|
|
1862
1857
|
const indent = ' '.repeat(depth - 1);
|
|
@@ -1869,14 +1864,14 @@ function printTree(nodes, config, options, depth = 1) {
|
|
|
1869
1864
|
}
|
|
1870
1865
|
|
|
1871
1866
|
if (options.showUrl) {
|
|
1872
|
-
const url = `${
|
|
1867
|
+
const url = `${client.buildUrl(`${client.webUrlPrefix}/spaces/${node.space?.key}/pages/${node.id}`)}`;
|
|
1873
1868
|
output += `\n${indent}${isLast ? ' ' : '│ '}${chalk.gray(url)}`;
|
|
1874
1869
|
}
|
|
1875
1870
|
|
|
1876
1871
|
console.log(output);
|
|
1877
|
-
|
|
1872
|
+
|
|
1878
1873
|
if (node.children && node.children.length > 0) {
|
|
1879
|
-
printTree(node.children, config, options, depth + 1);
|
|
1874
|
+
printTree(node.children, client, config, options, depth + 1);
|
|
1880
1875
|
}
|
|
1881
1876
|
});
|
|
1882
1877
|
}
|
package/lib/confluence-client.js
CHANGED
|
@@ -35,6 +35,7 @@ class ConfluenceClient {
|
|
|
35
35
|
this.email = config.email;
|
|
36
36
|
this.authType = (config.authType || (this.email ? 'basic' : 'bearer')).toLowerCase();
|
|
37
37
|
this.apiPath = this.sanitizeApiPath(config.apiPath);
|
|
38
|
+
this.webUrlPrefix = this.apiPath.startsWith('/wiki/') ? '/wiki' : '';
|
|
38
39
|
this.baseURL = `${this.protocol}://${this.domain}${this.apiPath}`;
|
|
39
40
|
this.markdown = new MarkdownIt();
|
|
40
41
|
this.setupConfluenceMarkdownExtensions();
|
|
@@ -412,7 +413,7 @@ class ConfluenceClient {
|
|
|
412
413
|
const webui = page._links?.webui || '';
|
|
413
414
|
return {
|
|
414
415
|
title: page.title,
|
|
415
|
-
url: webui ? this.buildUrl(
|
|
416
|
+
url: webui ? this.buildUrl(`${this.webUrlPrefix}${webui}`) : ''
|
|
416
417
|
};
|
|
417
418
|
}
|
|
418
419
|
return null;
|
|
@@ -506,7 +507,7 @@ class ConfluenceClient {
|
|
|
506
507
|
// Format: - [Page Title](URL)
|
|
507
508
|
const childPagesList = childPages.map(page => {
|
|
508
509
|
const webui = page._links?.webui || '';
|
|
509
|
-
const url = webui ? this.buildUrl(
|
|
510
|
+
const url = webui ? this.buildUrl(`${this.webUrlPrefix}${webui}`) : '';
|
|
510
511
|
if (url) {
|
|
511
512
|
return `- [${page.title}](${url})`;
|
|
512
513
|
} else {
|
|
@@ -1073,10 +1074,11 @@ class ConfluenceClient {
|
|
|
1073
1074
|
// so they appear as literal characters in the CDATA output
|
|
1074
1075
|
const decodedCode = code.replace(/\n$/, '')
|
|
1075
1076
|
.replace(/"/g, '"')
|
|
1076
|
-
.replace(/&/g, '&')
|
|
1077
1077
|
.replace(/</g, '<')
|
|
1078
|
-
.replace(/>/g, '>')
|
|
1079
|
-
|
|
1078
|
+
.replace(/>/g, '>')
|
|
1079
|
+
.replace(/&/g, '&'); // & last to avoid double-decoding
|
|
1080
|
+
const safeCode = decodedCode.replace(/]]>/g, ']]]]><![CDATA[>');
|
|
1081
|
+
return `<ac:structured-macro ac:name="code"><ac:parameter ac:name="language">${language}</ac:parameter><ac:plain-text-body><![CDATA[${safeCode}]]></ac:plain-text-body></ac:structured-macro>`;
|
|
1080
1082
|
});
|
|
1081
1083
|
|
|
1082
1084
|
// Convert inline code
|
|
@@ -1351,11 +1353,11 @@ class ConfluenceClient {
|
|
|
1351
1353
|
// Try to build a proper URL - if spaceKey starts with ~, it's a user space
|
|
1352
1354
|
if (spaceKey.startsWith('~')) {
|
|
1353
1355
|
const spacePath = `display/${spaceKey}/${encodeURIComponent(title)}`;
|
|
1354
|
-
return `\n> 📄 **${labels.includePage}**: [${title}](${this.buildUrl(
|
|
1356
|
+
return `\n> 📄 **${labels.includePage}**: [${title}](${this.buildUrl(`${this.webUrlPrefix}/${spacePath}`)})\n`;
|
|
1355
1357
|
} else {
|
|
1356
1358
|
// For non-user spaces, we cannot construct a valid link without the page ID.
|
|
1357
1359
|
// Document that manual correction is required.
|
|
1358
|
-
return `\n> 📄 **${labels.includePage}**: [${title}](${this.buildUrl(
|
|
1360
|
+
return `\n> 📄 **${labels.includePage}**: [${title}](${this.buildUrl(`${this.webUrlPrefix}/spaces/${spaceKey}/pages/[PAGE_ID_HERE]`)}) _(manual link correction required)_\n`;
|
|
1359
1361
|
}
|
|
1360
1362
|
});
|
|
1361
1363
|
|