confluence-cli 2.1.11 â 2.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/README.md
CHANGED
|
@@ -7,7 +7,7 @@ A powerful command-line interface for Atlassian Confluence that allows you to re
|
|
|
7
7
|
- đ **Read pages** - Get page content in text or HTML format
|
|
8
8
|
- đ **Search** - Find pages using Confluence's powerful search
|
|
9
9
|
- âšī¸ **Page info** - Get detailed information about pages
|
|
10
|
-
- đ **List spaces** - View
|
|
10
|
+
- đ **List spaces** - View available Confluence spaces
|
|
11
11
|
- âī¸ **Create pages** - Create new pages with support for Markdown, HTML, or Storage format
|
|
12
12
|
- đ **Update pages** - Update existing page content and titles
|
|
13
13
|
- đī¸ **Delete pages** - Delete (or move to trash) pages by ID or URL
|
|
@@ -691,7 +691,7 @@ confluence stats
|
|
|
691
691
|
| `read <pageId_or_url>` | Read page content | `--format <html\|text\|storage\|markdown>` |
|
|
692
692
|
| `info <pageId_or_url>` | Get page information | `--format <text\|json>` |
|
|
693
693
|
| `search <query>` | Search for pages | `--limit <number>` |
|
|
694
|
-
| `spaces` | List
|
|
694
|
+
| `spaces` | List available spaces | `--limit <number>` |
|
|
695
695
|
| `find <title>` | Find a page by its title | `--space <spaceKey>` |
|
|
696
696
|
| `children <pageId>` | List child pages of a page | `--recursive`, `--max-depth <number>`, `--format <list\|tree\|json>`, `--show-url`, `--show-id` |
|
|
697
697
|
| `create <title> <spaceKey>` | Create a new page | `--content <string>`, `--file <path>`, `--format <storage\|html\|markdown>`|
|
|
@@ -739,7 +739,7 @@ confluence info 123456789
|
|
|
739
739
|
# Search with limit
|
|
740
740
|
confluence search "API documentation" --limit 3
|
|
741
741
|
|
|
742
|
-
# List
|
|
742
|
+
# List spaces
|
|
743
743
|
confluence spaces
|
|
744
744
|
|
|
745
745
|
# Move a page to a new parent
|
package/bin/confluence.js
CHANGED
|
@@ -139,13 +139,14 @@ program
|
|
|
139
139
|
// List spaces command
|
|
140
140
|
program
|
|
141
141
|
.command('spaces')
|
|
142
|
-
.description('List
|
|
143
|
-
.
|
|
142
|
+
.description('List Confluence spaces')
|
|
143
|
+
.option('-l, --limit <limit>', 'Limit number of results', '500')
|
|
144
|
+
.action(async (options) => {
|
|
144
145
|
const analytics = new Analytics();
|
|
145
146
|
try {
|
|
146
147
|
const config = getConfig(getProfileName());
|
|
147
148
|
const client = new ConfluenceClient(config);
|
|
148
|
-
const spaces = await client.getSpaces();
|
|
149
|
+
const spaces = await client.getSpaces(parseInt(options.limit));
|
|
149
150
|
|
|
150
151
|
console.log(chalk.blue('Available spaces:'));
|
|
151
152
|
spaces.forEach(space => {
|
package/lib/confluence-client.js
CHANGED
|
@@ -437,12 +437,12 @@ class ConfluenceClient {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
/**
|
|
440
|
-
* Get
|
|
440
|
+
* Get spaces
|
|
441
441
|
*/
|
|
442
|
-
async getSpaces() {
|
|
442
|
+
async getSpaces(limit = 500) {
|
|
443
443
|
const response = await this.client.get('/space', {
|
|
444
444
|
params: {
|
|
445
|
-
limit
|
|
445
|
+
limit
|
|
446
446
|
}
|
|
447
447
|
});
|
|
448
448
|
|
package/lib/macro-converter.js
CHANGED
|
@@ -135,7 +135,11 @@ class MacroConverter {
|
|
|
135
135
|
buildUrl: this.buildUrl,
|
|
136
136
|
webUrlPrefix: this.webUrlPrefix,
|
|
137
137
|
});
|
|
138
|
-
|
|
138
|
+
const result = walker.walk(storage);
|
|
139
|
+
if (typeof options.onWarnings === 'function' && walker.warnings.length > 0) {
|
|
140
|
+
options.onWarnings(walker.warnings);
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
139
143
|
}
|
|
140
144
|
}
|
|
141
145
|
|
package/lib/storage-walker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { Parser, DomHandler } = require('htmlparser2');
|
|
2
2
|
const { decodeHTML } = require('entities');
|
|
3
3
|
const { fenceLength, cleanupWithFences } = require('./markdown-cleanup');
|
|
4
4
|
|
|
@@ -65,12 +65,57 @@ class StorageWalker {
|
|
|
65
65
|
|
|
66
66
|
walk(storage) {
|
|
67
67
|
this._depth = 0;
|
|
68
|
-
|
|
68
|
+
this.warnings = [];
|
|
69
|
+
|
|
70
|
+
// htmlparser2 in xmlMode is lenient: malformed input (unclosed tags,
|
|
71
|
+
// crossed nesting) is auto-closed without raising. We need to surface
|
|
72
|
+
// those events so callers can flag pages that were silently repaired.
|
|
73
|
+
//
|
|
74
|
+
// The handler emits onclosetag(name, isImplied) for *every* tag that
|
|
75
|
+
// wasn't matched by an explicit </tag> â including legitimate XML
|
|
76
|
+
// self-closing tags like `<br/>` and `<ri:attachment/>`. We
|
|
77
|
+
// distinguish the two by tracking each open tag's index range: a
|
|
78
|
+
// self-closing tag's open and close events share the same
|
|
79
|
+
// (startIndex, endIndex), while a genuinely auto-closed tag's close
|
|
80
|
+
// event lands at a later position in the source.
|
|
81
|
+
const handler = new DomHandler(null, { xmlMode: true });
|
|
82
|
+
const openStack = [];
|
|
83
|
+
const origOnOpenTag = handler.onopentag.bind(handler);
|
|
84
|
+
const origOnCloseTag = handler.onclosetag.bind(handler);
|
|
85
|
+
handler.onopentag = (...args) => {
|
|
86
|
+
openStack.push({ sIdx: parser.startIndex, eIdx: parser.endIndex });
|
|
87
|
+
origOnOpenTag(...args);
|
|
88
|
+
};
|
|
89
|
+
handler.onclosetag = (...args) => {
|
|
90
|
+
const [name, isImplied] = args;
|
|
91
|
+
const opened = openStack.pop();
|
|
92
|
+
if (isImplied) {
|
|
93
|
+
const selfClosing =
|
|
94
|
+
opened
|
|
95
|
+
&& opened.sIdx === parser.startIndex
|
|
96
|
+
&& opened.eIdx === parser.endIndex;
|
|
97
|
+
if (!selfClosing) {
|
|
98
|
+
const offset = parser.endIndex;
|
|
99
|
+
this.warnings.push({ type: 'implicit-close', tag: name, offset });
|
|
100
|
+
if (process.env.CONFLUENCE_CLI_VERBOSE) {
|
|
101
|
+
process.stderr.write(
|
|
102
|
+
`StorageWalker: auto-closed <${name}> at offset ${offset}\n`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
origOnCloseTag(...args);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const parser = new Parser(handler, {
|
|
69
111
|
xmlMode: true,
|
|
70
112
|
recognizeSelfClosing: true,
|
|
71
113
|
decodeEntities: true,
|
|
72
114
|
});
|
|
73
|
-
|
|
115
|
+
parser.write(storage);
|
|
116
|
+
parser.end();
|
|
117
|
+
|
|
118
|
+
return this.cleanup(this.walkNodes(handler.dom));
|
|
74
119
|
}
|
|
75
120
|
|
|
76
121
|
walkNodes(nodes) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "confluence-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "confluence-cli",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.2.0",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^1.15.0",
|
package/package.json
CHANGED
|
@@ -221,7 +221,7 @@ confluence search --cql 'siteSearch ~ "deployment pipeline" and space = "MYSPACE
|
|
|
221
221
|
|
|
222
222
|
### `spaces`
|
|
223
223
|
|
|
224
|
-
List
|
|
224
|
+
List accessible Confluence spaces (key and name).
|
|
225
225
|
|
|
226
226
|
```sh
|
|
227
227
|
confluence spaces
|