confluence-exporter 1.0.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/.eslintrc.cjs +18 -0
- package/.github/copilot-instructions.md +3 -0
- package/.github/prompts/analyze.prompt.md +101 -0
- package/.github/prompts/clarify.prompt.md +158 -0
- package/.github/prompts/constitution.prompt.md +73 -0
- package/.github/prompts/implement.prompt.md +56 -0
- package/.github/prompts/plan.prompt.md +50 -0
- package/.github/prompts/specify.prompt.md +21 -0
- package/.github/prompts/tasks.prompt.md +69 -0
- package/LICENSE +21 -0
- package/README.md +332 -0
- package/agents.md +1174 -0
- package/dist/api.d.ts +73 -0
- package/dist/api.js +387 -0
- package/dist/api.js.map +1 -0
- package/dist/commands/download.command.d.ts +18 -0
- package/dist/commands/download.command.js +257 -0
- package/dist/commands/download.command.js.map +1 -0
- package/dist/commands/executor.d.ts +22 -0
- package/dist/commands/executor.js +52 -0
- package/dist/commands/executor.js.map +1 -0
- package/dist/commands/help.command.d.ts +8 -0
- package/dist/commands/help.command.js +68 -0
- package/dist/commands/help.command.js.map +1 -0
- package/dist/commands/index.command.d.ts +14 -0
- package/dist/commands/index.command.js +95 -0
- package/dist/commands/index.command.js.map +1 -0
- package/dist/commands/index.d.ts +13 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/plan.command.d.ts +54 -0
- package/dist/commands/plan.command.js +272 -0
- package/dist/commands/plan.command.js.map +1 -0
- package/dist/commands/registry.d.ts +12 -0
- package/dist/commands/registry.js +32 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/transform.command.d.ts +69 -0
- package/dist/commands/transform.command.js +951 -0
- package/dist/commands/transform.command.js.map +1 -0
- package/dist/commands/types.d.ts +12 -0
- package/dist/commands/types.js +5 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.command.d.ts +10 -0
- package/dist/commands/update.command.js +201 -0
- package/dist/commands/update.command.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.js +52 -0
- package/dist/logger.js.map +1 -0
- package/dist/types.d.ts +167 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +56 -0
- package/dist/utils.js +178 -0
- package/dist/utils.js.map +1 -0
- package/eslint.config.js +29 -0
- package/jest.config.cjs +25 -0
- package/migrate-meta.js +132 -0
- package/package.json +53 -0
- package/src/api.ts +469 -0
- package/src/commands/download.command.ts +324 -0
- package/src/commands/executor.ts +62 -0
- package/src/commands/help.command.ts +72 -0
- package/src/commands/index.command.ts +111 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/plan.command.ts +318 -0
- package/src/commands/registry.ts +39 -0
- package/src/commands/transform.command.ts +1103 -0
- package/src/commands/types.ts +16 -0
- package/src/commands/update.command.ts +229 -0
- package/src/constants.ts +0 -0
- package/src/index.ts +120 -0
- package/src/logger.ts +60 -0
- package/src/test.sh +66 -0
- package/src/types.ts +176 -0
- package/src/utils.ts +204 -0
- package/tests/commands/README.md +123 -0
- package/tests/commands/download.command.test.ts +8 -0
- package/tests/commands/help.command.test.ts +8 -0
- package/tests/commands/index.command.test.ts +8 -0
- package/tests/commands/plan.command.test.ts +15 -0
- package/tests/commands/transform.command.test.ts +8 -0
- package/tests/fixtures/_index.yaml +38 -0
- package/tests/fixtures/mock-pages.ts +62 -0
- package/tsconfig.json +25 -0
- package/vite.config.ts +45 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download command handler - Downloads HTML pages from _queue.yaml
|
|
3
|
+
*/
|
|
4
|
+
import { ConfluenceApi } from '../api.js';
|
|
5
|
+
import path, { join } from 'path';
|
|
6
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'fs';
|
|
7
|
+
import { parse, stringify } from 'yaml';
|
|
8
|
+
import { format } from 'prettier';
|
|
9
|
+
import { updateIndexEntry, readIndexEntry } from '../utils.js';
|
|
10
|
+
export class DownloadCommand {
|
|
11
|
+
config;
|
|
12
|
+
name = 'download';
|
|
13
|
+
description = 'Download HTML pages from Confluence';
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async execute(context) {
|
|
18
|
+
const api = new ConfluenceApi(this.config);
|
|
19
|
+
// Single page mode
|
|
20
|
+
if (this.config.pageId) {
|
|
21
|
+
console.log(`\n📄 Downloading single page: ${this.config.pageId}\n`);
|
|
22
|
+
// Check if page needs downloading
|
|
23
|
+
const indexPath = join(this.config.outputDir, '_index.yaml');
|
|
24
|
+
const indexEntry = readIndexEntry(indexPath, this.config.pageId);
|
|
25
|
+
if (indexEntry && indexEntry.downloadedVersion !== undefined && indexEntry.downloadedAt) {
|
|
26
|
+
// Check if we have current version info
|
|
27
|
+
const currentVersion = indexEntry.version ?? 0;
|
|
28
|
+
const downloadedVersion = indexEntry.downloadedVersion;
|
|
29
|
+
if (currentVersion === downloadedVersion) {
|
|
30
|
+
console.log(`⏭️ Page ${this.config.pageId} is up-to-date (v${downloadedVersion}), skipping download`);
|
|
31
|
+
console.log('\n✅ Download complete!\n');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log(`📥 Updating page ${this.config.pageId} from v${downloadedVersion} to v${currentVersion}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log(`📥 Downloading new page ${this.config.pageId}`);
|
|
40
|
+
}
|
|
41
|
+
await this.downloadPage(api, this.config.pageId);
|
|
42
|
+
console.log('\n✅ Download complete!\n');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Queue mode - check for tree first, then fallback to queue
|
|
46
|
+
const treeFile = join(this.config.outputDir, '_tree.yaml');
|
|
47
|
+
const queueFile = join(this.config.outputDir, '_queue.yaml');
|
|
48
|
+
console.log(`\n🔍 Checking for tree file: ${treeFile}`);
|
|
49
|
+
console.log(`🔍 Checking for queue file: ${queueFile}\n`);
|
|
50
|
+
const hasTree = existsSync(treeFile);
|
|
51
|
+
const hasQueue = existsSync(queueFile);
|
|
52
|
+
if (!hasTree || !hasQueue) {
|
|
53
|
+
throw new Error(`❌ Tree or queue file not found. Run 'plan' command first to create the tree and queue.`);
|
|
54
|
+
}
|
|
55
|
+
// Read queue
|
|
56
|
+
const queueContent = readFileSync(queueFile, 'utf-8');
|
|
57
|
+
const queue = parse(queueContent);
|
|
58
|
+
console.log(`📊 Queue contains ${queue.length} pages\n`);
|
|
59
|
+
// Apply limit if specified
|
|
60
|
+
const pagesToProcess = this.config.limit ? queue.slice(0, this.config.limit) : queue;
|
|
61
|
+
await this.downloadFromQueueWithHierarchy(api, this.config, pagesToProcess);
|
|
62
|
+
}
|
|
63
|
+
async downloadFromQueueWithHierarchy(api, config, queue) {
|
|
64
|
+
const treeFile = join(config.outputDir, '_tree.yaml');
|
|
65
|
+
const treeContent = readFileSync(treeFile, 'utf-8');
|
|
66
|
+
const tree = parse(treeContent);
|
|
67
|
+
// Build a map of pageId -> path
|
|
68
|
+
const pagePathMap = new Map();
|
|
69
|
+
const buildPathMap = (node, currentPath) => {
|
|
70
|
+
// Store the path for this page
|
|
71
|
+
pagePathMap.set(node.id, currentPath);
|
|
72
|
+
// If node has children, build paths for them too
|
|
73
|
+
if (node.children && node.children.length > 0) {
|
|
74
|
+
const slug = this.slugify(node.title);
|
|
75
|
+
const childDir = join(currentPath, `${node.id}-${slug}`);
|
|
76
|
+
for (const child of node.children) {
|
|
77
|
+
buildPathMap(child, childDir);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
// Create root folder for space
|
|
82
|
+
const rootDir = join(config.outputDir, config.spaceKey);
|
|
83
|
+
mkdirSync(rootDir, { recursive: true });
|
|
84
|
+
// Build the path map from tree
|
|
85
|
+
for (const node of tree) {
|
|
86
|
+
buildPathMap(node, rootDir);
|
|
87
|
+
}
|
|
88
|
+
// Display first page path as tree
|
|
89
|
+
const firstPagePath = pagePathMap.get(queue[0].id);
|
|
90
|
+
if (firstPagePath) {
|
|
91
|
+
this.displayPathAsTree(path.dirname(firstPagePath), rootDir);
|
|
92
|
+
}
|
|
93
|
+
// Download pages from queue using the path map in batches
|
|
94
|
+
const batchSize = config.parallel || 5;
|
|
95
|
+
for (let batchStart = 0; batchStart < queue.length; batchStart += batchSize) {
|
|
96
|
+
const batchEnd = Math.min(batchStart + batchSize, queue.length);
|
|
97
|
+
const batch = queue.slice(batchStart, batchEnd);
|
|
98
|
+
console.log(`\n📦 Processing batch ${Math.floor(batchStart / batchSize) + 1}/${Math.ceil(queue.length / batchSize)} (${batch.length} pages)`);
|
|
99
|
+
await this.downloadBatch(api, config, batch, pagePathMap, rootDir);
|
|
100
|
+
}
|
|
101
|
+
console.log('\n✅ Download complete!\n');
|
|
102
|
+
}
|
|
103
|
+
async downloadBatch(api, config, batch, pagePathMap, rootDir) {
|
|
104
|
+
const indexPath = join(config.outputDir, '_index.yaml');
|
|
105
|
+
// Read index once for the entire batch
|
|
106
|
+
const indexContent = readFileSync(indexPath, 'utf-8');
|
|
107
|
+
const allIndexEntries = parse(indexContent);
|
|
108
|
+
const indexMap = new Map(allIndexEntries.map(entry => [entry.id, entry]));
|
|
109
|
+
// Determine which pages need downloading
|
|
110
|
+
const pagesToDownload = [];
|
|
111
|
+
const skippedPages = [];
|
|
112
|
+
for (const entry of batch) {
|
|
113
|
+
const pagePath = pagePathMap.get(entry.id) || rootDir;
|
|
114
|
+
const indexEntry = indexMap.get(entry.id);
|
|
115
|
+
let skip = false;
|
|
116
|
+
let skipReason = '';
|
|
117
|
+
if (indexEntry && indexEntry.downloadedVersion !== undefined && indexEntry.downloadedAt) {
|
|
118
|
+
// Page has been downloaded before
|
|
119
|
+
const currentVersion = entry.version ?? 0;
|
|
120
|
+
const downloadedVersion = indexEntry.downloadedVersion;
|
|
121
|
+
if (currentVersion === downloadedVersion) {
|
|
122
|
+
skip = true;
|
|
123
|
+
skipReason = `(⏭️ skipped - up-to-date v${downloadedVersion})`;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
skipReason = `(📥 updating v${downloadedVersion} → v${currentVersion})`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
skipReason = `(📥 new download)`;
|
|
131
|
+
}
|
|
132
|
+
const filename = `${entry.id}-${this.slugify(entry.title)}.html`;
|
|
133
|
+
const deep = Math.max(0, pagePath.split(path.sep).length - rootDir.split(path.sep).length - 1);
|
|
134
|
+
console.log(`${' '.repeat(deep)}/${filename} ${skipReason}`);
|
|
135
|
+
if (skip) {
|
|
136
|
+
skippedPages.push({ entry, pagePath, skipReason });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
pagesToDownload.push({ entry, pagePath, skipReason });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Download pages in parallel
|
|
143
|
+
if (pagesToDownload.length > 0) {
|
|
144
|
+
console.log(`\n📥 Downloading ${pagesToDownload.length} pages in parallel...`);
|
|
145
|
+
const downloadPromises = pagesToDownload.map(async ({ entry, pagePath }) => {
|
|
146
|
+
try {
|
|
147
|
+
// Create directory if it doesn't exist
|
|
148
|
+
mkdirSync(pagePath, { recursive: true });
|
|
149
|
+
const page = await api.getPage(entry.id);
|
|
150
|
+
// Update the index entry in memory
|
|
151
|
+
const indexEntry = indexMap.get(entry.id);
|
|
152
|
+
if (indexEntry) {
|
|
153
|
+
indexEntry.downloadedVersion = page.version ?? 0;
|
|
154
|
+
indexEntry.downloadedAt = new Date().toISOString();
|
|
155
|
+
}
|
|
156
|
+
return { entry, page, pagePath, success: true };
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
console.error(`❌ Failed to download page ${entry.id}:`, error);
|
|
160
|
+
return { entry, page: null, pagePath, success: false };
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const results = await Promise.all(downloadPromises);
|
|
164
|
+
// Process successful downloads
|
|
165
|
+
for (const result of results) {
|
|
166
|
+
if (result.success && result.page) {
|
|
167
|
+
try {
|
|
168
|
+
await this.savePageToFile(result.page, result.pagePath);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(`❌ Failed to save page ${result.entry.id}:`, error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Write updated index back to file once for the entire batch
|
|
177
|
+
if (pagesToDownload.length > 0) {
|
|
178
|
+
const yamlContent = stringify(allIndexEntries, {
|
|
179
|
+
indent: 2,
|
|
180
|
+
lineWidth: 0
|
|
181
|
+
});
|
|
182
|
+
writeFileSync(indexPath, yamlContent, 'utf-8');
|
|
183
|
+
console.log(`💾 Updated index with ${pagesToDownload.length} downloaded pages`);
|
|
184
|
+
}
|
|
185
|
+
console.log(`✅ Batch complete: ${pagesToDownload.length} downloaded, ${skippedPages.length} skipped`);
|
|
186
|
+
}
|
|
187
|
+
async savePageToFile(page, filePath) {
|
|
188
|
+
const slug = this.slugify(page.title);
|
|
189
|
+
const filename = `${page.id}-${slug}.html`;
|
|
190
|
+
const fullPath = join(filePath, filename);
|
|
191
|
+
// Format HTML with Prettier
|
|
192
|
+
let formattedHtml = page.body;
|
|
193
|
+
try {
|
|
194
|
+
formattedHtml = await format(page.body, {
|
|
195
|
+
parser: 'html',
|
|
196
|
+
printWidth: 120,
|
|
197
|
+
htmlWhitespaceSensitivity: 'ignore',
|
|
198
|
+
tabWidth: 2,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
console.warn(`⚠️ Failed to format HTML for ${page.title}, saving unformatted`);
|
|
203
|
+
}
|
|
204
|
+
writeFileSync(fullPath, formattedHtml, 'utf-8');
|
|
205
|
+
}
|
|
206
|
+
displayPathAsTree(fullPath, rootDir) {
|
|
207
|
+
// Get relative path from root
|
|
208
|
+
const relativePath = path.relative(rootDir, fullPath);
|
|
209
|
+
// Split path into segments
|
|
210
|
+
const segments = relativePath.split(path.sep).filter(s => s);
|
|
211
|
+
// Display each segment with proper indentation
|
|
212
|
+
for (let i = 0; i < segments.length; i++) {
|
|
213
|
+
const indent = ' '.repeat(i);
|
|
214
|
+
console.log(`${indent}/${segments[i]}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async downloadPage(api, pageId, outputDir) {
|
|
218
|
+
const page = await api.getPage(pageId);
|
|
219
|
+
const slug = this.slugify(page.title);
|
|
220
|
+
const filename = `${pageId}-${slug}.html`;
|
|
221
|
+
const dir = outputDir || process.cwd();
|
|
222
|
+
const filepath = join(dir, filename);
|
|
223
|
+
// Format HTML with Prettier
|
|
224
|
+
let formattedHtml = page.body;
|
|
225
|
+
try {
|
|
226
|
+
formattedHtml = await format(page.body, {
|
|
227
|
+
parser: 'html',
|
|
228
|
+
printWidth: 120,
|
|
229
|
+
htmlWhitespaceSensitivity: 'ignore',
|
|
230
|
+
tabWidth: 2,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
console.warn(`⚠️ Failed to format HTML for ${page.title}, saving unformatted`);
|
|
235
|
+
}
|
|
236
|
+
writeFileSync(filepath, formattedHtml, 'utf-8');
|
|
237
|
+
// Update _index.yaml with download metadata
|
|
238
|
+
const indexPath = join(this.config.outputDir, '_index.yaml');
|
|
239
|
+
const success = updateIndexEntry(indexPath, page.id, {
|
|
240
|
+
downloadedVersion: page.version ?? 0,
|
|
241
|
+
downloadedAt: new Date().toISOString()
|
|
242
|
+
});
|
|
243
|
+
if (!success) {
|
|
244
|
+
console.warn(`⚠️ Failed to update index for page ${page.title}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
slugify(text) {
|
|
248
|
+
return text
|
|
249
|
+
.toLowerCase()
|
|
250
|
+
.replace(/[^\w\s-]/g, '')
|
|
251
|
+
.replace(/\s+/g, '-')
|
|
252
|
+
.replace(/-+/g, '-')
|
|
253
|
+
.trim()
|
|
254
|
+
.substring(0, 50); // Limit length for filesystem
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=download.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.command.js","sourceRoot":"","sources":["../../src/commands/download.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command executor - orchestrates command execution
|
|
3
|
+
*/
|
|
4
|
+
import { ConfluenceConfig } from 'src/types.js';
|
|
5
|
+
import type { Command, CommandContext } from './types.js';
|
|
6
|
+
export declare class CommandExecutor {
|
|
7
|
+
private config;
|
|
8
|
+
private registry;
|
|
9
|
+
constructor(config: ConfluenceConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Validate commands and return parsed list
|
|
12
|
+
*/
|
|
13
|
+
validateCommands(commands: string[]): Command[];
|
|
14
|
+
/**
|
|
15
|
+
* Execute a sequence of commands
|
|
16
|
+
*/
|
|
17
|
+
executeCommands(commands: Command[], context: CommandContext): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Get list of valid commands
|
|
20
|
+
*/
|
|
21
|
+
getValidCommands(): Command[];
|
|
22
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command executor - orchestrates command execution
|
|
3
|
+
*/
|
|
4
|
+
import { CommandRegistry } from './registry.js';
|
|
5
|
+
export class CommandExecutor {
|
|
6
|
+
config;
|
|
7
|
+
registry;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.registry = new CommandRegistry(config);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validate commands and return parsed list
|
|
14
|
+
*/
|
|
15
|
+
validateCommands(commands) {
|
|
16
|
+
const validated = [];
|
|
17
|
+
for (const cmd of commands) {
|
|
18
|
+
const command = cmd.toLowerCase();
|
|
19
|
+
if (this.registry.isValidCommand(command)) {
|
|
20
|
+
validated.push(command);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw new Error(`Unknown command: "${cmd}"`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return validated;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Execute a sequence of commands
|
|
30
|
+
*/
|
|
31
|
+
async executeCommands(commands, context) {
|
|
32
|
+
for (let i = 0; i < commands.length; i++) {
|
|
33
|
+
const command = commands[i];
|
|
34
|
+
if (i > 0) {
|
|
35
|
+
console.log('\n' + '─'.repeat(60) + '\n');
|
|
36
|
+
}
|
|
37
|
+
const handler = this.registry.getHandler(command);
|
|
38
|
+
if (!handler) {
|
|
39
|
+
throw new Error(`No handler found for command: ${command}`);
|
|
40
|
+
}
|
|
41
|
+
await handler.execute(context);
|
|
42
|
+
}
|
|
43
|
+
console.log('\n✓ All commands completed successfully!');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get list of valid commands
|
|
47
|
+
*/
|
|
48
|
+
getValidCommands() {
|
|
49
|
+
return this.registry.getValidCommands();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/commands/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,OAAO,eAAe;IAGN;IAFZ,QAAQ,CAAkB;IAElC,YAAoB,MAAwB;QAAxB,WAAM,GAAN,MAAM,CAAkB;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,QAAkB;QACjC,MAAM,SAAS,GAAc,EAAE,CAAC;QAEhC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,GAAG,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,QAAmB,EAAE,OAAuB;QAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAE5B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACV,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;YAC9D,CAAC;YAED,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help command handler
|
|
3
|
+
*/
|
|
4
|
+
export class HelpCommand {
|
|
5
|
+
async execute(_context) {
|
|
6
|
+
this.showHelp();
|
|
7
|
+
}
|
|
8
|
+
showHelp() {
|
|
9
|
+
console.log('Minimal Confluence to Markdown Exporter\n');
|
|
10
|
+
console.log('Usage: node index.js [command] [options]\n');
|
|
11
|
+
console.log('If no command is provided, runs full sync: update index (or create if not exists), plan, download, and transform.\n');
|
|
12
|
+
console.log('Commands:');
|
|
13
|
+
console.log(' help Show this help message');
|
|
14
|
+
console.log(' index Create _index.yaml with page metadata');
|
|
15
|
+
console.log(' update Check for new/updated pages and update _index.yaml');
|
|
16
|
+
console.log(' plan Create _queue.yaml for download (from index or specific page tree)');
|
|
17
|
+
console.log(' download Download HTML pages from _queue.yaml');
|
|
18
|
+
console.log(' transform Transform HTML files to Markdown (skips existing MD files, creates links structure)');
|
|
19
|
+
console.log(' index plan download transform Run all commands in sequence\n');
|
|
20
|
+
console.log('Options:');
|
|
21
|
+
console.log(' -u, --url <url> Confluence base URL');
|
|
22
|
+
console.log(' -n, --username <email> Confluence username/email');
|
|
23
|
+
console.log(' -p, --password <token> Confluence API token');
|
|
24
|
+
console.log(' -s, --space <key> Confluence space key');
|
|
25
|
+
console.log(' -i, --pageId <id> Download specific page ID only (optional)');
|
|
26
|
+
console.log(' -o, --output <dir> Output directory (default: ./output)');
|
|
27
|
+
console.log(' -l, --limit <number> Limit number of pages to process (optional)');
|
|
28
|
+
console.log(' --parallel <number> Number of concurrent operations (default: 5)');
|
|
29
|
+
console.log(' -f, --force Force re-download of all pages (skip version check)');
|
|
30
|
+
console.log(' --clear Clear existing MD files and images before transforming');
|
|
31
|
+
console.log(' --pageSize <number> Items per API page (default: 25)');
|
|
32
|
+
console.log(' -h, --help Show this help message\n');
|
|
33
|
+
console.log('Environment Variables:');
|
|
34
|
+
console.log(' CONFLUENCE_BASE_URL');
|
|
35
|
+
console.log(' CONFLUENCE_USERNAME');
|
|
36
|
+
console.log(' CONFLUENCE_PASSWORD');
|
|
37
|
+
console.log(' CONFLUENCE_SPACE_KEY');
|
|
38
|
+
console.log(' OUTPUT_DIR\n');
|
|
39
|
+
console.log('Examples:');
|
|
40
|
+
console.log(' # Full workflow: index, plan, download, and transform');
|
|
41
|
+
console.log(' node index.js index plan download transform -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
42
|
+
console.log(' # Full workflow with limit (process first 10 pages only)');
|
|
43
|
+
console.log(' node index.js index plan download transform -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE -l 10\n');
|
|
44
|
+
console.log(' # Create index only (Phase 1)');
|
|
45
|
+
console.log(' node index.js index -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
46
|
+
console.log(' # Check for new/updated pages and update existing index');
|
|
47
|
+
console.log(' node index.js update -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
48
|
+
console.log(' # Create download queue from existing index (Phase 2)');
|
|
49
|
+
console.log(' node index.js plan -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
50
|
+
console.log(' # Create download queue for specific page and all children');
|
|
51
|
+
console.log(' node index.js plan -i 123456789 -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
52
|
+
console.log(' # Force re-download all pages (ignore version check)');
|
|
53
|
+
console.log(' node index.js plan --force -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
54
|
+
console.log(' # Download HTML pages from existing queue (Phase 3)');
|
|
55
|
+
console.log(' node index.js download -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
56
|
+
console.log(' # Transform HTML to Markdown (Phase 4)');
|
|
57
|
+
console.log(' node index.js transform -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
58
|
+
console.log(' # Transform HTML to Markdown with clear (remove existing MD files first)');
|
|
59
|
+
console.log(' node index.js transform --clear -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
60
|
+
console.log(' # Download and transform together');
|
|
61
|
+
console.log(' node index.js download transform -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
62
|
+
console.log(' # Download and transform with higher concurrency');
|
|
63
|
+
console.log(' node index.js download transform --parallel 10 -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE\n');
|
|
64
|
+
console.log(' # Download single page HTML only (no index/plan needed)');
|
|
65
|
+
console.log(' node index.js download -i 123456789 -u https://mysite.atlassian.net -n user@example.com -p token -s MYSPACE');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=help.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.command.js","sourceRoot":"","sources":["../../src/commands/help.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index command handler - Creates _index.yaml with all page metadata
|
|
3
|
+
*/
|
|
4
|
+
import type { ConfluenceConfig } from '../types.js';
|
|
5
|
+
import type { CommandContext, CommandHandler } from './types.js';
|
|
6
|
+
export declare class IndexCommand implements CommandHandler {
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: ConfluenceConfig);
|
|
9
|
+
execute(context: CommandContext): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Create _index.yaml file with all pages to download
|
|
12
|
+
*/
|
|
13
|
+
private createIndex;
|
|
14
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index command handler - Creates _index.yaml with all page metadata
|
|
3
|
+
*/
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import yaml from 'yaml';
|
|
7
|
+
import { ConfluenceApi } from '../api.js';
|
|
8
|
+
export class IndexCommand {
|
|
9
|
+
config;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async execute(context) {
|
|
14
|
+
const api = new ConfluenceApi(this.config);
|
|
15
|
+
// Create output directory if it doesn't exist
|
|
16
|
+
await fs.mkdir(this.config.outputDir, { recursive: true });
|
|
17
|
+
console.log(`Starting indexing of space: ${this.config.spaceKey}`);
|
|
18
|
+
console.log(`Output directory: ${this.config.outputDir}\n`);
|
|
19
|
+
// Phase 1: Create _index.yaml
|
|
20
|
+
console.log('Phase 1: Creating _index.yaml...');
|
|
21
|
+
await this.createIndex(api, this.config);
|
|
22
|
+
console.log(`\nIndexing complete!`);
|
|
23
|
+
console.log(`Index saved to: ${this.config.outputDir}/_index.yaml`);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create _index.yaml file with all pages to download
|
|
27
|
+
*/
|
|
28
|
+
async createIndex(api, config) {
|
|
29
|
+
const indexPath = path.join(config.outputDir, '_index.yaml');
|
|
30
|
+
let pageCount = 0;
|
|
31
|
+
let pageSize = config.pageSize || 100;
|
|
32
|
+
let startFrom = 0;
|
|
33
|
+
// Check if _index.yaml already exists (resume functionality)
|
|
34
|
+
try {
|
|
35
|
+
const existingContent = await fs.readFile(indexPath, 'utf-8');
|
|
36
|
+
// Extract page size from comment if it exists
|
|
37
|
+
const pageSizeMatch = existingContent.match(/# Page Size: (\d+)/);
|
|
38
|
+
if (pageSizeMatch) {
|
|
39
|
+
pageSize = parseInt(pageSizeMatch[1], 10);
|
|
40
|
+
console.log(`Using existing page size from index: ${pageSize}`);
|
|
41
|
+
}
|
|
42
|
+
const existingPages = yaml.parse(existingContent);
|
|
43
|
+
if (existingPages && Array.isArray(existingPages)) {
|
|
44
|
+
pageCount = existingPages.length;
|
|
45
|
+
// Calculate the start position for the API
|
|
46
|
+
startFrom = pageCount;
|
|
47
|
+
console.log(`Found existing index with ${pageCount} pages. Resuming from position ${startFrom + 1}...\n`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (_error) {
|
|
51
|
+
// File doesn't exist or is invalid, start fresh
|
|
52
|
+
const header = `# Confluence Export Index
|
|
53
|
+
# Space: ${config.spaceKey}
|
|
54
|
+
# Export Date: ${new Date().toISOString()}
|
|
55
|
+
# Page Size: ${pageSize}
|
|
56
|
+
|
|
57
|
+
`;
|
|
58
|
+
await fs.writeFile(indexPath, header, 'utf-8');
|
|
59
|
+
console.log(`Creating new index with page size: ${pageSize}...\n`);
|
|
60
|
+
}
|
|
61
|
+
// Fetch pages starting from where we left off
|
|
62
|
+
for await (const page of api.getAllPages(config.spaceKey, pageSize, startFrom)) {
|
|
63
|
+
pageCount++;
|
|
64
|
+
console.log(`[${pageCount}] Indexed: ${page.title} (${page.id}) [API Page ${page.apiPageNumber}]`);
|
|
65
|
+
// Create page entry
|
|
66
|
+
const pageEntry = {
|
|
67
|
+
id: page.id,
|
|
68
|
+
title: page.title,
|
|
69
|
+
version: page.version,
|
|
70
|
+
parentId: page.parentId,
|
|
71
|
+
modifiedDate: page.modifiedDate,
|
|
72
|
+
indexedDate: new Date().toISOString(),
|
|
73
|
+
pageNumber: page.apiPageNumber
|
|
74
|
+
};
|
|
75
|
+
// Convert to YAML and format as array item (with leading -)
|
|
76
|
+
const yamlDoc = yaml.stringify(pageEntry).trim();
|
|
77
|
+
const lines = yamlDoc.split('\n');
|
|
78
|
+
const arrayItem = lines.map((line, index) => {
|
|
79
|
+
if (index === 0) {
|
|
80
|
+
return `- ${line}`;
|
|
81
|
+
}
|
|
82
|
+
return ` ${line}`;
|
|
83
|
+
}).join('\n');
|
|
84
|
+
await fs.appendFile(indexPath, arrayItem + '\n', 'utf-8');
|
|
85
|
+
// Check if limit is reached
|
|
86
|
+
if (config.limit && pageCount >= config.limit) {
|
|
87
|
+
console.log(`\n⚠ Limit reached: ${config.limit} pages indexed`);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
console.log(`\n✓ Index created: ${indexPath}`);
|
|
92
|
+
console.log(` Total pages indexed: ${pageCount}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=index.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.command.js","sourceRoot":"","sources":["../../src/commands/index.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands module exports
|
|
3
|
+
* Re-exports all command-related classes and types for easier importing
|
|
4
|
+
*/
|
|
5
|
+
export { HelpCommand } from './help.command.js';
|
|
6
|
+
export { IndexCommand } from './index.command.js';
|
|
7
|
+
export { UpdateCommand } from './update.command.js';
|
|
8
|
+
export { PlanCommand } from './plan.command.js';
|
|
9
|
+
export { DownloadCommand } from './download.command.js';
|
|
10
|
+
export { TransformCommand } from './transform.command.js';
|
|
11
|
+
export { CommandRegistry } from './registry.js';
|
|
12
|
+
export { CommandExecutor } from './executor.js';
|
|
13
|
+
export type { Command, CommandContext, CommandHandler } from './types.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands module exports
|
|
3
|
+
* Re-exports all command-related classes and types for easier importing
|
|
4
|
+
*/
|
|
5
|
+
export { HelpCommand } from './help.command.js';
|
|
6
|
+
export { IndexCommand } from './index.command.js';
|
|
7
|
+
export { UpdateCommand } from './update.command.js';
|
|
8
|
+
export { PlanCommand } from './plan.command.js';
|
|
9
|
+
export { DownloadCommand } from './download.command.js';
|
|
10
|
+
export { TransformCommand } from './transform.command.js';
|
|
11
|
+
export { CommandRegistry } from './registry.js';
|
|
12
|
+
export { CommandExecutor } from './executor.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan command handler - Creates _queue.yaml for download
|
|
3
|
+
*/
|
|
4
|
+
import type { ConfluenceConfig, PageTreeNode } from '../types.js';
|
|
5
|
+
import type { CommandContext, CommandHandler } from './types.js';
|
|
6
|
+
export declare class PlanCommand implements CommandHandler {
|
|
7
|
+
private config;
|
|
8
|
+
queuePath: string;
|
|
9
|
+
treePath: string;
|
|
10
|
+
tree: PageTreeNode[];
|
|
11
|
+
constructor(config: ConfluenceConfig);
|
|
12
|
+
execute(context: CommandContext): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Recursively collect a page and all its descendants
|
|
15
|
+
*/
|
|
16
|
+
private collectPageTree;
|
|
17
|
+
/**
|
|
18
|
+
* Find a node by ID in the tree structure
|
|
19
|
+
*/
|
|
20
|
+
private findNodeInTree;
|
|
21
|
+
/**
|
|
22
|
+
* Flatten tree structure to array of PageIndexEntry
|
|
23
|
+
*/
|
|
24
|
+
private flattenTree;
|
|
25
|
+
/**
|
|
26
|
+
* Flatten array of tree nodes to array of PageIndexEntry
|
|
27
|
+
*/
|
|
28
|
+
private flattenTreeArray;
|
|
29
|
+
/**
|
|
30
|
+
* Filter pages based on whether they need to be downloaded
|
|
31
|
+
* Checks for existing files and compares versions/dates
|
|
32
|
+
*
|
|
33
|
+
* @param pages - All pages from the tree
|
|
34
|
+
* @param forceMode - If true, skip all checks and include all pages
|
|
35
|
+
* @returns Filtered pages with queueReason and statistics
|
|
36
|
+
*/
|
|
37
|
+
private filterPagesForQueue;
|
|
38
|
+
/**
|
|
39
|
+
* Load all index entries from _index.yaml file
|
|
40
|
+
*/
|
|
41
|
+
private loadIndexEntries;
|
|
42
|
+
/**
|
|
43
|
+
* Build tree structure from flat index
|
|
44
|
+
*/
|
|
45
|
+
private buildTreeFromIndex;
|
|
46
|
+
/**
|
|
47
|
+
* Write _tree.yaml file with hierarchical structure
|
|
48
|
+
*/
|
|
49
|
+
private writeTree;
|
|
50
|
+
/**
|
|
51
|
+
* Write _queue.yaml file
|
|
52
|
+
*/
|
|
53
|
+
private writeQueue;
|
|
54
|
+
}
|