@sitecore-content-sdk/core 0.1.0-beta.32 → 0.1.0-beta.33

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.
@@ -8,6 +8,7 @@ const utils_1 = require("../personalize/utils");
8
8
  const layout_personalizer_1 = require("../personalize/layout-personalizer");
9
9
  const site_1 = require("../site");
10
10
  const utils_2 = require("./utils");
11
+ const native_fetcher_1 = require("../native-fetcher");
11
12
  /**
12
13
  * This is a generic content client that can be used by any framework.
13
14
  * Use it to retrieve pages, preview data, dictionary and other data
@@ -21,6 +22,7 @@ class SitecoreClient {
21
22
  this.initOptions = initOptions;
22
23
  this.clientFactory = this.getClientFactory();
23
24
  this.siteResolver = this.getSiteResolver();
25
+ this.sitemapXmlService = this.getGraphqlSitemapXMLService();
24
26
  const baseServiceOptions = this.getBaseServiceOptions();
25
27
  this.layoutService = this.getLayoutService(baseServiceOptions);
26
28
  this.dictionaryService = this.getDictionaryService(baseServiceOptions);
@@ -209,10 +211,59 @@ class SitecoreClient {
209
211
  async getPagePaths(languages, fetchOptions) {
210
212
  return this.sitePathService.fetchSiteRoutes(languages || [], fetchOptions);
211
213
  }
214
+ /**
215
+ * Retrieves sitemap XML content - either a specific sitemap or the index of all sitemaps.
216
+ * @param {SitemapXmlOptions} reqOptions - Options for sitemap retrieval
217
+ * @param {FetchOptions} [fetchOptions] - Additional fetch options.
218
+ * @returns {Promise<string>} Promise resolving to the sitemap XML content as string
219
+ * @throws {Error} Throws 'REDIRECT_404' if requested sitemap is not found
220
+ */
221
+ async getSiteMap(reqOptions, fetchOptions) {
222
+ const ABSOLUTE_URL_REGEXP = '^(?:[a-z]+:)?//';
223
+ const { reqHost, reqProtocol, id } = reqOptions;
224
+ // Get specific sitemap
225
+ const sitemapPath = await this.sitemapXmlService.getSitemap(id);
226
+ if (sitemapPath) {
227
+ const isAbsoluteUrl = sitemapPath.match(ABSOLUTE_URL_REGEXP);
228
+ const sitemapUrl = isAbsoluteUrl
229
+ ? sitemapPath
230
+ : `${this.initOptions.api.local.apiHost}${sitemapPath}`;
231
+ try {
232
+ const fetcher = new native_fetcher_1.NativeDataFetcher();
233
+ const xmlResponse = await fetcher.fetch(sitemapUrl);
234
+ return xmlResponse.data;
235
+ }
236
+ catch (error) {
237
+ throw new Error('REDIRECT_404');
238
+ }
239
+ }
240
+ // Get sitemap index
241
+ const sitemaps = await this.sitemapXmlService.fetchSitemaps(fetchOptions);
242
+ if (!sitemaps.length) {
243
+ throw new Error('REDIRECT_404');
244
+ }
245
+ return `<?xml version="1.0" encoding="UTF-8"?>
246
+ <sitemapindex xmlns="http://sitemaps.org/schemas/sitemap/0.9">
247
+ ${sitemaps
248
+ .map((item) => {
249
+ const parseUrl = item.split('/');
250
+ const lastSegment = parseUrl[parseUrl.length - 1];
251
+ const escapedUrl = `${reqProtocol}://${reqHost}/${lastSegment}`.replace(/&/g, '&amp;');
252
+ return `<sitemap><loc>${escapedUrl}</loc></sitemap>`;
253
+ })
254
+ .join('')}
255
+ </sitemapindex>`;
256
+ }
212
257
  /**
213
258
  * Factory methods for creating dependencies
214
259
  * Subclasses can override these to provide custom implementations.
215
260
  */
261
+ getGraphqlSitemapXMLService() {
262
+ return new site_1.GraphQLSitemapXmlService({
263
+ clientFactory: this.clientFactory,
264
+ siteName: this.initOptions.defaultSite,
265
+ });
266
+ }
216
267
  getBaseServiceOptions() {
217
268
  return {
218
269
  defaultSite: this.initOptions.defaultSite,
@@ -3,8 +3,9 @@ import { GraphQLDictionaryService } from '../i18n';
3
3
  import { getDesignLibraryStylesheetLinks, getContentStylesheetLink, GraphQLLayoutService, } from '../layout';
4
4
  import { getGroomedVariantIds } from '../personalize/utils';
5
5
  import { personalizeLayout } from '../personalize/layout-personalizer';
6
- import { SiteResolver, GraphQLErrorPagesService, GraphQLSitePathService, } from '../site';
6
+ import { SiteResolver, GraphQLErrorPagesService, GraphQLSitePathService, GraphQLSitemapXmlService, } from '../site';
7
7
  import { createGraphQLClientFactory } from './utils';
8
+ import { NativeDataFetcher } from '../native-fetcher';
8
9
  /**
9
10
  * This is a generic content client that can be used by any framework.
10
11
  * Use it to retrieve pages, preview data, dictionary and other data
@@ -18,6 +19,7 @@ export class SitecoreClient {
18
19
  this.initOptions = initOptions;
19
20
  this.clientFactory = this.getClientFactory();
20
21
  this.siteResolver = this.getSiteResolver();
22
+ this.sitemapXmlService = this.getGraphqlSitemapXMLService();
21
23
  const baseServiceOptions = this.getBaseServiceOptions();
22
24
  this.layoutService = this.getLayoutService(baseServiceOptions);
23
25
  this.dictionaryService = this.getDictionaryService(baseServiceOptions);
@@ -206,10 +208,59 @@ export class SitecoreClient {
206
208
  async getPagePaths(languages, fetchOptions) {
207
209
  return this.sitePathService.fetchSiteRoutes(languages || [], fetchOptions);
208
210
  }
211
+ /**
212
+ * Retrieves sitemap XML content - either a specific sitemap or the index of all sitemaps.
213
+ * @param {SitemapXmlOptions} reqOptions - Options for sitemap retrieval
214
+ * @param {FetchOptions} [fetchOptions] - Additional fetch options.
215
+ * @returns {Promise<string>} Promise resolving to the sitemap XML content as string
216
+ * @throws {Error} Throws 'REDIRECT_404' if requested sitemap is not found
217
+ */
218
+ async getSiteMap(reqOptions, fetchOptions) {
219
+ const ABSOLUTE_URL_REGEXP = '^(?:[a-z]+:)?//';
220
+ const { reqHost, reqProtocol, id } = reqOptions;
221
+ // Get specific sitemap
222
+ const sitemapPath = await this.sitemapXmlService.getSitemap(id);
223
+ if (sitemapPath) {
224
+ const isAbsoluteUrl = sitemapPath.match(ABSOLUTE_URL_REGEXP);
225
+ const sitemapUrl = isAbsoluteUrl
226
+ ? sitemapPath
227
+ : `${this.initOptions.api.local.apiHost}${sitemapPath}`;
228
+ try {
229
+ const fetcher = new NativeDataFetcher();
230
+ const xmlResponse = await fetcher.fetch(sitemapUrl);
231
+ return xmlResponse.data;
232
+ }
233
+ catch (error) {
234
+ throw new Error('REDIRECT_404');
235
+ }
236
+ }
237
+ // Get sitemap index
238
+ const sitemaps = await this.sitemapXmlService.fetchSitemaps(fetchOptions);
239
+ if (!sitemaps.length) {
240
+ throw new Error('REDIRECT_404');
241
+ }
242
+ return `<?xml version="1.0" encoding="UTF-8"?>
243
+ <sitemapindex xmlns="http://sitemaps.org/schemas/sitemap/0.9">
244
+ ${sitemaps
245
+ .map((item) => {
246
+ const parseUrl = item.split('/');
247
+ const lastSegment = parseUrl[parseUrl.length - 1];
248
+ const escapedUrl = `${reqProtocol}://${reqHost}/${lastSegment}`.replace(/&/g, '&amp;');
249
+ return `<sitemap><loc>${escapedUrl}</loc></sitemap>`;
250
+ })
251
+ .join('')}
252
+ </sitemapindex>`;
253
+ }
209
254
  /**
210
255
  * Factory methods for creating dependencies
211
256
  * Subclasses can override these to provide custom implementations.
212
257
  */
258
+ getGraphqlSitemapXMLService() {
259
+ return new GraphQLSitemapXmlService({
260
+ clientFactory: this.clientFactory,
261
+ siteName: this.initOptions.defaultSite,
262
+ });
263
+ }
213
264
  getBaseServiceOptions() {
214
265
  return {
215
266
  defaultSite: this.initOptions.defaultSite,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/core",
3
- "version": "0.1.0-beta.32",
3
+ "version": "0.1.0-beta.33",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -45,6 +45,7 @@
45
45
  "@types/node": "^22.12.0",
46
46
  "@types/proxyquire": "^1.3.31",
47
47
  "@types/sinon": "^17.0.3",
48
+ "@types/sinon-chai": "^4.0.0",
48
49
  "@types/url-parse": "1.4.11",
49
50
  "chai": "^4.2.0",
50
51
  "chai-spies": "^1.1.0",
@@ -71,11 +72,12 @@
71
72
  "graphql": "^16.10.0",
72
73
  "graphql-request": "^6.1.0",
73
74
  "memory-cache": "^0.2.0",
75
+ "sinon-chai": "^4.0.0",
74
76
  "url-parse": "^1.5.10"
75
77
  },
76
78
  "description": "",
77
79
  "types": "types/index.d.ts",
78
- "gitHead": "36237ed63ce1e3829ccc45fddee95ed8d191c021",
80
+ "gitHead": "627eaa2aaf1042fefcfcecacc4084296766aabd1",
79
81
  "files": [
80
82
  "dist",
81
83
  "types",
@@ -2,6 +2,6 @@ export { GraphQLClientError, GraphQLClient, GraphQLRequestClient, GraphQLRequest
2
2
  export { DefaultRetryStrategy } from '../retries';
3
3
  export { RetryStrategy, PageInfo, FetchOptions } from '../models';
4
4
  export { getEdgeProxyContentUrl, getEdgeProxyFormsUrl } from './graphql-edge-proxy';
5
- export { SitecoreClient, Page, PageOptions } from './sitecore-client';
5
+ export { SitecoreClient, Page, PageOptions, SitemapXmlOptions } from './sitecore-client';
6
6
  export { SitecoreClientInit } from './models';
7
7
  export { createGraphQLClientFactory } from './utils';
@@ -4,7 +4,7 @@ import { DictionaryPhrases, GraphQLDictionaryService } from '../i18n';
4
4
  import { GraphQLLayoutService, LayoutServiceData, RouteOptions } from '../layout';
5
5
  import { HTMLLink, FetchOptions, StaticPath, RetryStrategy } from '../models';
6
6
  import { PersonalizedRewriteData } from '../personalize/utils';
7
- import { ErrorPages, SiteInfo, SiteResolver, GraphQLErrorPagesService, GraphQLSitePathService } from '../site';
7
+ import { ErrorPages, SiteInfo, SiteResolver, GraphQLErrorPagesService, GraphQLSitePathService, GraphQLSitemapXmlService } from '../site';
8
8
  import { SitecoreClientInit } from './models';
9
9
  /**
10
10
  * Represent a Page model returned from Edge endpoint
@@ -26,6 +26,17 @@ export type Page = {
26
26
  export type PageOptions = Partial<RouteOptions> & {
27
27
  personalize?: PersonalizedRewriteData;
28
28
  };
29
+ /**
30
+ * Request options for the getSiteMap method
31
+ */
32
+ export type SitemapXmlOptions = {
33
+ /** The hostname from the request (e.g., 'example.com') */
34
+ reqHost: string;
35
+ /** The protocol from request headers (e.g., 'https' or 'http') */
36
+ reqProtocol: string | string[];
37
+ /** Optional sitemap identifier when requesting a specific sitemap */
38
+ id?: string;
39
+ };
29
40
  /**
30
41
  * Contract for the Sitecore Client implementations
31
42
  */
@@ -81,6 +92,12 @@ export interface BaseSitecoreClient {
81
92
  enableStyles?: boolean;
82
93
  enableThemes?: boolean;
83
94
  }): HTMLLink[];
95
+ /**
96
+ * Retrieves sitemap XML content - either a specific sitemap or the index of all sitemaps.
97
+ * @param { SitemapRequestConfig} reqOptions - Configuration for sitemap retrieval
98
+ * @returns {Promise<string>} Promise resolving to the sitemap XML content as string
99
+ */
100
+ getSiteMap(reqOptions: SitemapXmlOptions): Promise<string>;
84
101
  }
85
102
  export interface BaseServiceOptions {
86
103
  defaultSite: string;
@@ -104,6 +121,7 @@ export declare class SitecoreClient implements BaseSitecoreClient {
104
121
  protected errorPagesService: GraphQLErrorPagesService;
105
122
  protected componentService: RestComponentLayoutService;
106
123
  protected sitePathService: GraphQLSitePathService;
124
+ protected sitemapXmlService: GraphQLSitemapXmlService;
107
125
  /**
108
126
  * Init SitecoreClient
109
127
  * @param {SitecoreClientInit} initOptions initOptions for the client, containing site and Sitecore connection details
@@ -176,10 +194,19 @@ export declare class SitecoreClient implements BaseSitecoreClient {
176
194
  * @returns {Promise<StaticPath[]>} A promise that resolves to an array of static paths.
177
195
  */
178
196
  getPagePaths(languages?: string[], fetchOptions?: FetchOptions): Promise<StaticPath[]>;
197
+ /**
198
+ * Retrieves sitemap XML content - either a specific sitemap or the index of all sitemaps.
199
+ * @param {SitemapXmlOptions} reqOptions - Options for sitemap retrieval
200
+ * @param {FetchOptions} [fetchOptions] - Additional fetch options.
201
+ * @returns {Promise<string>} Promise resolving to the sitemap XML content as string
202
+ * @throws {Error} Throws 'REDIRECT_404' if requested sitemap is not found
203
+ */
204
+ getSiteMap(reqOptions: SitemapXmlOptions, fetchOptions?: FetchOptions): Promise<string>;
179
205
  /**
180
206
  * Factory methods for creating dependencies
181
207
  * Subclasses can override these to provide custom implementations.
182
208
  */
209
+ protected getGraphqlSitemapXMLService(): GraphQLSitemapXmlService;
183
210
  protected getBaseServiceOptions(): BaseServiceOptions;
184
211
  protected getClientFactory(): GraphQLRequestClientFactory;
185
212
  protected getSiteResolver(): SiteResolver;