@markwinap/confluence-sync-core 1.0.2

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.
Files changed (63) hide show
  1. package/.github/workflows/publish.yml +40 -0
  2. package/README.md +9 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +41 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +15 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +73 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/confluenceClient.d.ts +19 -0
  12. package/dist/confluenceClient.d.ts.map +1 -0
  13. package/dist/confluenceClient.js +147 -0
  14. package/dist/confluenceClient.js.map +1 -0
  15. package/dist/contracts.d.ts +112 -0
  16. package/dist/contracts.d.ts.map +1 -0
  17. package/dist/contracts.js +15 -0
  18. package/dist/contracts.js.map +1 -0
  19. package/dist/diff.d.ts +14 -0
  20. package/dist/diff.d.ts.map +1 -0
  21. package/dist/diff.js +74 -0
  22. package/dist/diff.js.map +1 -0
  23. package/dist/format.d.ts +3 -0
  24. package/dist/format.d.ts.map +1 -0
  25. package/dist/format.js +194 -0
  26. package/dist/format.js.map +1 -0
  27. package/dist/index.d.ts +15 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +33 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/manifest.d.ts +6 -0
  32. package/dist/manifest.d.ts.map +1 -0
  33. package/dist/manifest.js +57 -0
  34. package/dist/manifest.js.map +1 -0
  35. package/dist/paths.d.ts +6 -0
  36. package/dist/paths.d.ts.map +1 -0
  37. package/dist/paths.js +54 -0
  38. package/dist/paths.js.map +1 -0
  39. package/dist/progress.d.ts +67 -0
  40. package/dist/progress.d.ts.map +1 -0
  41. package/dist/progress.js +168 -0
  42. package/dist/progress.js.map +1 -0
  43. package/dist/project.d.ts +11 -0
  44. package/dist/project.d.ts.map +1 -0
  45. package/dist/project.js +114 -0
  46. package/dist/project.js.map +1 -0
  47. package/dist/pull.d.ts +8 -0
  48. package/dist/pull.d.ts.map +1 -0
  49. package/dist/pull.js +303 -0
  50. package/dist/pull.js.map +1 -0
  51. package/dist/push.d.ts +6 -0
  52. package/dist/push.d.ts.map +1 -0
  53. package/dist/push.js +129 -0
  54. package/dist/push.js.map +1 -0
  55. package/dist/status.d.ts +29 -0
  56. package/dist/status.d.ts.map +1 -0
  57. package/dist/status.js +153 -0
  58. package/dist/status.js.map +1 -0
  59. package/dist/types.d.ts +103 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +3 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +26 -0
@@ -0,0 +1,40 @@
1
+ name: Publish package
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: 20
20
+ registry-url: https://registry.npmjs.org
21
+ cache: npm
22
+
23
+ - run: npm ci
24
+
25
+ - id: package
26
+ run: |
27
+ echo "name=$(node -p "require('./package.json').name")" >> "$GITHUB_OUTPUT"
28
+ echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
29
+
30
+ - id: version
31
+ env:
32
+ PACKAGE_NAME: ${{ steps.package.outputs.name }}
33
+ PACKAGE_VERSION: ${{ steps.package.outputs.version }}
34
+ run: |
35
+ if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version --registry=https://registry.npmjs.org > /dev/null 2>&1; then
36
+ echo "publish=false" >> "$GITHUB_OUTPUT"
37
+ else
38
+ echo "publish=true" >> "$GITHUB_OUTPUT"
39
+ fi
40
+
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @markwinap/confluence-sync-core
2
+
3
+ Framework-neutral Confluence content synchronization library.
4
+
5
+ This package provides the shared engine used by `confluence-sync` (CLI) and the VS Code extension. It is not intended to be used directly by end users.
6
+
7
+ ## Publishing
8
+
9
+ Push a commit to `main` with a new `version` in `package.json` to publish it. The GitHub repository requires an `NPM_TOKEN` Actions secret containing an npm granular access token with publish permission for `@markwinap/confluence-sync-core`.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("./config");
4
+ const confluenceClient_1 = require("./confluenceClient");
5
+ const manifest_1 = require("./manifest");
6
+ const pull_1 = require("./pull");
7
+ const push_1 = require("./push");
8
+ const status_1 = require("./status");
9
+ async function main() {
10
+ const [command, ...args] = process.argv.slice(2);
11
+ if (!command || command === "help" || args.includes("--help"))
12
+ return usage();
13
+ const contentDir = process.env.CONFLUENCE_SYNC_CONTENT_DIR;
14
+ const config = (0, config_1.loadConfig)(contentDir);
15
+ const client = new confluenceClient_1.ConfluenceClient(config);
16
+ if (command === "pull") {
17
+ const dryRun = args.includes("--dry-run");
18
+ const trashFlag = args.includes("--trash") || process.env.PULL_TRASH_DELETED === "1";
19
+ const result = await (0, pull_1.pull)(config, client, { prune: trashFlag, dryRun });
20
+ const deletionCount = result.manifest.deletions?.length || 0;
21
+ const deletionMsg = deletionCount ? `, ${deletionCount} deletion(s) detected` : "";
22
+ const trashMsg = trashFlag && !dryRun ? " and moved to trash" : trashFlag && dryRun ? " (dry-run, not moved)" : "";
23
+ console.log(`Pull complete: ${result.manifest.items.length} item(s), ${result.manifest.warnings.length} warning(s)${deletionMsg}${trashMsg}.`);
24
+ }
25
+ else if (command === "status") {
26
+ (0, status_1.printStatus)(await (0, status_1.getStatus)(config.contentDir, (0, manifest_1.readManifest)(config.contentDir), client));
27
+ }
28
+ else if (command === "push") {
29
+ const manifest = (0, manifest_1.readManifest)(config.contentDir);
30
+ const changes = await (0, status_1.getStatus)(config.contentDir, manifest, client);
31
+ (0, status_1.printStatus)(changes);
32
+ await (0, push_1.push)(config, manifest, changes, client, args.includes("--dry-run"));
33
+ }
34
+ else
35
+ throw new Error(`Unknown command: ${command}`);
36
+ }
37
+ function usage() {
38
+ console.log("Usage: npm run <pull|status|push> [-- --dry-run]\n\nCommands:\n pull Download the configured Confluence subtree\n pull -- --trash Move locally-stored items deleted from Confluence to the trash folder\n pull -- --trash --dry-run Preview which local items would be moved to trash\n (On Windows/PowerShell with npm run, set PULL_TRASH_DELETED=1 instead of --trash)\n status Compare local hashes and remote versions\n push -- --dry-run Preview safe upserts\n push Apply safe page and attachment upserts");
39
+ }
40
+ main().catch(error => { console.error(error instanceof Error ? error.message : error); process.exitCode = 1; });
41
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface Config {
2
+ email: string;
3
+ token: string;
4
+ baseUrl: string;
5
+ spaceKey: string;
6
+ rootPageId: string;
7
+ contentDir: string;
8
+ minDelayMs: number;
9
+ maxDelayMs: number;
10
+ attachmentMinDelayMs: number;
11
+ attachmentMaxDelayMs: number;
12
+ concurrency?: number;
13
+ }
14
+ export declare function loadConfig(contentDir?: string): Config;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAyBtD"}
package/dist/config.js ADDED
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const dotenv_1 = require("dotenv");
38
+ const path = __importStar(require("path"));
39
+ function loadConfig(contentDir) {
40
+ const rootDir = process.env.CONFLUENCE_SYNC_PROJECT_DIR || process.cwd();
41
+ (0, dotenv_1.config)({ path: path.resolve(rootDir, ".env") });
42
+ const email = process.env.ATLASSIAN_EMAIL;
43
+ const token = process.env.ATLASSIAN_API_TOKEN;
44
+ if (!email || !token)
45
+ throw new Error("ATLASSIAN_EMAIL and ATLASSIAN_API_TOKEN must be set in .env");
46
+ const baseUrl = new URL(process.env.CONFLUENCE_BASE_URL || "https://example.atlassian.net").origin;
47
+ const minDelayMs = numberEnv("RATE_LIMIT_MIN_MS", 250);
48
+ const maxDelayMs = numberEnv("RATE_LIMIT_MAX_MS", 750);
49
+ const attachmentMinDelayMs = numberEnv("ATTACHMENT_RATE_LIMIT_MIN_MS", 100);
50
+ const attachmentMaxDelayMs = numberEnv("ATTACHMENT_RATE_LIMIT_MAX_MS", 400);
51
+ if (minDelayMs > maxDelayMs || attachmentMinDelayMs > attachmentMaxDelayMs)
52
+ throw new Error("Minimum delays cannot exceed maximum delays");
53
+ return {
54
+ email,
55
+ token,
56
+ baseUrl,
57
+ spaceKey: process.env.CONFLUENCE_SPACE_KEY || "SPACE",
58
+ rootPageId: process.env.CONFLUENCE_ROOT_PAGE_ID || "0",
59
+ contentDir: contentDir || path.resolve(rootDir, "content"),
60
+ minDelayMs,
61
+ maxDelayMs,
62
+ attachmentMinDelayMs,
63
+ attachmentMaxDelayMs,
64
+ concurrency: 5,
65
+ };
66
+ }
67
+ function numberEnv(name, fallback) {
68
+ const value = Number(process.env[name] ?? fallback);
69
+ if (!Number.isFinite(value) || value < 0)
70
+ throw new Error(`${name} must be a non-negative number`);
71
+ return value;
72
+ }
73
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,gCAyBC;AA1CD,mCAA2C;AAC3C,2CAA6B;AAgB7B,SAAgB,UAAU,CAAC,UAAmB;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzE,IAAA,eAAO,EAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAC9C,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACrG,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,+BAA+B,CAAC,CAAC,MAAM,CAAC;IACnG,MAAM,UAAU,GAAG,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,SAAS,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,oBAAoB,GAAG,SAAS,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,oBAAoB,GAAG,SAAS,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;IAC5E,IAAI,UAAU,GAAG,UAAU,IAAI,oBAAoB,GAAG,oBAAoB;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC3I,OAAO;QACL,KAAK;QACL,KAAK;QACL,OAAO;QACP,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO;QACrD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,GAAG;QACtD,UAAU,EAAE,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;QAC1D,UAAU;QACV,UAAU;QACV,oBAAoB;QACpB,oBAAoB;QACpB,WAAW,EAAE,CAAC;KACf,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,QAAgB;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gCAAgC,CAAC,CAAC;IACnG,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Config } from "./config";
2
+ import { ContentType, RemoteAttachment, RemoteContent } from "./types";
3
+ export declare class ConfluenceClient {
4
+ private readonly config;
5
+ private readonly http;
6
+ constructor(config: Config);
7
+ getContent(id: string, type: ContentType): Promise<RemoteContent>;
8
+ getDescendants(pageId: string): Promise<RemoteContent[]>;
9
+ getAttachments(pageId: string): Promise<RemoteAttachment[]>;
10
+ downloadAttachment(pageId: string, attachment: RemoteAttachment): Promise<Buffer>;
11
+ createPage(spaceId: string, title: string, parentId: string | undefined, storage: string): Promise<RemoteContent>;
12
+ updatePage(id: string, title: string, version: number, storage: string): Promise<RemoteContent>;
13
+ uploadAttachment(pageId: string, file: string, existingId?: string): Promise<void>;
14
+ private paginate;
15
+ private request;
16
+ private pause;
17
+ private friendlyError;
18
+ }
19
+ //# sourceMappingURL=confluenceClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluenceClient.d.ts","sourceRoot":"","sources":["../src/confluenceClient.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIvE,qBAAa,gBAAgB;IAEf,OAAO,CAAC,QAAQ,CAAC,MAAM;IADnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBACR,MAAM,EAAE,MAAM;IAIrC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAMjE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAgBxD,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAU3D,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IASjF,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAIjH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI/F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAO1E,QAAQ;YAaR,OAAO;YAeP,KAAK;IAMnB,OAAO,CAAC,aAAa;CAKtB"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ConfluenceClient = void 0;
40
+ const axios_1 = __importStar(require("axios"));
41
+ const form_data_1 = __importDefault(require("form-data"));
42
+ const fs_1 = require("fs");
43
+ class ConfluenceClient {
44
+ config;
45
+ http;
46
+ constructor(config) {
47
+ this.config = config;
48
+ this.http = axios_1.default.create({ baseURL: config.baseUrl, auth: { username: config.email, password: config.token }, timeout: 60000, headers: { Accept: "application/json", "User-Agent": "ConfluenceDocumentationSync/1.0" } });
49
+ }
50
+ async getContent(id, type) {
51
+ const plural = type === "database" ? "databases" : `${type}s`;
52
+ const params = type === "page" ? { "body-format": "storage" } : undefined;
53
+ return (await this.request({ method: "GET", url: `/wiki/api/v2/${plural}/${id}`, params })).data;
54
+ }
55
+ async getDescendants(pageId) {
56
+ const found = new Map();
57
+ const queue = [{ id: pageId, type: "page" }];
58
+ while (queue.length) {
59
+ const current = queue.shift();
60
+ const plural = current.type === "database" ? "databases" : `${current.type}s`;
61
+ const batch = await this.paginate(`/wiki/api/v2/${plural}/${current.id}/descendants`, { depth: 10, limit: 100 });
62
+ for (const item of batch) {
63
+ const normalized = { ...item, id: String(item.id) };
64
+ if (!found.has(normalized.id))
65
+ found.set(normalized.id, normalized);
66
+ if (item.depth === 10)
67
+ queue.push({ id: normalized.id, type: normalized.type });
68
+ }
69
+ }
70
+ return [...found.values()];
71
+ }
72
+ async getAttachments(pageId) {
73
+ const rows = await this.paginate(`/wiki/api/v2/pages/${pageId}/attachments`, { limit: 100 });
74
+ const attachments = [];
75
+ for (const row of rows) {
76
+ const detail = (await this.request({ method: "GET", url: `/wiki/api/v2/attachments/${row.id}` })).data;
77
+ attachments.push({ id: String(row.id), title: detail.title || row.title, fileId: detail.fileId || row.fileId, mediaType: detail.mediaType || row.mediaType, fileSize: detail.fileSize || row.fileSize, version: detail.version || row.version, downloadLink: detail.downloadLink || detail._links?.download });
78
+ }
79
+ return attachments;
80
+ }
81
+ async downloadAttachment(pageId, attachment) {
82
+ const endpoint = `/wiki/rest/api/content/${pageId}/child/attachment/${attachment.id}/download`;
83
+ const redirect = await this.request({ method: "GET", url: endpoint, responseType: "arraybuffer", headers: { Accept: "*/*" }, maxRedirects: 0, validateStatus: status => status === 302 || (status >= 200 && status < 300), delay: "attachment" });
84
+ if (redirect.status !== 302)
85
+ return Buffer.from(redirect.data);
86
+ const location = redirect.headers.location;
87
+ if (!location)
88
+ throw new Error(`Attachment ${attachment.id} returned a redirect without a Location header`);
89
+ return Buffer.from((await axios_1.default.get(new URL(location, this.config.baseUrl).href, { responseType: "arraybuffer", timeout: 60000 })).data);
90
+ }
91
+ async createPage(spaceId, title, parentId, storage) {
92
+ return (await this.request({ method: "POST", url: "/wiki/api/v2/pages", data: { spaceId, status: "current", title, parentId, body: { representation: "storage", value: storage } } })).data;
93
+ }
94
+ async updatePage(id, title, version, storage) {
95
+ return (await this.request({ method: "PUT", url: `/wiki/api/v2/pages/${id}`, data: { id, status: "current", title, body: { representation: "storage", value: storage }, version: { number: version + 1, message: "Synchronized from ConFluenceDocumentationSync" } } })).data;
96
+ }
97
+ async uploadAttachment(pageId, file, existingId) {
98
+ const form = new form_data_1.default();
99
+ form.append("file", (0, fs_1.createReadStream)(file));
100
+ const url = existingId ? `/wiki/rest/api/content/${pageId}/child/attachment/${existingId}/data` : `/wiki/rest/api/content/${pageId}/child/attachment`;
101
+ await this.request({ method: "POST", url, data: form, headers: { ...form.getHeaders(), "X-Atlassian-Token": "no-check" }, delay: "attachment", maxBodyLength: Infinity });
102
+ }
103
+ async paginate(url, params) {
104
+ const results = [];
105
+ let next = url;
106
+ let first = true;
107
+ while (next) {
108
+ const response = await this.request({ method: "GET", url: next, params: first ? params : undefined });
109
+ results.push(...response.data.results);
110
+ next = response.data._links?.next;
111
+ first = false;
112
+ }
113
+ return results;
114
+ }
115
+ async request(request) {
116
+ let lastError;
117
+ for (let attempt = 0; attempt < 4; attempt++) {
118
+ if (attempt || request.delay)
119
+ await this.pause(request.delay === "attachment");
120
+ try {
121
+ return await this.http.request(request);
122
+ }
123
+ catch (error) {
124
+ lastError = error;
125
+ const status = (0, axios_1.isAxiosError)(error) ? error.response?.status : undefined;
126
+ if (status && status < 500 && status !== 429)
127
+ throw this.friendlyError(error);
128
+ if (attempt < 3)
129
+ await new Promise(resolve => setTimeout(resolve, Math.min(1000 * 2 ** attempt, 10000)));
130
+ }
131
+ }
132
+ throw this.friendlyError(lastError);
133
+ }
134
+ async pause(attachment) {
135
+ const min = attachment ? this.config.attachmentMinDelayMs : this.config.minDelayMs;
136
+ const max = attachment ? this.config.attachmentMaxDelayMs : this.config.maxDelayMs;
137
+ await new Promise(resolve => setTimeout(resolve, min + Math.floor(Math.random() * (max - min + 1))));
138
+ }
139
+ friendlyError(error) {
140
+ if (!(0, axios_1.isAxiosError)(error))
141
+ return error instanceof Error ? error : new Error(String(error));
142
+ const detail = typeof error.response?.data === "object" ? JSON.stringify(error.response.data) : String(error.response?.data || error.message);
143
+ return new Error(`Confluence API ${error.response?.status || "network error"}: ${detail}`);
144
+ }
145
+ }
146
+ exports.ConfluenceClient = ConfluenceClient;
147
+ //# sourceMappingURL=confluenceClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confluenceClient.js","sourceRoot":"","sources":["../src/confluenceClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import type { Manifest, ManifestItem, PullOptions } from "./types";
2
+ export type ContentType = "page" | "folder" | "whiteboard" | "database" | "embed";
3
+ export type OperationPhase = "discovery" | "processing" | "applying" | "completed" | "cancelled" | "failed";
4
+ export type ProgressKind = "indeterminate" | "determinate";
5
+ export interface SyncProgress {
6
+ operation: "pull" | "status" | "push";
7
+ phase: OperationPhase;
8
+ kind: ProgressKind;
9
+ currentItem?: {
10
+ id?: string;
11
+ title: string;
12
+ type: ContentType;
13
+ };
14
+ currentFile?: {
15
+ name: string;
16
+ bytesLoaded?: number;
17
+ bytesTotal?: number;
18
+ };
19
+ totalItems?: number;
20
+ processed: number;
21
+ succeeded: number;
22
+ synced: number;
23
+ skipped: number;
24
+ conflicts: number;
25
+ failed: number;
26
+ attachments: {
27
+ total: number;
28
+ processed: number;
29
+ bytesTotal?: number;
30
+ bytesLoaded?: number;
31
+ };
32
+ percentage: number;
33
+ message?: string;
34
+ }
35
+ export interface OperationSummary {
36
+ operation: "pull" | "status" | "push";
37
+ elapsedMs: number;
38
+ discovered: number;
39
+ processed: number;
40
+ synced: number;
41
+ unchanged: number;
42
+ skipped: number;
43
+ conflicts: number;
44
+ failed: number;
45
+ attachments: {
46
+ processed: number;
47
+ bytes?: number;
48
+ };
49
+ dryRun: boolean;
50
+ }
51
+ export interface ProjectRef {
52
+ id: string;
53
+ displayName: string;
54
+ rootPath: string;
55
+ contentDir: string;
56
+ }
57
+ export interface SyncProjectConfig {
58
+ displayName?: string;
59
+ baseUrl: string;
60
+ spaceKey: string;
61
+ rootPageId: string;
62
+ contentDir?: string;
63
+ minDelayMs?: number;
64
+ maxDelayMs?: number;
65
+ attachmentMinDelayMs?: number;
66
+ attachmentMaxDelayMs?: number;
67
+ concurrency?: number;
68
+ }
69
+ export interface Credentials {
70
+ email: string;
71
+ token: string;
72
+ }
73
+ export type SyncErrorCode = "AUTH_MISSING" | "CONFIG_INVALID" | "PROJECT_AMBIGUOUS" | "NETWORK_ERROR" | "API_ERROR" | "CONFLICT" | "PUSH_BLOCKED" | "CANCELLED" | "INTERNAL";
74
+ export declare class SyncError extends Error {
75
+ readonly code: SyncErrorCode;
76
+ readonly cause?: unknown | undefined;
77
+ constructor(code: SyncErrorCode, message: string, cause?: unknown | undefined);
78
+ }
79
+ export interface OperationContext {
80
+ onProgress?: (progress: SyncProgress) => void | Promise<void>;
81
+ onDiagnostic?: (level: "info" | "warn" | "error", message: string) => void | Promise<void>;
82
+ isCancelled?: () => boolean;
83
+ }
84
+ export interface PullPlan {
85
+ create: ManifestItem[];
86
+ update: ManifestItem[];
87
+ unchanged: ManifestItem[];
88
+ conflicts: ManifestItem[];
89
+ deleteCandidates: ManifestItem[];
90
+ warnings: string[];
91
+ }
92
+ export interface PullResult {
93
+ manifest: Manifest;
94
+ summary: OperationSummary;
95
+ warnings: string[];
96
+ }
97
+ export interface StatusResult {
98
+ changes: Change[];
99
+ summary: OperationSummary;
100
+ }
101
+ export interface PushResult {
102
+ summary: OperationSummary;
103
+ }
104
+ export interface Change {
105
+ item: ManifestItem;
106
+ kind: ChangeKind;
107
+ detail: string;
108
+ remoteVersion?: number;
109
+ }
110
+ export type ChangeKind = "unchanged" | "local" | "remote" | "new-local" | "conflict" | "format-conflict";
111
+ export type { PullOptions };
112
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SyncError = void 0;
4
+ class SyncError extends Error {
5
+ code;
6
+ cause;
7
+ constructor(code, message, cause) {
8
+ super(message);
9
+ this.code = code;
10
+ this.cause = cause;
11
+ this.name = "SyncError";
12
+ }
13
+ }
14
+ exports.SyncError = SyncError;
15
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";;;AAkFA,MAAa,SAAU,SAAQ,KAAK;IAEhB;IAEA;IAHlB,YACkB,IAAmB,EACnC,OAAe,EACC,KAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAe;QAEnB,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AATD,8BASC"}
package/dist/diff.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { ManifestItem } from "./types";
2
+ export interface DiffContent {
3
+ item: ManifestItem;
4
+ localStorage?: string;
5
+ localMarkdown?: string;
6
+ remoteStorage?: string;
7
+ baselineStorage?: string;
8
+ }
9
+ export declare function buildLocalDiff(contentDir: string, item: ManifestItem): DiffContent;
10
+ export declare function buildRemoteDiff(remoteStorage: string, item: ManifestItem): DiffContent;
11
+ export declare function previewStorageFromMarkdown(item: ManifestItem, contentDir: string): string | undefined;
12
+ export declare function previewMarkdownFromStorage(item: ManifestItem, contentDir: string): string | undefined;
13
+ export declare function hasLossyConstructs(storage: string): boolean;
14
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,WAAW,CAKlF;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,WAAW,CAEtF;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIrG;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIrG;AAMD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D"}
package/dist/diff.js ADDED
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildLocalDiff = buildLocalDiff;
37
+ exports.buildRemoteDiff = buildRemoteDiff;
38
+ exports.previewStorageFromMarkdown = previewStorageFromMarkdown;
39
+ exports.previewMarkdownFromStorage = previewMarkdownFromStorage;
40
+ exports.hasLossyConstructs = hasLossyConstructs;
41
+ const path = __importStar(require("path"));
42
+ const fs_1 = require("fs");
43
+ const format_1 = require("./format");
44
+ function buildLocalDiff(contentDir, item) {
45
+ const dir = path.join(contentDir, item.relativeDir);
46
+ const localStorage = readOptional(path.join(dir, "page.storage.xhtml"));
47
+ const localMarkdown = readOptional(path.join(dir, "page.md"));
48
+ return { item, localStorage, localMarkdown };
49
+ }
50
+ function buildRemoteDiff(remoteStorage, item) {
51
+ return { item, remoteStorage };
52
+ }
53
+ function previewStorageFromMarkdown(item, contentDir) {
54
+ const dir = path.join(contentDir, item.relativeDir);
55
+ const md = readOptional(path.join(dir, "page.md"));
56
+ return md ? (0, format_1.markdownToStorage)(md) : undefined;
57
+ }
58
+ function previewMarkdownFromStorage(item, contentDir) {
59
+ const dir = path.join(contentDir, item.relativeDir);
60
+ const storage = readOptional(path.join(dir, "page.storage.xhtml"));
61
+ return storage ? (0, format_1.storageToMarkdown)(storage) : undefined;
62
+ }
63
+ function readOptional(file) {
64
+ try {
65
+ return (0, fs_1.readFileSync)(file, "utf8");
66
+ }
67
+ catch {
68
+ return undefined;
69
+ }
70
+ }
71
+ function hasLossyConstructs(storage) {
72
+ return /<(ac:|ri:|atlassian|macro|structured-macro|layout)/i.test(storage);
73
+ }
74
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,wCAKC;AAED,0CAEC;AAED,gEAIC;AAED,gEAIC;AAMD,gDAEC;AA1CD,2CAA6B;AAC7B,2BAAkC;AAClC,qCAAgE;AAWhE,SAAgB,cAAc,CAAC,UAAkB,EAAE,IAAkB;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IAC9D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAC/C,CAAC;AAED,SAAgB,eAAe,CAAC,aAAqB,EAAE,IAAkB;IACvE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AACjC,CAAC;AAED,SAAgB,0BAA0B,CAAC,IAAkB,EAAE,UAAkB;IAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,CAAC,CAAC,CAAC,IAAA,0BAAiB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,SAAgB,0BAA0B,CAAC,IAAkB,EAAE,UAAkB;IAC/E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACnE,OAAO,OAAO,CAAC,CAAC,CAAC,IAAA,0BAAiB,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QAAC,OAAO,IAAA,iBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;AACxE,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAAe;IAChD,OAAO,qDAAqD,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function storageToMarkdown(storage: string): string;
2
+ export declare function markdownToStorage(markdown: string): string;
3
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAkBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuH1D"}