From 5c42d7787cf4c53098759ac221a81369e033df3d Mon Sep 17 00:00:00 2001 From: Andrew McClenaghan Date: Tue, 18 Apr 2023 17:14:40 +1000 Subject: [PATCH] feat: Update a page when you are the last modifier Check the accountId who did the last version. If it isn't your accountId then don't update the page. --- packages/lib/src/Publisher.ts | 25 +++++++++++++++++++++++-- packages/lib/src/TreeConfluence.ts | 9 ++++++++- packages/lib/src/adaptors/index.ts | 3 +++ packages/obsidian/src/MyBaseClient.ts | 1 + 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/lib/src/Publisher.ts b/packages/lib/src/Publisher.ts index 9e96a4fe..0d5b35c1 100644 --- a/packages/lib/src/Publisher.ts +++ b/packages/lib/src/Publisher.ts @@ -69,12 +69,14 @@ export interface ConfluenceAdfFile { export interface ConfluenceNode { file: ConfluenceAdfFile; version: number; + lastUpdatedBy: string, existingAdf: string; parentPageId: string; } export interface ConfluenceTreeNode { file: ConfluenceAdfFile; version: number; + lastUpdatedBy: string, existingAdf: string; children: ConfluenceTreeNode[]; } @@ -91,6 +93,7 @@ export class Publisher { adaptor: LoaderAdaptor; settings: ConfluenceSettings; mermaidRenderer: MermaidRenderer; + myAccountId: string | undefined; constructor( adaptor: LoaderAdaptor, @@ -106,6 +109,11 @@ export class Publisher { } async publish(publishFilter?: string) { + if(!this.myAccountId) { + const currentUser = await this.confluenceClient.users.getCurrentUser(); + this.myAccountId = currentUser.accountId; + } + const parentPage = await this.confluenceClient.content.getContentById({ id: this.settings.confluenceParentId, expand: ["body.atlas_doc_format", "space"], @@ -177,7 +185,8 @@ export class Publisher { node.parentPageId, node.version, node.existingAdf, - node.file + node.file, + node.lastUpdatedBy, ); return { @@ -185,6 +194,13 @@ export class Publisher { successfulUploadResult, }; } catch (e: unknown) { + if (e instanceof Error) { + return { + node, + reason: e.message, + }; + } + return { node, reason: JSON.stringify(e), // TODO: Understand why this doesn't show error message properly @@ -196,8 +212,13 @@ export class Publisher { parentPageId: string, pageVersionNumber: number, currentContents: string, - adfFile: ConfluenceAdfFile + adfFile: ConfluenceAdfFile, + lastUpdatedBy: string, ): Promise { + if (lastUpdatedBy !== this.myAccountId) { + throw new Error(`Page last updated by another user. Won't publish over their changes. MyAccountId: ${this.myAccountId}, Last Updated By: ${lastUpdatedBy}`); + } + const result: UploadAdfFileResult = { adfFile, contentResult: "same", diff --git a/packages/lib/src/TreeConfluence.ts b/packages/lib/src/TreeConfluence.ts index 164c71cb..106020c3 100644 --- a/packages/lib/src/TreeConfluence.ts +++ b/packages/lib/src/TreeConfluence.ts @@ -15,12 +15,13 @@ function flattenTree( parentPageId?: string ): ConfluenceNode[] { const nodes: ConfluenceNode[] = []; - const { file, version, existingAdf, children } = node; + const { file, version, lastUpdatedBy, existingAdf, children } = node; if (parentPageId) { nodes.push({ file, version, + lastUpdatedBy, existingAdf, parentPageId: parentPageId, }); @@ -73,6 +74,7 @@ async function createFileStructureInConfluence( let version: number; let existingAdf: string | undefined; + let lastUpdatedBy: string | undefined; const file: ConfluenceAdfFile = { ...node.file, pageId: parentPageId, @@ -92,6 +94,7 @@ async function createFileStructureInConfluence( file.spaceKey = pageDetails.spaceKey; version = pageDetails.version; existingAdf = pageDetails.existingAdf; + lastUpdatedBy = pageDetails.lastUpdatedBy; } else { version = 0; existingAdf = ""; @@ -114,6 +117,7 @@ async function createFileStructureInConfluence( return { file: file, version, + lastUpdatedBy: lastUpdatedBy ?? "", existingAdf: existingAdf ?? "", children: childDetails, }; @@ -141,6 +145,7 @@ async function ensurePageExists( id: contentById.id, title: file.pageTitle, version: contentById?.version?.number ?? 1, + lastUpdatedBy: contentById?.version?.by?.accountId ?? "NO ACCOUNT ID", existingAdf: contentById?.body?.atlas_doc_format?.value, spaceKey: contentById.space.key, }; @@ -175,6 +180,7 @@ async function ensurePageExists( id: currentPage.id, title: file.pageTitle, version: currentPage?.version?.number ?? 1, + lastUpdatedBy: currentPage?.version?.by?.accountId ?? "NO ACCOUNT ID", existingAdf: currentPage?.body?.atlas_doc_format?.value, spaceKey, }; @@ -204,6 +210,7 @@ async function ensurePageExists( id: pageDetails.id, title: file.pageTitle, version: pageDetails?.version?.number ?? 1, + lastUpdatedBy: pageDetails?.version?.by?.accountId ?? "NO ACCOUNT ID", existingAdf: pageDetails?.body?.atlas_doc_format?.value, spaceKey, }; diff --git a/packages/lib/src/adaptors/index.ts b/packages/lib/src/adaptors/index.ts index 1f0cc6cb..e8072590 100644 --- a/packages/lib/src/adaptors/index.ts +++ b/packages/lib/src/adaptors/index.ts @@ -34,4 +34,7 @@ export interface CustomConfluenceClient { space: Api.Space; contentAttachments: Api.ContentAttachments; contentLabels: Api.ContentLabels; + users: Api.Users; } + + diff --git a/packages/obsidian/src/MyBaseClient.ts b/packages/obsidian/src/MyBaseClient.ts index 1276a0b1..c06cec72 100644 --- a/packages/obsidian/src/MyBaseClient.ts +++ b/packages/obsidian/src/MyBaseClient.ts @@ -197,4 +197,5 @@ export class CustomConfluenceClient extends MyBaseClient { space = new Api.Space(this); contentAttachments = new Api.ContentAttachments(this); contentLabels = new Api.ContentLabels(this); + users = new Api.Users(this); }