@adobe/spacecat-shared-content-client 1.3.40 → 1.4.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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/clients/content-client.js +49 -21
- package/src/clients/index.d.ts +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-content-client-v1.4.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-content-client-v1.3.40...@adobe/spacecat-shared-content-client-v1.4.0) (2025-03-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Broken internal links autofix ([40764fb](https://github.com/adobe/spacecat-shared/commit/40764fbb88da9760ecfbb008fc4ea27cfe27e823))
|
|
7
|
+
|
|
1
8
|
# [@adobe/spacecat-shared-content-client-v1.3.40](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-content-client-v1.3.39...@adobe/spacecat-shared-content-client-v1.3.40) (2025-03-03)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
12
|
import { createFrom as createContentSDKClient } from '@adobe/spacecat-helix-content-sdk';
|
|
14
13
|
import {
|
|
15
14
|
composeBaseURL, hasText, isObject, tracingFetch,
|
|
@@ -100,39 +99,45 @@ const validateMetadata = (metadata) => {
|
|
|
100
99
|
}
|
|
101
100
|
};
|
|
102
101
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
102
|
+
const validateLinks = (links, type) => {
|
|
103
|
+
let pathRegex;
|
|
104
|
+
if (type === 'URL') {
|
|
105
|
+
pathRegex = /^(http:\/\/|https:\/\/)[a-zA-Z0-9\-._~%!$&'()*+,;=:@/]*$/;
|
|
106
|
+
} else if (type === 'Redirect') {
|
|
107
|
+
pathRegex = /^\/[a-zA-Z0-9\-._~%!$&'()*+,;=:@/]*$/;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!Array.isArray(links)) {
|
|
111
|
+
throw new Error(`${type}s must be an array`);
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
if (!
|
|
110
|
-
throw new Error(
|
|
114
|
+
if (!links.length) {
|
|
115
|
+
throw new Error(`${type}s must not be empty`);
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
for (const
|
|
114
|
-
if (!isObject(
|
|
115
|
-
throw new Error(
|
|
118
|
+
for (const link of links) {
|
|
119
|
+
if (!isObject(link)) {
|
|
120
|
+
throw new Error(`${type} must be an object`);
|
|
116
121
|
}
|
|
117
122
|
|
|
118
|
-
if (!hasText(
|
|
119
|
-
throw new Error(
|
|
123
|
+
if (!hasText(link.from)) {
|
|
124
|
+
throw new Error(`${type} must have a valid from path`);
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
if (!hasText(
|
|
123
|
-
throw new Error(
|
|
127
|
+
if (!hasText(link.to)) {
|
|
128
|
+
throw new Error(`${type} must have a valid to path`);
|
|
124
129
|
}
|
|
125
130
|
|
|
126
|
-
if (!pathRegex.test(
|
|
127
|
-
throw new Error(`Invalid
|
|
131
|
+
if (!pathRegex.test(link.from)) {
|
|
132
|
+
throw new Error(`Invalid ${type} from path: ${link.from}`);
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
if (!pathRegex.test(
|
|
131
|
-
throw new Error(`Invalid
|
|
135
|
+
if (!pathRegex.test(link.to)) {
|
|
136
|
+
throw new Error(`Invalid ${type} to path: ${link.to}`);
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
if (
|
|
135
|
-
throw new Error(
|
|
139
|
+
if (link.from === link.to) {
|
|
140
|
+
throw new Error(`${type} from and to paths must be different`);
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
};
|
|
@@ -322,7 +327,7 @@ export default class ContentClient {
|
|
|
322
327
|
async updateRedirects(redirects) {
|
|
323
328
|
const startTime = process.hrtime.bigint();
|
|
324
329
|
|
|
325
|
-
|
|
330
|
+
validateLinks(redirects, 'Redirect');
|
|
326
331
|
|
|
327
332
|
await this.#initClient();
|
|
328
333
|
|
|
@@ -349,4 +354,27 @@ export default class ContentClient {
|
|
|
349
354
|
|
|
350
355
|
this.#logDuration('updateRedirects', startTime);
|
|
351
356
|
}
|
|
357
|
+
|
|
358
|
+
async updateBrokenInternalLink(path, brokenLink) {
|
|
359
|
+
const startTime = process.hrtime.bigint();
|
|
360
|
+
|
|
361
|
+
validateLinks([brokenLink], 'URL');
|
|
362
|
+
validatePath(path);
|
|
363
|
+
|
|
364
|
+
await this.#initClient();
|
|
365
|
+
|
|
366
|
+
this.log.info(`Updating page link for ${this.site.getId()} and path ${path}`);
|
|
367
|
+
|
|
368
|
+
const docPath = this.#resolveDocPath(path);
|
|
369
|
+
const document = await this.rawClient.getDocument(docPath);
|
|
370
|
+
|
|
371
|
+
this.log.info('Updating link from', brokenLink.from, 'to', brokenLink.to);
|
|
372
|
+
const response = await document.updateLink(brokenLink.from, brokenLink.to);
|
|
373
|
+
|
|
374
|
+
if (response.status !== 200) {
|
|
375
|
+
throw new Error(`Failed to update link from ${brokenLink.from} to ${brokenLink.to} // ${brokenLink}`);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
this.#logDuration('updateBrokenInternalLink', startTime);
|
|
379
|
+
}
|
|
352
380
|
}
|
package/src/clients/index.d.ts
CHANGED
|
@@ -103,4 +103,18 @@ export class ContentClient {
|
|
|
103
103
|
* is an issue updating the redirects.
|
|
104
104
|
*/
|
|
105
105
|
updateRedirects(redirects: Array<{ from: string, to: string }>): Promise<void>
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Updates the broken internal links for the given page path.
|
|
109
|
+
*
|
|
110
|
+
* @param {string} path The path to the page.
|
|
111
|
+
* @param {Array<{ from: string, to: string }>} brokenLinks The array of broken link objects to
|
|
112
|
+
* update.
|
|
113
|
+
* @returns {Promise<void>} A promise that resolves when the broken links have been updated.
|
|
114
|
+
* @throws {Error} If the path is not a string, empty or does not start with a "/"
|
|
115
|
+
* @throws {Error} If the brokenLinks array is not valid or if there is an issue updating the
|
|
116
|
+
* links.
|
|
117
|
+
*/
|
|
118
|
+
updateBrokenInternalLinks(path: string, brokenLinks: Array<{ from: string, to: string }>):
|
|
119
|
+
Promise<void>;
|
|
106
120
|
}
|