@sitecore-content-sdk/content 1.5.0-canary.10

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 (262) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +7 -0
  3. package/client.d.ts +1 -0
  4. package/codegen.d.ts +1 -0
  5. package/config-cli.d.ts +1 -0
  6. package/config.d.ts +1 -0
  7. package/dist/cjs/client/edge-proxy.js +29 -0
  8. package/dist/cjs/client/index.js +14 -0
  9. package/dist/cjs/client/models.js +2 -0
  10. package/dist/cjs/client/sitecore-client.js +443 -0
  11. package/dist/cjs/client/utils.js +53 -0
  12. package/dist/cjs/config/define-config.js +200 -0
  13. package/dist/cjs/config/index.js +7 -0
  14. package/dist/cjs/config/models.js +12 -0
  15. package/dist/cjs/config-cli/define-cli-config.js +23 -0
  16. package/dist/cjs/config-cli/index.js +7 -0
  17. package/dist/cjs/config-cli/models.js +8 -0
  18. package/dist/cjs/constants.js +12 -0
  19. package/dist/cjs/debug.js +21 -0
  20. package/dist/cjs/editing/codegen/index.js +15 -0
  21. package/dist/cjs/editing/codegen/preview.js +305 -0
  22. package/dist/cjs/editing/component-layout-service.js +63 -0
  23. package/dist/cjs/editing/design-library.js +191 -0
  24. package/dist/cjs/editing/editing-service.js +82 -0
  25. package/dist/cjs/editing/index.js +34 -0
  26. package/dist/cjs/editing/models.js +44 -0
  27. package/dist/cjs/editing/utils.js +105 -0
  28. package/dist/cjs/form/form.js +81 -0
  29. package/dist/cjs/form/index.js +7 -0
  30. package/dist/cjs/i18n/dictionary-service.js +144 -0
  31. package/dist/cjs/i18n/index.js +7 -0
  32. package/dist/cjs/i18n/utils.js +16 -0
  33. package/dist/cjs/index.js +47 -0
  34. package/dist/cjs/layout/content-styles.js +72 -0
  35. package/dist/cjs/layout/index.js +29 -0
  36. package/dist/cjs/layout/layout-service.js +69 -0
  37. package/dist/cjs/layout/models.js +39 -0
  38. package/dist/cjs/layout/rewrite-edge-host.js +161 -0
  39. package/dist/cjs/layout/themes.js +74 -0
  40. package/dist/cjs/layout/utils.js +117 -0
  41. package/dist/cjs/media/index.js +38 -0
  42. package/dist/cjs/media/media-api.js +100 -0
  43. package/dist/cjs/models.js +2 -0
  44. package/dist/cjs/personalize/index.js +15 -0
  45. package/dist/cjs/personalize/layout-personalizer.js +98 -0
  46. package/dist/cjs/personalize/personalize-service.js +109 -0
  47. package/dist/cjs/personalize/utils.js +143 -0
  48. package/dist/cjs/site/error-pages-service.js +95 -0
  49. package/dist/cjs/site/index.js +26 -0
  50. package/dist/cjs/site/models.js +2 -0
  51. package/dist/cjs/site/redirects-service.js +109 -0
  52. package/dist/cjs/site/robots-service.js +74 -0
  53. package/dist/cjs/site/site-resolver.js +73 -0
  54. package/dist/cjs/site/siteinfo-service.js +94 -0
  55. package/dist/cjs/site/sitemap-xml-service.js +92 -0
  56. package/dist/cjs/site/sitepath-service.js +201 -0
  57. package/dist/cjs/site/utils.js +55 -0
  58. package/dist/cjs/sitecore-service-base.js +33 -0
  59. package/dist/cjs/tools/codegen/component-generation.js +49 -0
  60. package/dist/cjs/tools/codegen/extract-files.js +103 -0
  61. package/dist/cjs/tools/codegen/import-map.js +398 -0
  62. package/dist/cjs/tools/codegen/utils.js +418 -0
  63. package/dist/cjs/tools/generate-map.js +2 -0
  64. package/dist/cjs/tools/generateSites.js +58 -0
  65. package/dist/cjs/tools/index.js +30 -0
  66. package/dist/cjs/tools/scaffold.js +62 -0
  67. package/dist/cjs/tools/templating/components.js +96 -0
  68. package/dist/cjs/tools/templating/index.js +6 -0
  69. package/dist/esm/client/edge-proxy.js +24 -0
  70. package/dist/esm/client/index.js +4 -0
  71. package/dist/esm/client/models.js +1 -0
  72. package/dist/esm/client/sitecore-client.js +439 -0
  73. package/dist/esm/client/utils.js +49 -0
  74. package/dist/esm/config/define-config.js +194 -0
  75. package/dist/esm/config/index.js +2 -0
  76. package/dist/esm/config/models.js +9 -0
  77. package/dist/esm/config-cli/define-cli-config.js +19 -0
  78. package/dist/esm/config-cli/index.js +2 -0
  79. package/dist/esm/config-cli/models.js +5 -0
  80. package/dist/esm/constants.js +9 -0
  81. package/dist/esm/debug.js +19 -0
  82. package/dist/esm/editing/codegen/index.js +1 -0
  83. package/dist/esm/editing/codegen/preview.js +287 -0
  84. package/dist/esm/editing/component-layout-service.js +56 -0
  85. package/dist/esm/editing/design-library.js +179 -0
  86. package/dist/esm/editing/editing-service.js +75 -0
  87. package/dist/esm/editing/index.js +6 -0
  88. package/dist/esm/editing/models.js +41 -0
  89. package/dist/esm/editing/utils.js +98 -0
  90. package/dist/esm/form/form.js +72 -0
  91. package/dist/esm/form/index.js +1 -0
  92. package/dist/esm/i18n/dictionary-service.js +137 -0
  93. package/dist/esm/i18n/index.js +2 -0
  94. package/dist/esm/i18n/utils.js +13 -0
  95. package/dist/esm/index.js +5 -0
  96. package/dist/esm/layout/content-styles.js +64 -0
  97. package/dist/esm/layout/index.js +7 -0
  98. package/dist/esm/layout/layout-service.js +62 -0
  99. package/dist/esm/layout/models.js +36 -0
  100. package/dist/esm/layout/rewrite-edge-host.js +155 -0
  101. package/dist/esm/layout/themes.js +69 -0
  102. package/dist/esm/layout/utils.js +109 -0
  103. package/dist/esm/media/index.js +2 -0
  104. package/dist/esm/media/media-api.js +90 -0
  105. package/dist/esm/models.js +1 -0
  106. package/dist/esm/personalize/index.js +3 -0
  107. package/dist/esm/personalize/layout-personalizer.js +93 -0
  108. package/dist/esm/personalize/personalize-service.js +102 -0
  109. package/dist/esm/personalize/utils.js +135 -0
  110. package/dist/esm/site/error-pages-service.js +88 -0
  111. package/dist/esm/site/index.js +8 -0
  112. package/dist/esm/site/models.js +1 -0
  113. package/dist/esm/site/redirects-service.js +102 -0
  114. package/dist/esm/site/robots-service.js +67 -0
  115. package/dist/esm/site/site-resolver.js +69 -0
  116. package/dist/esm/site/siteinfo-service.js +87 -0
  117. package/dist/esm/site/sitemap-xml-service.js +85 -0
  118. package/dist/esm/site/sitepath-service.js +193 -0
  119. package/dist/esm/site/utils.js +49 -0
  120. package/dist/esm/sitecore-service-base.js +29 -0
  121. package/dist/esm/tools/codegen/component-generation.js +44 -0
  122. package/dist/esm/tools/codegen/extract-files.js +97 -0
  123. package/dist/esm/tools/codegen/import-map.js +355 -0
  124. package/dist/esm/tools/codegen/utils.js +373 -0
  125. package/dist/esm/tools/generate-map.js +1 -0
  126. package/dist/esm/tools/generateSites.js +51 -0
  127. package/dist/esm/tools/index.js +6 -0
  128. package/dist/esm/tools/scaffold.js +54 -0
  129. package/dist/esm/tools/templating/components.js +59 -0
  130. package/dist/esm/tools/templating/index.js +1 -0
  131. package/editing.d.ts +1 -0
  132. package/i18n.d.ts +1 -0
  133. package/layout.d.ts +1 -0
  134. package/media.d.ts +1 -0
  135. package/package.json +157 -0
  136. package/personalize.d.ts +1 -0
  137. package/site.d.ts +1 -0
  138. package/tools.d.ts +1 -0
  139. package/types/client/edge-proxy.d.ts +17 -0
  140. package/types/client/edge-proxy.d.ts.map +1 -0
  141. package/types/client/index.d.ts +7 -0
  142. package/types/client/index.d.ts.map +1 -0
  143. package/types/client/models.d.ts +21 -0
  144. package/types/client/models.d.ts.map +1 -0
  145. package/types/client/sitecore-client.d.ts +346 -0
  146. package/types/client/sitecore-client.d.ts.map +1 -0
  147. package/types/client/utils.d.ts +15 -0
  148. package/types/client/utils.d.ts.map +1 -0
  149. package/types/config/define-config.d.ts +20 -0
  150. package/types/config/define-config.d.ts.map +1 -0
  151. package/types/config/index.d.ts +3 -0
  152. package/types/config/index.d.ts.map +1 -0
  153. package/types/config/models.d.ts +294 -0
  154. package/types/config/models.d.ts.map +1 -0
  155. package/types/config-cli/define-cli-config.d.ts +9 -0
  156. package/types/config-cli/define-cli-config.d.ts.map +1 -0
  157. package/types/config-cli/index.d.ts +3 -0
  158. package/types/config-cli/index.d.ts.map +1 -0
  159. package/types/config-cli/models.d.ts +6 -0
  160. package/types/config-cli/models.d.ts.map +1 -0
  161. package/types/constants.d.ts +10 -0
  162. package/types/constants.d.ts.map +1 -0
  163. package/types/debug.d.ts +19 -0
  164. package/types/debug.d.ts.map +1 -0
  165. package/types/editing/codegen/index.d.ts +2 -0
  166. package/types/editing/codegen/index.d.ts.map +1 -0
  167. package/types/editing/codegen/preview.d.ts +289 -0
  168. package/types/editing/codegen/preview.d.ts.map +1 -0
  169. package/types/editing/component-layout-service.d.ts +84 -0
  170. package/types/editing/component-layout-service.d.ts.map +1 -0
  171. package/types/editing/design-library.d.ts +119 -0
  172. package/types/editing/design-library.d.ts.map +1 -0
  173. package/types/editing/editing-service.d.ts +71 -0
  174. package/types/editing/editing-service.d.ts.map +1 -0
  175. package/types/editing/index.d.ts +7 -0
  176. package/types/editing/index.d.ts.map +1 -0
  177. package/types/editing/models.d.ts +103 -0
  178. package/types/editing/models.d.ts.map +1 -0
  179. package/types/editing/utils.d.ts +82 -0
  180. package/types/editing/utils.d.ts.map +1 -0
  181. package/types/form/form.d.ts +25 -0
  182. package/types/form/form.d.ts.map +1 -0
  183. package/types/form/index.d.ts +2 -0
  184. package/types/form/index.d.ts.map +1 -0
  185. package/types/i18n/dictionary-service.d.ts +133 -0
  186. package/types/i18n/dictionary-service.d.ts.map +1 -0
  187. package/types/i18n/index.d.ts +3 -0
  188. package/types/i18n/index.d.ts.map +1 -0
  189. package/types/i18n/utils.d.ts +9 -0
  190. package/types/i18n/utils.d.ts.map +1 -0
  191. package/types/index.d.ts +7 -0
  192. package/types/index.d.ts.map +1 -0
  193. package/types/layout/content-styles.d.ts +20 -0
  194. package/types/layout/content-styles.d.ts.map +1 -0
  195. package/types/layout/index.d.ts +7 -0
  196. package/types/layout/index.d.ts.map +1 -0
  197. package/types/layout/layout-service.d.ts +45 -0
  198. package/types/layout/layout-service.d.ts.map +1 -0
  199. package/types/layout/models.d.ts +174 -0
  200. package/types/layout/models.d.ts.map +1 -0
  201. package/types/layout/rewrite-edge-host.d.ts +43 -0
  202. package/types/layout/rewrite-edge-host.d.ts.map +1 -0
  203. package/types/layout/themes.d.ts +13 -0
  204. package/types/layout/themes.d.ts.map +1 -0
  205. package/types/layout/utils.d.ts +56 -0
  206. package/types/layout/utils.d.ts.map +1 -0
  207. package/types/media/index.d.ts +3 -0
  208. package/types/media/index.d.ts.map +1 -0
  209. package/types/media/media-api.d.ts +60 -0
  210. package/types/media/media-api.d.ts.map +1 -0
  211. package/types/models.d.ts +32 -0
  212. package/types/models.d.ts.map +1 -0
  213. package/types/personalize/index.d.ts +4 -0
  214. package/types/personalize/index.d.ts.map +1 -0
  215. package/types/personalize/layout-personalizer.d.ts +29 -0
  216. package/types/personalize/layout-personalizer.d.ts.map +1 -0
  217. package/types/personalize/personalize-service.d.ts +88 -0
  218. package/types/personalize/personalize-service.d.ts.map +1 -0
  219. package/types/personalize/utils.d.ts +78 -0
  220. package/types/personalize/utils.d.ts.map +1 -0
  221. package/types/site/error-pages-service.d.ts +72 -0
  222. package/types/site/error-pages-service.d.ts.map +1 -0
  223. package/types/site/index.d.ts +10 -0
  224. package/types/site/index.d.ts.map +1 -0
  225. package/types/site/models.d.ts +23 -0
  226. package/types/site/models.d.ts.map +1 -0
  227. package/types/site/redirects-service.d.ts +91 -0
  228. package/types/site/redirects-service.d.ts.map +1 -0
  229. package/types/site/robots-service.d.ts +57 -0
  230. package/types/site/robots-service.d.ts.map +1 -0
  231. package/types/site/site-resolver.d.ts +28 -0
  232. package/types/site/site-resolver.d.ts.map +1 -0
  233. package/types/site/siteinfo-service.d.ts +64 -0
  234. package/types/site/siteinfo-service.d.ts.map +1 -0
  235. package/types/site/sitemap-xml-service.d.ts +63 -0
  236. package/types/site/sitemap-xml-service.d.ts.map +1 -0
  237. package/types/site/sitepath-service.d.ts +137 -0
  238. package/types/site/sitepath-service.d.ts.map +1 -0
  239. package/types/site/utils.d.ts +41 -0
  240. package/types/site/utils.d.ts.map +1 -0
  241. package/types/sitecore-service-base.d.ts +31 -0
  242. package/types/sitecore-service-base.d.ts.map +1 -0
  243. package/types/tools/codegen/component-generation.d.ts +50 -0
  244. package/types/tools/codegen/component-generation.d.ts.map +1 -0
  245. package/types/tools/codegen/extract-files.d.ts +20 -0
  246. package/types/tools/codegen/extract-files.d.ts.map +1 -0
  247. package/types/tools/codegen/import-map.d.ts +98 -0
  248. package/types/tools/codegen/import-map.d.ts.map +1 -0
  249. package/types/tools/codegen/utils.d.ts +76 -0
  250. package/types/tools/codegen/utils.d.ts.map +1 -0
  251. package/types/tools/generate-map.d.ts +36 -0
  252. package/types/tools/generate-map.d.ts.map +1 -0
  253. package/types/tools/generateSites.d.ts +22 -0
  254. package/types/tools/generateSites.d.ts.map +1 -0
  255. package/types/tools/index.d.ts +8 -0
  256. package/types/tools/index.d.ts.map +1 -0
  257. package/types/tools/scaffold.d.ts +27 -0
  258. package/types/tools/scaffold.d.ts.map +1 -0
  259. package/types/tools/templating/components.d.ts +104 -0
  260. package/types/tools/templating/components.d.ts.map +1 -0
  261. package/types/tools/templating/index.d.ts +2 -0
  262. package/types/tools/templating/index.d.ts.map +1 -0
@@ -0,0 +1,87 @@
1
+ import { MemoryCacheClient } from '@sitecore-content-sdk/core';
2
+ import debug from '../debug';
3
+ const siteQuery = /* GraphQL */ `
4
+ query {
5
+ site {
6
+ siteInfoCollection {
7
+ name
8
+ hostName: hostname
9
+ language
10
+ }
11
+ }
12
+ }
13
+ `;
14
+ /**
15
+ * Service to fetch site information
16
+ * @public
17
+ */
18
+ export class SiteInfoService {
19
+ /**
20
+ * Creates an instance of graphQL service to retrieve site configuration list from Sitecore
21
+ * @param {SiteInfoServiceConfig} config instance
22
+ */
23
+ constructor(config) {
24
+ this.config = config;
25
+ this.graphQLClient = this.getGraphQLClient();
26
+ this.cache = this.getCacheClient();
27
+ }
28
+ /**
29
+ * site query is available on XM Cloud and XP 10.4+
30
+ */
31
+ get siteQuery() {
32
+ return siteQuery;
33
+ }
34
+ async fetchSiteInfo(fetchOptions) {
35
+ var _a, _b;
36
+ const cachedResult = this.cache.getCacheValue(this.getCacheKey());
37
+ if (cachedResult) {
38
+ return cachedResult;
39
+ }
40
+ if (process.env.SITECORE) {
41
+ debug.multisite('Skipping site information fetch (building on XM Cloud)');
42
+ return [];
43
+ }
44
+ const response = await this.graphQLClient.request(this.siteQuery, {}, fetchOptions);
45
+ const results = (_b = (_a = response === null || response === void 0 ? void 0 : response.site) === null || _a === void 0 ? void 0 : _a.siteInfoCollection) === null || _b === void 0 ? void 0 : _b.reduce((result, current) => {
46
+ // filter out built in website
47
+ current.name !== 'website' &&
48
+ result.push({
49
+ name: current.name,
50
+ hostName: current.hostName,
51
+ language: current.language,
52
+ });
53
+ return result;
54
+ }, []);
55
+ this.cache.setCacheValue(this.getCacheKey(), results);
56
+ return results;
57
+ }
58
+ /**
59
+ * Gets cache client implementation
60
+ * Override this method if custom cache needs to be used
61
+ * @returns CacheClient instance
62
+ */
63
+ getCacheClient() {
64
+ var _a, _b;
65
+ return new MemoryCacheClient({
66
+ cacheEnabled: (_a = this.config.cacheEnabled) !== null && _a !== void 0 ? _a : true,
67
+ cacheTimeout: (_b = this.config.cacheTimeout) !== null && _b !== void 0 ? _b : 10,
68
+ });
69
+ }
70
+ /**
71
+ * Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default
72
+ * library for fetching graphql data (@see GraphQLRequestClient). Override this method if you
73
+ * want to use something else.
74
+ * @returns {GraphQLClient} implementation
75
+ */
76
+ getGraphQLClient() {
77
+ if (!this.config.clientFactory) {
78
+ throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
79
+ }
80
+ return this.config.clientFactory({
81
+ debugger: debug.multisite,
82
+ });
83
+ }
84
+ getCacheKey() {
85
+ return 'siteinfo-service-cache';
86
+ }
87
+ }
@@ -0,0 +1,85 @@
1
+ import debug from '../debug';
2
+ import { siteNameError } from '../constants';
3
+ const PREFIX_NAME_SITEMAP = 'sitemap';
4
+ // The default query for request sitemaps
5
+ const defaultQuery = /* GraphQL */ `
6
+ query SitemapQuery($siteName: String!) {
7
+ site {
8
+ siteInfo(site: $siteName) {
9
+ sitemap
10
+ }
11
+ }
12
+ }
13
+ `;
14
+ /**
15
+ * Service that fetch the sitemaps data using Sitecore's GraphQL API.
16
+ * @public
17
+ */
18
+ export class SitemapXmlService {
19
+ /**
20
+ * Creates an instance of graphQL sitemaps service with the provided options
21
+ * @param {SitemapXmlServiceConfig} options instance
22
+ */
23
+ constructor(options) {
24
+ this.options = options;
25
+ this.graphQLClient = this.getGraphQLClient();
26
+ }
27
+ get query() {
28
+ return defaultQuery;
29
+ }
30
+ /**
31
+ * Fetch list of sitemaps for the site
32
+ * @returns {string[]} list of sitemap paths
33
+ * @param {FetchOptions} [fetchOptions] Options to override graphQL client details like retries and fetch implementation
34
+ * @throws {Error} if the siteName is empty.
35
+ */
36
+ async fetchSitemaps(fetchOptions) {
37
+ const siteName = this.options.siteName;
38
+ if (!siteName) {
39
+ throw new Error(siteNameError);
40
+ }
41
+ const sitemapResult = this.graphQLClient.request(this.query, {
42
+ siteName,
43
+ }, fetchOptions);
44
+ try {
45
+ return sitemapResult.then((result) => result.site.siteInfo.sitemap);
46
+ }
47
+ catch (e) {
48
+ return Promise.reject(e);
49
+ }
50
+ }
51
+ /**
52
+ * Get sitemap file path for sitemap id
53
+ * @param {string} id the sitemap id (can be empty for default 'sitemap.xml' file)
54
+ * @returns {string | undefined} the sitemap file path or undefined if one doesn't exist
55
+ */
56
+ async getSitemap(id) {
57
+ let searchSitemap;
58
+ if (id === undefined) {
59
+ return undefined;
60
+ }
61
+ else if (id === '') {
62
+ searchSitemap = `${PREFIX_NAME_SITEMAP}.xml`;
63
+ }
64
+ else {
65
+ const normalizedId = id.startsWith('-') ? id.slice(1) : id;
66
+ searchSitemap = `${PREFIX_NAME_SITEMAP}-${normalizedId}.xml`;
67
+ }
68
+ const sitemaps = await this.fetchSitemaps();
69
+ return sitemaps.find((sitemap) => sitemap.includes(searchSitemap));
70
+ }
71
+ /**
72
+ * Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default
73
+ * library for fetching graphql data (@see GraphQLRequestClient). Override this method if you
74
+ * want to use something else.
75
+ * @returns {GraphQLClient} implementation
76
+ */
77
+ getGraphQLClient() {
78
+ if (!this.options.clientFactory) {
79
+ throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
80
+ }
81
+ return this.options.clientFactory({
82
+ debugger: debug.sitemap,
83
+ });
84
+ }
85
+ }
@@ -0,0 +1,193 @@
1
+ import { getPersonalizedRewrite } from '../personalize';
2
+ import { getSiteRewrite } from '../site';
3
+ import debug from '../debug';
4
+ /** @private */
5
+ export const languageError = 'The list of languages cannot be empty';
6
+ export const siteError = 'The service needs a site name';
7
+ export const sitesError = 'The list of sites cannot be empty';
8
+ /**
9
+ * @param {string} siteName to inject into error text
10
+ * @private
11
+ */
12
+ export function getSiteEmptyError(siteName) {
13
+ return `Site "${siteName}" does not exist or site item tree is missing`;
14
+ }
15
+ /**
16
+ * GQL query made dynamic based whether personalization is enabled or not
17
+ * @param {boolean} usesPersonalize flag to detrmine which variation of a query to run
18
+ * @returns GraphQL query to fetch site paths with
19
+ */
20
+ const defaultQuery = (usesPersonalize) => /* GraphQL */ `
21
+ query ${usesPersonalize ? 'PersonalizeSitemapQuery' : 'DefaultSitemapQuery'}(
22
+ $siteName: String!
23
+ $language: String!
24
+ $includedPaths: [String]
25
+ $excludedPaths: [String]
26
+ $pageSize: Int = 100
27
+ $after: String
28
+ ) {
29
+ site {
30
+ siteInfo(site: $siteName) {
31
+ routes(
32
+ language: $language
33
+ includedPaths: $includedPaths
34
+ excludedPaths: $excludedPaths
35
+ first: $pageSize
36
+ after: $after
37
+ ){
38
+ total
39
+ pageInfo {
40
+ endCursor
41
+ hasNext
42
+ }
43
+ results {
44
+ path: routePath
45
+ ${usesPersonalize
46
+ ? `
47
+ route {
48
+ personalization {
49
+ variantIds
50
+ }
51
+ }`
52
+ : ''}
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ `;
59
+ /**
60
+ * Service that fetches the list of site pages using Sitecore's GraphQL API.
61
+ * Used to handle a single site
62
+ * This list is used for SSG and Export functionality.
63
+ * @mixes SearchQueryService<PageListQueryResult>
64
+ * @public
65
+ */
66
+ export class SitePathService {
67
+ /**
68
+ * Creates an instance of graphQL sitemap service with the provided options
69
+ * @param {SitePathServiceConfig} options instance
70
+ */
71
+ constructor(options) {
72
+ this.options = options;
73
+ this._graphQLClient = this.getGraphQLClient();
74
+ }
75
+ /**
76
+ * GraphQL client accessible by descendant classes when needed
77
+ */
78
+ get graphQLClient() {
79
+ return this._graphQLClient;
80
+ }
81
+ /**
82
+ * Gets the default query used for fetching the list of site pages
83
+ */
84
+ get query() {
85
+ return defaultQuery(this.options.includePersonalizedRoutes);
86
+ }
87
+ /**
88
+ * Fetch a flat list of all pages that belong to all the requested sites and have a
89
+ * version in the specified language(s).
90
+ * @param {string[]} sites Fetch pages for these sites.
91
+ * @param {string[]} languages Fetch pages that have versions in this language(s).
92
+ * @param {FetchOptions} fetchOptions Options to override graphQL client details like retries and fetch implementation
93
+ * @returns list of pages
94
+ * @throws {RangeError} if the list of languages is empty.
95
+ * @throws {RangeError} if the any of the languages is an empty string.
96
+ */
97
+ async fetchSiteRoutes(sites, languages, fetchOptions) {
98
+ const formatPath = (path, locale) => ({
99
+ params: {
100
+ path,
101
+ },
102
+ locale,
103
+ });
104
+ const paths = new Array();
105
+ if (!languages.length) {
106
+ throw new RangeError(languageError);
107
+ }
108
+ // Get all sites
109
+ if (!sites || !sites.length) {
110
+ throw new RangeError(sitesError);
111
+ }
112
+ // Fetch paths for each site
113
+ for (let i = 0; i < sites.length; i++) {
114
+ for (const language of languages) {
115
+ // Fetch paths using all locales
116
+ const sitePaths = await this.fetchLanguageSitePaths(language, sites[i], fetchOptions);
117
+ const transformedPaths = await this.transformLanguageSitePaths(sitePaths, formatPath, language);
118
+ paths.push(...transformedPaths);
119
+ }
120
+ }
121
+ return [].concat(...paths);
122
+ }
123
+ async transformLanguageSitePaths(sitePaths, formatStaticPath, language) {
124
+ const toSegments = (p) => decodeURI(p)
125
+ .replace(/^\/|\/$/g, '')
126
+ .split('/');
127
+ const aggregatedPaths = [];
128
+ sitePaths.forEach((item) => {
129
+ var _a, _b, _c;
130
+ if (!item)
131
+ return;
132
+ aggregatedPaths.push(formatStaticPath(toSegments(item.path), language));
133
+ const variantIds = (_c = (_b = (_a = item.route) === null || _a === void 0 ? void 0 : _a.personalization) === null || _b === void 0 ? void 0 : _b.variantIds) === null || _c === void 0 ? void 0 : _c.filter((variantId) => !variantId.includes('_') // exclude component A/B test
134
+ );
135
+ if (variantIds === null || variantIds === void 0 ? void 0 : variantIds.length) {
136
+ aggregatedPaths.push(...variantIds.map((varId) => formatStaticPath(toSegments(getPersonalizedRewrite(item.path, [varId])), language)));
137
+ }
138
+ });
139
+ return aggregatedPaths;
140
+ }
141
+ /**
142
+ * Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default
143
+ * library for fetching graphql data (@see GraphQLRequestClient). Override this method if you
144
+ * want to use something else.
145
+ * @returns {GraphQLClient} implementation
146
+ */
147
+ getGraphQLClient() {
148
+ if (!this.options.clientFactory) {
149
+ throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
150
+ }
151
+ return this.options.clientFactory({
152
+ debugger: debug.sitemap,
153
+ });
154
+ }
155
+ /**
156
+ * Fetch and return site paths for multisite implementation, with prefixes included
157
+ * @param {string} language path language
158
+ * @param {string} siteName site name
159
+ * @param {FetchOptions} fetchOptions Options to override graphQL client details like retries and fetch implementation
160
+ * @returns modified paths
161
+ */
162
+ async fetchLanguageSitePaths(language, siteName, fetchOptions) {
163
+ var _a, _b, _c, _d;
164
+ const args = {
165
+ siteName: siteName,
166
+ language: language,
167
+ pageSize: this.options.pageSize,
168
+ includedPaths: this.options.includedPaths,
169
+ excludedPaths: this.options.excludedPaths,
170
+ };
171
+ let results = [];
172
+ let hasNext = true;
173
+ let after = '';
174
+ debug.sitemap('fetching sitemap data for %s %s', language, siteName);
175
+ while (hasNext) {
176
+ const fetchResponse = await this.graphQLClient.request(this.query, Object.assign(Object.assign({}, args), { after }), fetchOptions);
177
+ if (!((_a = fetchResponse === null || fetchResponse === void 0 ? void 0 : fetchResponse.site) === null || _a === void 0 ? void 0 : _a.siteInfo)) {
178
+ throw new RangeError(getSiteEmptyError(siteName));
179
+ }
180
+ else {
181
+ results = results.concat((_b = fetchResponse.site.siteInfo.routes) === null || _b === void 0 ? void 0 : _b.results);
182
+ hasNext = (_c = fetchResponse.site.siteInfo.routes) === null || _c === void 0 ? void 0 : _c.pageInfo.hasNext;
183
+ after = (_d = fetchResponse.site.siteInfo.routes) === null || _d === void 0 ? void 0 : _d.pageInfo.endCursor;
184
+ }
185
+ }
186
+ results.forEach((item) => {
187
+ if (item) {
188
+ item.path = getSiteRewrite(item.path, { siteName: siteName });
189
+ }
190
+ });
191
+ return results;
192
+ }
193
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Site prefix for rewrite path
3
+ * @public
4
+ */
5
+ export const SITE_PREFIX = '_site_';
6
+ /**
7
+ * Site key for cookie and query string parameter access
8
+ * @public
9
+ */
10
+ export const SITE_KEY = 'sc_site';
11
+ /**
12
+ * Get a site rewrite path for given pathname
13
+ * @param {string} pathname the pathname
14
+ * @param {SiteRewriteData} data the site data to include in the rewrite
15
+ * @returns {string} the rewrite path
16
+ * @public
17
+ */
18
+ export function getSiteRewrite(pathname, data) {
19
+ const path = pathname.startsWith('/') ? pathname : '/' + pathname;
20
+ return `/${SITE_PREFIX}${data.siteName}${path}`;
21
+ }
22
+ /**
23
+ * Get site data from the rewrite path
24
+ * @param {string} pathname the pathname
25
+ * @param {string} defaultSiteName the default site name
26
+ * @returns {SiteRewriteData} the site data from the rewrite
27
+ * @public
28
+ */
29
+ export function getSiteRewriteData(pathname, defaultSiteName) {
30
+ const data = {
31
+ siteName: defaultSiteName,
32
+ };
33
+ const path = pathname.endsWith('/') ? pathname : pathname + '/';
34
+ const result = path.match(`${SITE_PREFIX}(.*?)\\/`);
35
+ if (result && result[1] !== '') {
36
+ data.siteName = result[1];
37
+ }
38
+ return data;
39
+ }
40
+ /**
41
+ * Normalize a site rewrite path (remove site data)
42
+ * @param {string} pathname the pathname
43
+ * @returns {string} the pathname with site data removed
44
+ * @public
45
+ */
46
+ export function normalizeSiteRewrite(pathname) {
47
+ const result = pathname.match(`${SITE_PREFIX}.*?(?:\\/|$)`);
48
+ return result === null ? pathname : pathname.replace(result[0], '');
49
+ }
@@ -0,0 +1,29 @@
1
+ import { debug } from '@sitecore-content-sdk/core';
2
+ /**
3
+ * Base abstraction to implement custom layout service
4
+ */
5
+ export class SitecoreServiceBase {
6
+ /**
7
+ * Fetch layout data using the Sitecore GraphQL endpoint.
8
+ * @param {GraphQLServiceConfig} serviceConfig configuration
9
+ */
10
+ constructor(serviceConfig) {
11
+ this.serviceConfig = serviceConfig;
12
+ this.graphQLClient = this.getGraphQLClient();
13
+ }
14
+ /**
15
+ * Gets a GraphQL client that can make requests to the API.
16
+ * @returns {GraphQLClient} implementation
17
+ */
18
+ getGraphQLClient() {
19
+ var _a, _b;
20
+ if (!this.serviceConfig.clientFactory) {
21
+ throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
22
+ }
23
+ return this.serviceConfig.clientFactory({
24
+ debugger: this.serviceConfig.debugger || debug.http,
25
+ retries: (_a = this.serviceConfig.retries) === null || _a === void 0 ? void 0 : _a.count,
26
+ retryStrategy: (_b = this.serviceConfig.retries) === null || _b === void 0 ? void 0 : _b.retryStrategy,
27
+ });
28
+ }
29
+ }
@@ -0,0 +1,44 @@
1
+ import { constants, debug } from '@sitecore-content-sdk/core';
2
+ const { SITECORE_EDGE_PLATFORM_URL_DEFAULT } = constants;
3
+ /**
4
+ * Gets the component spec url.
5
+ * @param {GetComponentSpecParams} params - The parameters for getting the component spec url.
6
+ * @returns {string} The component spec url.
7
+ * @internal
8
+ */
9
+ export const getComponentSpecUrl = ({ componentId, edgeUrl = SITECORE_EDGE_PLATFORM_URL_DEFAULT, targetPath, token, }) => {
10
+ let url = `${edgeUrl}/authoring/api/v1/components/generated/${componentId}?token=${token}`;
11
+ if (targetPath) {
12
+ url += `&targetPath=${encodeURIComponent(targetPath)}`;
13
+ }
14
+ return url;
15
+ };
16
+ /**
17
+ * Fetches the component spec.
18
+ * @param {GetComponentSpecParams} params - The parameters for fetching the component spec.
19
+ * @returns {Promise<ComponentSpec>} The component spec.
20
+ * @internal
21
+ */
22
+ export const getComponentSpec = async ({ componentId, edgeUrl = SITECORE_EDGE_PLATFORM_URL_DEFAULT, targetPath, token, }) => {
23
+ const url = getComponentSpecUrl({ componentId, edgeUrl, targetPath, token });
24
+ debug.common('Fetching component spec for %s: %s', componentId, url);
25
+ try {
26
+ const response = await fetch(url);
27
+ if (response.status === 404) {
28
+ throw new Error(`Component '${componentId}' was not found. Please verify the component ID is correct and exists.`);
29
+ }
30
+ if (response.status === 401) {
31
+ throw new Error('The token is incorrect or expired or the component ID is incorrect.');
32
+ }
33
+ if (!response.ok) {
34
+ throw new Error(`Failed to fetch component ${componentId}`);
35
+ }
36
+ const spec = await response.json();
37
+ debug.common('Component spec fetched successfully for %s: %o', componentId, spec);
38
+ return spec;
39
+ }
40
+ catch (error) {
41
+ debug.common('Failed to fetch component spec: %s', String(error));
42
+ throw error;
43
+ }
44
+ };
@@ -0,0 +1,97 @@
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ import chalk from 'chalk';
3
+ import { ExtractedFileType, resolveComponentImportFiles, sendCode, validateDeployContext, readNamedExports, } from './utils';
4
+ import { auth } from '@sitecore-content-sdk/core/tools';
5
+ import { debug } from '@sitecore-content-sdk/core';
6
+ import path from 'path';
7
+ import fs from 'fs';
8
+ /**
9
+ * Extracts components from the app folder and sends them to XMCloud.
10
+ * @param {ExtractFilesConfig} args - Config for components extraction
11
+ * @public
12
+ */
13
+ export let extractFiles = _extractFiles;
14
+ // mock setup for unit tests to make sinon happy and mock-able with esbuild/tsx
15
+ // https://sinonjs.org/how-to/typescript-swc/
16
+ // This, plus the `_` names make the exports writable for sinon
17
+ export const unitMocks = {
18
+ set extractFiles(mockImplementation) {
19
+ extractFiles = mockImplementation;
20
+ },
21
+ get extractFiles() {
22
+ return _extractFiles;
23
+ },
24
+ };
25
+ function _extractFiles(args = {}) {
26
+ const authParams = {
27
+ clientId: process.env.SITECORE_AUTH_CLIENT_ID || '',
28
+ clientSecret: process.env.SITECORE_AUTH_CLIENT_SECRET || '',
29
+ authority: process.env.SITECORE_AUTH_AUTHORITY,
30
+ audience: process.env.SITECORE_AUTH_AUDIENCE,
31
+ };
32
+ const renderingHost = process.env.SITECORE_RENDERINGHOST_NAME;
33
+ return async ({ scConfig }) => {
34
+ if (!scConfig) {
35
+ throw new Error('Sitecore configuration is required to be provided');
36
+ }
37
+ if ((args.customValidateDeployContext && !args.customValidateDeployContext()) ||
38
+ !validateDeployContext()) {
39
+ debug.common('Skipping code extraction, not in deploy context');
40
+ return;
41
+ }
42
+ if (scConfig.disableCodeGeneration) {
43
+ debug.common('Skipping code extraction, code generation has been disabled');
44
+ return;
45
+ }
46
+ console.log(chalk.green('Code extraction started'));
47
+ const basePath = process.cwd();
48
+ try {
49
+ // Use Edge Platform mesh endpoint - staging is ready, prod QA in progress
50
+ const targetUrl = scConfig.api.edge.edgeUrl;
51
+ const { accessToken } = await auth.clientCredentialsFlow(authParams);
52
+ if (!accessToken) {
53
+ console.error(chalk.red('Failed to get access token, aborting code extraction'));
54
+ return;
55
+ }
56
+ // Resolve files from component-map
57
+ const resolvedImports = await resolveComponentImportFiles(basePath, args.componentMapPath);
58
+ const clientComponentMapPath = args.clientComponentMapPath || '.sitecore/component-map.client.ts';
59
+ const absClientMapPath = path.isAbsolute(clientComponentMapPath)
60
+ ? clientComponentMapPath
61
+ : path.resolve(basePath, clientComponentMapPath);
62
+ const exists = fs.existsSync(absClientMapPath);
63
+ if (exists) {
64
+ resolvedImports.push(...(await resolveComponentImportFiles(basePath, absClientMapPath)));
65
+ }
66
+ const fileDispatches = [];
67
+ for (const { componentKey, filePath, fileType } of resolvedImports) {
68
+ let extraLabels;
69
+ // return an array of export names (e.g., ['Default','Cooler'])
70
+ const variantNames = readNamedExports(filePath);
71
+ extraLabels = Object.assign(Object.assign({}, (variantNames.length ? { variantNames } : {})), (renderingHost ? { renderingHost } : {}));
72
+ fileDispatches.push(sendCode({
73
+ file: {
74
+ labels: extraLabels,
75
+ name: componentKey,
76
+ path: filePath,
77
+ type: fileType,
78
+ },
79
+ targetUrl,
80
+ token: accessToken,
81
+ }));
82
+ }
83
+ fileDispatches.push(sendCode({
84
+ file: Object.assign(Object.assign({}, (renderingHost ? { labels: { renderingHost } } : {})), { name: 'package.json', path: path.resolve(basePath, './package.json'), type: ExtractedFileType.PackageJson }),
85
+ targetUrl,
86
+ token: accessToken,
87
+ }));
88
+ const files = await Promise.all(fileDispatches);
89
+ console.log(chalk.green(`Code extraction completed successfully, files extracted:\r\n${files
90
+ .filter((file) => file !== null)
91
+ .join('\r\n')}`));
92
+ }
93
+ catch (error) {
94
+ console.warn(chalk.yellow('Error during code extraction:', error, error.stack));
95
+ }
96
+ };
97
+ }