@repo-toolkit/confluence 0.14.0 → 0.14.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 (3) hide show
  1. package/cli.js +18 -7
  2. package/index.js +18 -7
  3. package/package.json +2 -2
package/cli.js CHANGED
@@ -51,7 +51,8 @@ var STATUS_CODES = {
51
51
  };
52
52
  var ConfluenceApiError = class extends Error {
53
53
  constructor(message, status, endpoint, responseBody) {
54
- super(`${message} (status=${status}, endpoint=${endpoint})`);
54
+ const responseBodySuffix = responseBody === "" ? "" : `, responseBody=${responseBody}`;
55
+ super(`${message} (status=${status}, endpoint=${endpoint}${responseBodySuffix})`);
55
56
  this.name = "ConfluenceApiError";
56
57
  this.status = status;
57
58
  this.endpoint = endpoint;
@@ -93,8 +94,7 @@ var ConfluenceClient = class {
93
94
  const visited = /* @__PURE__ */ new Set();
94
95
  let pageCount = 0;
95
96
  const startUrl = this.v2Url(
96
- `/pages?${new URLSearchParams({
97
- "space-id": spaceId,
97
+ `/spaces/${encodeURIComponent(spaceId)}/pages?${new URLSearchParams({
98
98
  title,
99
99
  limit: String(MAX_LIMIT),
100
100
  "body-format": "storage"
@@ -282,23 +282,24 @@ Content-Type: application/octet-stream\r
282
282
  if (response.status >= 300 && response.status < 400) {
283
283
  throw new ConfluenceApiError("Redirect responses are not allowed", response.status, endpoint, "");
284
284
  }
285
- const text = await readBodyBounded(response, MAX_ERROR_BODY_LENGTH);
286
285
  if (!response.ok) {
286
+ const text2 = await readBodyBounded(response, MAX_ERROR_BODY_LENGTH);
287
287
  if (isSafe && shouldRetryStatus(response.status) && attempt < maxRetries) {
288
288
  attempt += 1;
289
- lastError = new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text);
289
+ lastError = new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text2);
290
290
  await sleepBackoff(response, endpoint);
291
291
  continue;
292
292
  }
293
- throw new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text);
293
+ throw new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text2);
294
294
  }
295
+ const text = await response.text();
295
296
  if (text.length === 0) {
296
297
  return {};
297
298
  }
298
299
  try {
299
300
  return JSON.parse(text);
300
301
  } catch {
301
- throw new ConfluenceApiError("Response was not valid JSON", response.status, endpoint, text);
302
+ throw new ConfluenceApiError("Response was not valid JSON", response.status, endpoint, truncateText(text));
302
303
  }
303
304
  } catch (cause) {
304
305
  if (cause instanceof ConfluenceApiError || cause instanceof ConfluenceUploadError) {
@@ -437,6 +438,16 @@ function sanitizeFilename(name) {
437
438
  }
438
439
  return cleaned;
439
440
  }
441
+ function truncateText(text, maxBytes = MAX_ERROR_BODY_LENGTH) {
442
+ if (Buffer.byteLength(text, "utf8") <= maxBytes) {
443
+ return text;
444
+ }
445
+ let end = text.length;
446
+ while (end > 0 && Buffer.byteLength(text.slice(0, end), "utf8") > maxBytes) {
447
+ end -= 1;
448
+ }
449
+ return text.slice(0, end) + "...";
450
+ }
440
451
  function multipartField(boundary, name, filename, value) {
441
452
  const headerLines = [`--${boundary}\r
442
453
  `];
package/index.js CHANGED
@@ -37,7 +37,8 @@ var STATUS_CODES = {
37
37
  };
38
38
  var ConfluenceApiError = class extends Error {
39
39
  constructor(message, status, endpoint, responseBody) {
40
- super(`${message} (status=${status}, endpoint=${endpoint})`);
40
+ const responseBodySuffix = responseBody === "" ? "" : `, responseBody=${responseBody}`;
41
+ super(`${message} (status=${status}, endpoint=${endpoint}${responseBodySuffix})`);
41
42
  this.name = "ConfluenceApiError";
42
43
  this.status = status;
43
44
  this.endpoint = endpoint;
@@ -79,8 +80,7 @@ var ConfluenceClient = class {
79
80
  const visited = /* @__PURE__ */ new Set();
80
81
  let pageCount = 0;
81
82
  const startUrl = this.v2Url(
82
- `/pages?${new URLSearchParams({
83
- "space-id": spaceId,
83
+ `/spaces/${encodeURIComponent(spaceId)}/pages?${new URLSearchParams({
84
84
  title,
85
85
  limit: String(MAX_LIMIT),
86
86
  "body-format": "storage"
@@ -268,23 +268,24 @@ Content-Type: application/octet-stream\r
268
268
  if (response.status >= 300 && response.status < 400) {
269
269
  throw new ConfluenceApiError("Redirect responses are not allowed", response.status, endpoint, "");
270
270
  }
271
- const text = await readBodyBounded(response, MAX_ERROR_BODY_LENGTH);
272
271
  if (!response.ok) {
272
+ const text2 = await readBodyBounded(response, MAX_ERROR_BODY_LENGTH);
273
273
  if (isSafe && shouldRetryStatus(response.status) && attempt < maxRetries) {
274
274
  attempt += 1;
275
- lastError = new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text);
275
+ lastError = new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text2);
276
276
  await sleepBackoff(response, endpoint);
277
277
  continue;
278
278
  }
279
- throw new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text);
279
+ throw new ConfluenceApiError(describeStatus(response.status), response.status, endpoint, text2);
280
280
  }
281
+ const text = await response.text();
281
282
  if (text.length === 0) {
282
283
  return {};
283
284
  }
284
285
  try {
285
286
  return JSON.parse(text);
286
287
  } catch {
287
- throw new ConfluenceApiError("Response was not valid JSON", response.status, endpoint, text);
288
+ throw new ConfluenceApiError("Response was not valid JSON", response.status, endpoint, truncateText(text));
288
289
  }
289
290
  } catch (cause) {
290
291
  if (cause instanceof ConfluenceApiError || cause instanceof ConfluenceUploadError) {
@@ -423,6 +424,16 @@ function sanitizeFilename(name) {
423
424
  }
424
425
  return cleaned;
425
426
  }
427
+ function truncateText(text, maxBytes = MAX_ERROR_BODY_LENGTH) {
428
+ if (Buffer.byteLength(text, "utf8") <= maxBytes) {
429
+ return text;
430
+ }
431
+ let end = text.length;
432
+ while (end > 0 && Buffer.byteLength(text.slice(0, end), "utf8") > maxBytes) {
433
+ end -= 1;
434
+ }
435
+ return text.slice(0, end) + "...";
436
+ }
426
437
  function multipartField(boundary, name, filename, value) {
427
438
  const headerLines = [`--${boundary}\r
428
439
  `];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@repo-toolkit/confluence",
3
3
  "description": "Sync a folder of markdown docs to Confluence pages and attachments (GitHub Action compatible)",
4
- "version": "0.14.0",
4
+ "version": "0.14.2",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "keywords": [
@@ -27,7 +27,7 @@
27
27
  "node": ">=20"
28
28
  },
29
29
  "dependencies": {
30
- "@repo-toolkit/publish-package": "0.14.0"
30
+ "@repo-toolkit/publish-package": "0.14.2"
31
31
  },
32
32
  "files": [
33
33
  "**/*",