obsidian-confluence 5.6.12 → 5.6.14

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.
@@ -2,123 +2,123 @@ import { App, Setting, PluginSettingTab } from "obsidian";
2
2
  import ConfluencePlugin from "./main";
3
3
 
4
4
  export class ConfluenceSettingTab extends PluginSettingTab {
5
- plugin: ConfluencePlugin;
5
+ plugin: ConfluencePlugin;
6
6
 
7
- constructor(app: App, plugin: ConfluencePlugin) {
8
- super(app, plugin);
9
- this.plugin = plugin;
10
- }
7
+ constructor(app: App, plugin: ConfluencePlugin) {
8
+ super(app, plugin);
9
+ this.plugin = plugin;
10
+ }
11
11
 
12
- display(): void {
13
- const { containerEl } = this;
12
+ display(): void {
13
+ const { containerEl } = this;
14
14
 
15
- containerEl.empty();
15
+ containerEl.empty();
16
16
 
17
- containerEl.createEl("h2", {
18
- text: "Settings for connecting to Atlassian Confluence",
19
- });
17
+ containerEl.createEl("h2", {
18
+ text: "Settings for connecting to Atlassian Confluence",
19
+ });
20
20
 
21
- new Setting(containerEl)
22
- .setName("Confluence Domain")
23
- .setDesc('Confluence Domain eg "https://mysite.atlassian.net"')
24
- .addText((text) =>
25
- text
26
- .setPlaceholder("https://mysite.atlassian.net")
27
- .setValue(this.plugin.settings.confluenceBaseUrl)
28
- .onChange(async (value) => {
29
- this.plugin.settings.confluenceBaseUrl = value;
30
- await this.plugin.saveSettings();
31
- }),
32
- );
21
+ new Setting(containerEl)
22
+ .setName("Confluence Domain")
23
+ .setDesc('Confluence Domain eg "https://mysite.atlassian.net"')
24
+ .addText((text) =>
25
+ text
26
+ .setPlaceholder("https://mysite.atlassian.net")
27
+ .setValue(this.plugin.settings.confluenceBaseUrl)
28
+ .onChange(async (value) => {
29
+ this.plugin.settings.confluenceBaseUrl = value;
30
+ await this.plugin.saveSettings();
31
+ }),
32
+ );
33
33
 
34
- new Setting(containerEl)
35
- .setName("Atlassian Username")
36
- .setDesc('eg "username@domain.com"')
37
- .addText((text) =>
38
- text
39
- .setPlaceholder("username@domain.com")
40
- .setValue(this.plugin.settings.atlassianUserName)
41
- .onChange(async (value) => {
42
- this.plugin.settings.atlassianUserName = value;
43
- await this.plugin.saveSettings();
44
- }),
45
- );
34
+ new Setting(containerEl)
35
+ .setName("Atlassian Username")
36
+ .setDesc('eg "username@domain.com"')
37
+ .addText((text) =>
38
+ text
39
+ .setPlaceholder("username@domain.com")
40
+ .setValue(this.plugin.settings.atlassianUserName)
41
+ .onChange(async (value) => {
42
+ this.plugin.settings.atlassianUserName = value;
43
+ await this.plugin.saveSettings();
44
+ }),
45
+ );
46
46
 
47
- new Setting(containerEl)
48
- .setName("Atlassian API Token")
49
- .setDesc("")
50
- .addText((text) =>
51
- text
52
- .setPlaceholder("")
53
- .setValue(this.plugin.settings.atlassianApiToken)
54
- .onChange(async (value) => {
55
- this.plugin.settings.atlassianApiToken = value;
56
- await this.plugin.saveSettings();
57
- }),
58
- );
47
+ new Setting(containerEl)
48
+ .setName("Atlassian API Token")
49
+ .setDesc("")
50
+ .addText((text) =>
51
+ text
52
+ .setPlaceholder("")
53
+ .setValue(this.plugin.settings.atlassianApiToken)
54
+ .onChange(async (value) => {
55
+ this.plugin.settings.atlassianApiToken = value;
56
+ await this.plugin.saveSettings();
57
+ }),
58
+ );
59
59
 
60
- new Setting(containerEl)
61
- .setName("Confluence Parent Page ID")
62
- .setDesc("Page ID to publish files under")
63
- .addText((text) =>
64
- text
65
- .setPlaceholder("23232345645")
66
- .setValue(this.plugin.settings.confluenceParentId)
67
- .onChange(async (value) => {
68
- this.plugin.settings.confluenceParentId = value;
69
- await this.plugin.saveSettings();
70
- }),
71
- );
60
+ new Setting(containerEl)
61
+ .setName("Confluence Parent Page ID")
62
+ .setDesc("Page ID to publish files under")
63
+ .addText((text) =>
64
+ text
65
+ .setPlaceholder("23232345645")
66
+ .setValue(this.plugin.settings.confluenceParentId)
67
+ .onChange(async (value) => {
68
+ this.plugin.settings.confluenceParentId = value;
69
+ await this.plugin.saveSettings();
70
+ }),
71
+ );
72
72
 
73
- new Setting(containerEl)
74
- .setName("Folder to publish")
75
- .setDesc(
76
- "Publish all files except notes that are excluded using YAML Frontmatter",
77
- )
78
- .addText((text) =>
79
- text
80
- .setPlaceholder("")
81
- .setValue(this.plugin.settings.folderToPublish)
82
- .onChange(async (value) => {
83
- this.plugin.settings.folderToPublish = value;
84
- await this.plugin.saveSettings();
85
- }),
86
- );
73
+ new Setting(containerEl)
74
+ .setName("Folder to publish")
75
+ .setDesc(
76
+ "Publish all files except notes that are excluded using YAML Frontmatter",
77
+ )
78
+ .addText((text) =>
79
+ text
80
+ .setPlaceholder("")
81
+ .setValue(this.plugin.settings.folderToPublish)
82
+ .onChange(async (value) => {
83
+ this.plugin.settings.folderToPublish = value;
84
+ await this.plugin.saveSettings();
85
+ }),
86
+ );
87
87
 
88
- new Setting(containerEl)
89
- .setName("First Header Page Name")
90
- .setDesc("First header replaces file name as page title")
91
- .addToggle((toggle) =>
92
- toggle
93
- .setValue(this.plugin.settings.firstHeadingPageTitle)
94
- .onChange(async (value) => {
95
- this.plugin.settings.firstHeadingPageTitle = value;
96
- await this.plugin.saveSettings();
97
- }),
98
- );
88
+ new Setting(containerEl)
89
+ .setName("First Header Page Name")
90
+ .setDesc("First header replaces file name as page title")
91
+ .addToggle((toggle) =>
92
+ toggle
93
+ .setValue(this.plugin.settings.firstHeadingPageTitle)
94
+ .onChange(async (value) => {
95
+ this.plugin.settings.firstHeadingPageTitle = value;
96
+ await this.plugin.saveSettings();
97
+ }),
98
+ );
99
99
 
100
- new Setting(containerEl)
101
- .setName("Mermaid Diagram Theme")
102
- .setDesc("Pick the theme to apply to mermaid diagrams")
103
- .addDropdown((dropdown) => {
104
- /* eslint-disable @typescript-eslint/naming-convention */
105
- dropdown
106
- .addOptions({
107
- "match-obsidian": "Match Obsidian",
108
- "light-obsidian": "Obsidian Theme - Light",
109
- "dark-obsidian": "Obsidian Theme - Dark",
110
- default: "Mermaid - Default",
111
- neutral: "Mermaid - Neutral",
112
- dark: "Mermaid - Dark",
113
- forest: "Mermaid - Forest",
114
- })
115
- .setValue(this.plugin.settings.mermaidTheme)
116
- .onChange(async (value) => {
117
- // @ts-expect-error
118
- this.plugin.settings.mermaidTheme = value;
119
- await this.plugin.saveSettings();
120
- });
121
- /* eslint-enable @typescript-eslint/naming-convention */
122
- });
123
- }
100
+ new Setting(containerEl)
101
+ .setName("Mermaid Diagram Theme")
102
+ .setDesc("Pick the theme to apply to mermaid diagrams")
103
+ .addDropdown((dropdown) => {
104
+ /* eslint-disable @typescript-eslint/naming-convention */
105
+ dropdown
106
+ .addOptions({
107
+ "match-obsidian": "Match Obsidian",
108
+ "light-obsidian": "Obsidian Theme - Light",
109
+ "dark-obsidian": "Obsidian Theme - Dark",
110
+ default: "Mermaid - Default",
111
+ neutral: "Mermaid - Neutral",
112
+ dark: "Mermaid - Dark",
113
+ forest: "Mermaid - Forest",
114
+ })
115
+ .setValue(this.plugin.settings.mermaidTheme)
116
+ .onChange(async (value) => {
117
+ // @ts-expect-error
118
+ this.plugin.settings.mermaidTheme = value;
119
+ await this.plugin.saveSettings();
120
+ });
121
+ /* eslint-enable @typescript-eslint/naming-convention */
122
+ });
123
+ }
124
124
  }
@@ -1,10 +1,10 @@
1
1
  import {
2
- Api,
3
- Callback,
4
- Client,
5
- Config,
6
- RequestConfig,
7
- AuthenticationService,
2
+ Api,
3
+ Callback,
4
+ Client,
5
+ Config,
6
+ RequestConfig,
7
+ AuthenticationService,
8
8
  } from "confluence.js";
9
9
  import { requestUrl } from "obsidian";
10
10
  import { RequiredConfluenceClient } from "md-confluence-lib";
@@ -13,208 +13,201 @@ const ATLASSIAN_TOKEN_CHECK_FLAG = "X-Atlassian-Token";
13
13
  const ATLASSIAN_TOKEN_CHECK_NOCHECK_VALUE = "no-check";
14
14
 
15
15
  export class MyBaseClient implements Client {
16
- protected urlSuffix = "/wiki/rest";
17
-
18
- constructor(protected readonly config: Config) {}
19
-
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- protected paramSerializer(parameters: Record<string, any>): string {
22
- const parts: string[] = [];
23
-
24
- Object.entries(parameters).forEach(([key, value]) => {
25
- if (value === null || typeof value === "undefined") {
26
- return;
27
- }
28
-
29
- if (Array.isArray(value)) {
30
- // eslint-disable-next-line no-param-reassign
31
- value = value.join(",");
32
- }
33
-
34
- if (value instanceof Date) {
35
- // eslint-disable-next-line no-param-reassign
36
- value = value.toISOString();
37
- } else if (value !== null && typeof value === "object") {
38
- // eslint-disable-next-line no-param-reassign
39
- value = JSON.stringify(value);
40
- } else if (value instanceof Function) {
41
- const part = value();
42
-
43
- return part && parts.push(part);
44
- }
45
-
46
- parts.push(`${this.encode(key)}=${this.encode(value)}`);
47
-
48
- return;
49
- });
50
-
51
- return parts.join("&");
52
- }
53
-
54
- protected encode(value: string) {
55
- return encodeURIComponent(value)
56
- .replace(/%3A/gi, ":")
57
- .replace(/%24/g, "$")
58
- .replace(/%2C/gi, ",")
59
- .replace(/%20/g, "+")
60
- .replace(/%5B/gi, "[")
61
- .replace(/%5D/gi, "]");
62
- }
63
-
64
- protected removeUndefinedProperties(
65
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
- obj: Record<string, any>,
67
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
- ): Record<string, any> {
69
- return Object.entries(obj)
70
- .filter(([, value]) => typeof value !== "undefined")
71
- .reduce(
72
- (accumulator, [key, value]) => ({
73
- ...accumulator,
74
- [key]: value,
75
- }),
76
- {},
77
- );
78
- }
79
-
80
- async sendRequest<T>(
81
- requestConfig: RequestConfig,
82
- callback: never,
83
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- telemetryData?: any,
85
- ): Promise<T>;
86
- async sendRequest<T>(
87
- requestConfig: RequestConfig,
88
- callback: Callback<T>,
89
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
- telemetryData?: any,
91
- ): Promise<void>;
92
- async sendRequest<T>(
93
- requestConfig: RequestConfig,
94
- callback: Callback<T> | never,
95
- ): Promise<void | T> {
96
- try {
97
- const contentType = (requestConfig.headers ?? {})[
98
- "content-type"
99
- ]?.toString();
100
- if (requestConfig.headers && contentType) {
101
- requestConfig.headers["Content-Type"] = contentType;
102
- delete requestConfig?.headers["content-type"];
103
- }
104
-
105
- const params = this.paramSerializer(requestConfig.params);
106
-
107
- const requestContentType =
108
- (requestConfig.headers ?? {})["Content-Type"]?.toString() ??
109
- "application/json";
110
-
111
- const requestBody = requestContentType.startsWith(
112
- "multipart/form-data",
113
- )
114
- ? [
115
- requestConfig.data.getHeaders(),
116
- requestConfig.data.getBuffer().buffer,
117
- ]
118
- : [{}, JSON.stringify(requestConfig.data)];
119
-
120
- const modifiedRequestConfig = {
121
- ...requestConfig,
122
- headers: this.removeUndefinedProperties({
123
- "User-Agent": "Obsidian.md",
124
- Accept: "application/json",
125
- [ATLASSIAN_TOKEN_CHECK_FLAG]: this.config
126
- .noCheckAtlassianToken
127
- ? ATLASSIAN_TOKEN_CHECK_NOCHECK_VALUE
128
- : undefined,
129
- ...this.config.baseRequestConfig?.headers,
130
- Authorization:
131
- await AuthenticationService.getAuthenticationToken(
132
- this.config.authentication,
133
- {
134
- // eslint-disable-next-line @typescript-eslint/naming-convention
135
- baseURL: this.config.host,
136
- url: `${this.config.host}${this.urlSuffix}`,
137
- method: requestConfig.method ?? "GET",
138
- },
139
- ),
140
- ...requestConfig.headers,
141
- "Content-Type": requestContentType,
142
- ...requestBody[0],
143
- }),
144
- url: `${this.config.host}${this.urlSuffix}${requestConfig.url}?${params}`,
145
- body: requestBody[1],
146
- method: requestConfig.method?.toUpperCase() ?? "GET",
147
- contentType: requestContentType,
148
- throw: false,
149
- };
150
- delete modifiedRequestConfig.data;
151
-
152
- const response = await requestUrl(modifiedRequestConfig);
153
-
154
- if (response.status >= 400) {
155
- throw new HTTPError(`Received a ${response.status}`, {
156
- status: response.status,
157
- data: response.text,
158
- });
159
- }
160
-
161
- const callbackResponseHandler =
162
- callback && ((data: T): void => callback(null, data));
163
- const defaultResponseHandler = (data: T): T => data;
164
-
165
- const responseHandler =
166
- callbackResponseHandler ?? defaultResponseHandler;
167
-
168
- this.config.middlewares?.onResponse?.(response.json);
169
-
170
- return responseHandler(response.json);
171
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
- } catch (e: any) {
173
- console.warn({ httpError: e, requestConfig });
174
- const err =
175
- this.config.newErrorHandling && e.isAxiosError
176
- ? e.response.data
177
- : e;
178
-
179
- const callbackErrorHandler =
180
- callback && ((error: Config.Error) => callback(error));
181
- const defaultErrorHandler = (error: Error) => {
182
- throw error;
183
- };
184
-
185
- const errorHandler = callbackErrorHandler ?? defaultErrorHandler;
186
-
187
- this.config.middlewares?.onError?.(err);
188
-
189
- return errorHandler(err);
190
- }
191
- }
16
+ protected urlSuffix = "/wiki/rest";
17
+
18
+ constructor(protected readonly config: Config) {}
19
+
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ protected paramSerializer(parameters: Record<string, any>): string {
22
+ const parts: string[] = [];
23
+
24
+ Object.entries(parameters).forEach(([key, value]) => {
25
+ if (value === null || typeof value === "undefined") {
26
+ return;
27
+ }
28
+
29
+ if (Array.isArray(value)) {
30
+ // eslint-disable-next-line no-param-reassign
31
+ value = value.join(",");
32
+ }
33
+
34
+ if (value instanceof Date) {
35
+ // eslint-disable-next-line no-param-reassign
36
+ value = value.toISOString();
37
+ } else if (value !== null && typeof value === "object") {
38
+ // eslint-disable-next-line no-param-reassign
39
+ value = JSON.stringify(value);
40
+ } else if (value instanceof Function) {
41
+ const part = value();
42
+
43
+ return part && parts.push(part);
44
+ }
45
+
46
+ parts.push(`${this.encode(key)}=${this.encode(value)}`);
47
+
48
+ return;
49
+ });
50
+
51
+ return parts.join("&");
52
+ }
53
+
54
+ protected encode(value: string) {
55
+ return encodeURIComponent(value)
56
+ .replace(/%3A/gi, ":")
57
+ .replace(/%24/g, "$")
58
+ .replace(/%2C/gi, ",")
59
+ .replace(/%20/g, "+")
60
+ .replace(/%5B/gi, "[")
61
+ .replace(/%5D/gi, "]");
62
+ }
63
+
64
+ protected removeUndefinedProperties(
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ obj: Record<string, any>,
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ ): Record<string, any> {
69
+ return Object.entries(obj)
70
+ .filter(([, value]) => typeof value !== "undefined")
71
+ .reduce(
72
+ (accumulator, [key, value]) => ({
73
+ ...accumulator,
74
+ [key]: value,
75
+ }),
76
+ {},
77
+ );
78
+ }
79
+
80
+ async sendRequest<T>(
81
+ requestConfig: RequestConfig,
82
+ callback: never,
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ telemetryData?: any,
85
+ ): Promise<T>;
86
+ async sendRequest<T>(
87
+ requestConfig: RequestConfig,
88
+ callback: Callback<T>,
89
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
+ telemetryData?: any,
91
+ ): Promise<void>;
92
+ async sendRequest<T>(
93
+ requestConfig: RequestConfig,
94
+ callback: Callback<T> | never,
95
+ ): Promise<void | T> {
96
+ try {
97
+ const contentType = (requestConfig.headers ?? {})[
98
+ "content-type"
99
+ ]?.toString();
100
+ if (requestConfig.headers && contentType) {
101
+ requestConfig.headers["Content-Type"] = contentType;
102
+ delete requestConfig?.headers["content-type"];
103
+ }
104
+
105
+ const params = this.paramSerializer(requestConfig.params);
106
+
107
+ const requestContentType =
108
+ (requestConfig.headers ?? {})["Content-Type"]?.toString() ??
109
+ "application/json";
110
+
111
+ const requestBody = requestContentType.startsWith("multipart/form-data")
112
+ ? [
113
+ requestConfig.data.getHeaders(),
114
+ requestConfig.data.getBuffer().buffer,
115
+ ]
116
+ : [{}, JSON.stringify(requestConfig.data)];
117
+
118
+ const modifiedRequestConfig = {
119
+ ...requestConfig,
120
+ headers: this.removeUndefinedProperties({
121
+ "User-Agent": "Obsidian.md",
122
+ Accept: "application/json",
123
+ [ATLASSIAN_TOKEN_CHECK_FLAG]: this.config.noCheckAtlassianToken
124
+ ? ATLASSIAN_TOKEN_CHECK_NOCHECK_VALUE
125
+ : undefined,
126
+ ...this.config.baseRequestConfig?.headers,
127
+ Authorization: await AuthenticationService.getAuthenticationToken(
128
+ this.config.authentication,
129
+ {
130
+ // eslint-disable-next-line @typescript-eslint/naming-convention
131
+ baseURL: this.config.host,
132
+ url: `${this.config.host}${this.urlSuffix}`,
133
+ method: requestConfig.method ?? "GET",
134
+ },
135
+ ),
136
+ ...requestConfig.headers,
137
+ "Content-Type": requestContentType,
138
+ ...requestBody[0],
139
+ }),
140
+ url: `${this.config.host}${this.urlSuffix}${requestConfig.url}?${params}`,
141
+ body: requestBody[1],
142
+ method: requestConfig.method?.toUpperCase() ?? "GET",
143
+ contentType: requestContentType,
144
+ throw: false,
145
+ };
146
+ delete modifiedRequestConfig.data;
147
+
148
+ const response = await requestUrl(modifiedRequestConfig);
149
+
150
+ if (response.status >= 400) {
151
+ throw new HTTPError(`Received a ${response.status}`, {
152
+ status: response.status,
153
+ data: response.text,
154
+ });
155
+ }
156
+
157
+ const callbackResponseHandler =
158
+ callback && ((data: T): void => callback(null, data));
159
+ const defaultResponseHandler = (data: T): T => data;
160
+
161
+ const responseHandler = callbackResponseHandler ?? defaultResponseHandler;
162
+
163
+ this.config.middlewares?.onResponse?.(response.json);
164
+
165
+ return responseHandler(response.json);
166
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
+ } catch (e: any) {
168
+ console.warn({ httpError: e, requestConfig });
169
+ const err =
170
+ this.config.newErrorHandling && e.isAxiosError ? e.response.data : e;
171
+
172
+ const callbackErrorHandler =
173
+ callback && ((error: Config.Error) => callback(error));
174
+ const defaultErrorHandler = (error: Error) => {
175
+ throw error;
176
+ };
177
+
178
+ const errorHandler = callbackErrorHandler ?? defaultErrorHandler;
179
+
180
+ this.config.middlewares?.onError?.(err);
181
+
182
+ return errorHandler(err);
183
+ }
184
+ }
192
185
  }
193
186
 
194
187
  export interface ErrorData {
195
- data: unknown;
196
- status: number;
188
+ data: unknown;
189
+ status: number;
197
190
  }
198
191
 
199
192
  export class HTTPError extends Error {
200
- constructor(
201
- msg: string,
202
- public response: ErrorData,
203
- ) {
204
- super(msg);
205
-
206
- // Set the prototype explicitly.
207
- Object.setPrototypeOf(this, HTTPError.prototype);
208
- }
193
+ constructor(
194
+ msg: string,
195
+ public response: ErrorData,
196
+ ) {
197
+ super(msg);
198
+
199
+ // Set the prototype explicitly.
200
+ Object.setPrototypeOf(this, HTTPError.prototype);
201
+ }
209
202
  }
210
203
 
211
204
  export class ObsidianConfluenceClient
212
- extends MyBaseClient
213
- implements RequiredConfluenceClient
205
+ extends MyBaseClient
206
+ implements RequiredConfluenceClient
214
207
  {
215
- content = new Api.Content(this);
216
- space = new Api.Space(this);
217
- contentAttachments = new Api.ContentAttachments(this);
218
- contentLabels = new Api.ContentLabels(this);
219
- users = new Api.Users(this);
208
+ content = new Api.Content(this);
209
+ space = new Api.Space(this);
210
+ contentAttachments = new Api.ContentAttachments(this);
211
+ contentLabels = new Api.ContentLabels(this);
212
+ users = new Api.Users(this);
220
213
  }