@sitecore-jss/sitecore-jss 0.1.0-beta.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 (143) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +7 -0
  3. package/dist/cjs/cache-client.js +54 -0
  4. package/dist/cjs/constants.js +12 -0
  5. package/dist/cjs/debug.js +43 -0
  6. package/dist/cjs/graphql/app-root-query.js +73 -0
  7. package/dist/cjs/graphql/graphql-edge-proxy.js +12 -0
  8. package/dist/cjs/graphql/index.js +11 -0
  9. package/dist/cjs/graphql/search-service.js +60 -0
  10. package/dist/cjs/graphql-request-client.js +106 -0
  11. package/dist/cjs/i18n/dictionary-service.js +45 -0
  12. package/dist/cjs/i18n/graphql-dictionary-service.js +125 -0
  13. package/dist/cjs/i18n/index.js +7 -0
  14. package/dist/cjs/index.js +36 -0
  15. package/dist/cjs/layout/content-styles.js +73 -0
  16. package/dist/cjs/layout/graphql-layout-service.js +84 -0
  17. package/dist/cjs/layout/index.js +18 -0
  18. package/dist/cjs/layout/layout-service.js +9 -0
  19. package/dist/cjs/layout/models.js +27 -0
  20. package/dist/cjs/layout/themes.js +79 -0
  21. package/dist/cjs/layout/utils.js +44 -0
  22. package/dist/cjs/media/index.js +24 -0
  23. package/dist/cjs/media/media-api.js +128 -0
  24. package/dist/cjs/models.js +2 -0
  25. package/dist/cjs/native-fetcher.js +183 -0
  26. package/dist/cjs/personalize/graphql-personalize-service.js +114 -0
  27. package/dist/cjs/personalize/index.js +12 -0
  28. package/dist/cjs/personalize/layout-personalizer.js +75 -0
  29. package/dist/cjs/personalize/utils.js +92 -0
  30. package/dist/cjs/site/graphql-error-pages-service.js +86 -0
  31. package/dist/cjs/site/graphql-redirects-service.js +103 -0
  32. package/dist/cjs/site/graphql-robots-service.js +81 -0
  33. package/dist/cjs/site/graphql-siteinfo-service.js +128 -0
  34. package/dist/cjs/site/graphql-sitemap-service.js +91 -0
  35. package/dist/cjs/site/index.js +22 -0
  36. package/dist/cjs/site/site-resolver.js +79 -0
  37. package/dist/cjs/site/utils.js +43 -0
  38. package/dist/cjs/utils/edit-frame.js +138 -0
  39. package/dist/cjs/utils/editing.js +122 -0
  40. package/dist/cjs/utils/env.js +26 -0
  41. package/dist/cjs/utils/index.js +25 -0
  42. package/dist/cjs/utils/is-server.js +10 -0
  43. package/dist/cjs/utils/timeout-promise.js +31 -0
  44. package/dist/cjs/utils/utils.js +70 -0
  45. package/dist/esm/cache-client.js +50 -0
  46. package/dist/esm/constants.js +9 -0
  47. package/dist/esm/debug.js +36 -0
  48. package/dist/esm/graphql/app-root-query.js +69 -0
  49. package/dist/esm/graphql/graphql-edge-proxy.js +8 -0
  50. package/dist/esm/graphql/index.js +4 -0
  51. package/dist/esm/graphql/search-service.js +56 -0
  52. package/dist/esm/graphql-request-client.js +99 -0
  53. package/dist/esm/i18n/dictionary-service.js +41 -0
  54. package/dist/esm/i18n/graphql-dictionary-service.js +118 -0
  55. package/dist/esm/i18n/index.js +2 -0
  56. package/dist/esm/index.js +7 -0
  57. package/dist/esm/layout/content-styles.js +65 -0
  58. package/dist/esm/layout/graphql-layout-service.js +77 -0
  59. package/dist/esm/layout/index.js +6 -0
  60. package/dist/esm/layout/layout-service.js +5 -0
  61. package/dist/esm/layout/models.js +24 -0
  62. package/dist/esm/layout/themes.js +74 -0
  63. package/dist/esm/layout/utils.js +39 -0
  64. package/dist/esm/media/index.js +2 -0
  65. package/dist/esm/media/media-api.js +117 -0
  66. package/dist/esm/models.js +1 -0
  67. package/dist/esm/native-fetcher.js +176 -0
  68. package/dist/esm/personalize/graphql-personalize-service.js +107 -0
  69. package/dist/esm/personalize/index.js +3 -0
  70. package/dist/esm/personalize/layout-personalizer.js +69 -0
  71. package/dist/esm/personalize/utils.js +85 -0
  72. package/dist/esm/site/graphql-error-pages-service.js +79 -0
  73. package/dist/esm/site/graphql-redirects-service.js +96 -0
  74. package/dist/esm/site/graphql-robots-service.js +74 -0
  75. package/dist/esm/site/graphql-siteinfo-service.js +121 -0
  76. package/dist/esm/site/graphql-sitemap-service.js +84 -0
  77. package/dist/esm/site/index.js +7 -0
  78. package/dist/esm/site/site-resolver.js +75 -0
  79. package/dist/esm/site/utils.js +37 -0
  80. package/dist/esm/utils/edit-frame.js +133 -0
  81. package/dist/esm/utils/editing.js +111 -0
  82. package/dist/esm/utils/env.js +22 -0
  83. package/dist/esm/utils/index.js +5 -0
  84. package/dist/esm/utils/is-server.js +8 -0
  85. package/dist/esm/utils/timeout-promise.js +28 -0
  86. package/dist/esm/utils/utils.js +61 -0
  87. package/graphql.d.ts +1 -0
  88. package/graphql.js +1 -0
  89. package/i18n.d.ts +1 -0
  90. package/i18n.js +1 -0
  91. package/layout.d.ts +1 -0
  92. package/layout.js +1 -0
  93. package/media.d.ts +1 -0
  94. package/media.js +1 -0
  95. package/package.json +71 -0
  96. package/personalize.d.ts +1 -0
  97. package/personalize.js +1 -0
  98. package/site.d.ts +1 -0
  99. package/site.js +1 -0
  100. package/types/cache-client.d.ts +64 -0
  101. package/types/constants.d.ts +6 -0
  102. package/types/debug.d.ts +26 -0
  103. package/types/graphql/app-root-query.d.ts +32 -0
  104. package/types/graphql/graphql-edge-proxy.d.ts +7 -0
  105. package/types/graphql/index.d.ts +4 -0
  106. package/types/graphql/search-service.d.ts +92 -0
  107. package/types/graphql-request-client.d.ts +88 -0
  108. package/types/i18n/dictionary-service.d.ts +56 -0
  109. package/types/i18n/graphql-dictionary-service.d.ts +65 -0
  110. package/types/i18n/index.d.ts +2 -0
  111. package/types/index.d.ts +6 -0
  112. package/types/layout/content-styles.d.ts +18 -0
  113. package/types/layout/graphql-layout-service.d.ts +59 -0
  114. package/types/layout/index.d.ts +6 -0
  115. package/types/layout/layout-service.d.ts +20 -0
  116. package/types/layout/models.d.ts +140 -0
  117. package/types/layout/themes.d.ts +11 -0
  118. package/types/layout/utils.d.ts +17 -0
  119. package/types/media/index.d.ts +2 -0
  120. package/types/media/media-api.d.ts +69 -0
  121. package/types/models.d.ts +6 -0
  122. package/types/native-fetcher.d.ts +92 -0
  123. package/types/personalize/graphql-personalize-service.d.ts +77 -0
  124. package/types/personalize/index.d.ts +3 -0
  125. package/types/personalize/layout-personalizer.d.ts +25 -0
  126. package/types/personalize/utils.d.ts +53 -0
  127. package/types/site/graphql-error-pages-service.d.ts +55 -0
  128. package/types/site/graphql-redirects-service.d.ts +66 -0
  129. package/types/site/graphql-robots-service.d.ts +47 -0
  130. package/types/site/graphql-siteinfo-service.d.ts +69 -0
  131. package/types/site/graphql-sitemap-service.d.ts +53 -0
  132. package/types/site/index.d.ts +7 -0
  133. package/types/site/site-resolver.d.ts +27 -0
  134. package/types/site/utils.d.ts +24 -0
  135. package/types/utils/edit-frame.d.ts +76 -0
  136. package/types/utils/editing.d.ts +58 -0
  137. package/types/utils/env.d.ts +7 -0
  138. package/types/utils/index.d.ts +5 -0
  139. package/types/utils/is-server.d.ts +6 -0
  140. package/types/utils/timeout-promise.d.ts +18 -0
  141. package/types/utils/utils.d.ts +18 -0
  142. package/utils.d.ts +1 -0
  143. package/utils.js +1 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GraphQLRobotsService = void 0;
16
+ const constants_1 = require("../constants");
17
+ const debug_1 = __importDefault(require("../debug"));
18
+ // The default query for request robots.txt
19
+ const defaultQuery = /* GraphQL */ `
20
+ query RobotsQuery($siteName: String!) {
21
+ site {
22
+ siteInfo(site: $siteName) {
23
+ robots
24
+ }
25
+ }
26
+ }
27
+ `;
28
+ /**
29
+ * Service that fetch the robots.txt data using Sitecore's GraphQL API.
30
+ */
31
+ class GraphQLRobotsService {
32
+ /**
33
+ * Creates an instance of graphQL robots.txt service with the provided options
34
+ * @param {GraphQLRobotsServiceConfig} options instance
35
+ */
36
+ constructor(options) {
37
+ this.options = options;
38
+ this.graphQLClient = this.getGraphQLClient();
39
+ }
40
+ get query() {
41
+ return defaultQuery;
42
+ }
43
+ /**
44
+ * Fetch a data of robots.txt from API
45
+ * @returns text of robots.txt
46
+ * @throws {Error} if the siteName is empty.
47
+ */
48
+ fetchRobots() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ const siteName = this.options.siteName;
51
+ if (!siteName) {
52
+ throw new Error(constants_1.siteNameError);
53
+ }
54
+ const robotsResult = this.graphQLClient.request(this.query, {
55
+ siteName,
56
+ });
57
+ try {
58
+ return robotsResult.then((result) => {
59
+ var _a, _b;
60
+ return (_b = (_a = result === null || result === void 0 ? void 0 : result.site) === null || _a === void 0 ? void 0 : _a.siteInfo) === null || _b === void 0 ? void 0 : _b.robots;
61
+ });
62
+ }
63
+ catch (e) {
64
+ return Promise.reject(e);
65
+ }
66
+ });
67
+ }
68
+ /**
69
+ * Gets a GraphQL client that can make requests to the API.
70
+ * @returns {GraphQLClient} implementation
71
+ */
72
+ getGraphQLClient() {
73
+ if (!this.options.clientFactory) {
74
+ throw new Error('You should provide a clientFactory.');
75
+ }
76
+ return this.options.clientFactory({
77
+ debugger: debug_1.default.robots,
78
+ });
79
+ }
80
+ }
81
+ exports.GraphQLRobotsService = GraphQLRobotsService;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GraphQLSiteInfoService = void 0;
16
+ const debug_1 = __importDefault(require("../debug"));
17
+ const cache_client_1 = require("../cache-client");
18
+ const headlessSiteGroupingTemplate = 'E46F3AF2-39FA-4866-A157-7017C4B2A40C';
19
+ const sitecoreContentRootItem = '0DE95AE4-41AB-4D01-9EB0-67441B7C2450';
20
+ const defaultQuery = /* GraphQL */ `
21
+ query($pageSize: Int = 10, $after: String) {
22
+ search(
23
+ where: {
24
+ AND: [
25
+ { name: "_templates", value: "${headlessSiteGroupingTemplate}", operator: CONTAINS }
26
+ { name: "_path", value: "${sitecoreContentRootItem}", operator: CONTAINS }
27
+ ]
28
+ }
29
+ first: $pageSize
30
+ after: $after
31
+ ) {
32
+ pageInfo {
33
+ endCursor
34
+ hasNext
35
+ }
36
+ results {
37
+ ... on Item {
38
+ name: field(name: "SiteName") {
39
+ value
40
+ }
41
+ hostName: field(name: "Hostname") {
42
+ value
43
+ }
44
+ language: field(name: "Language") {
45
+ value
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ `;
52
+ class GraphQLSiteInfoService {
53
+ /**
54
+ * Creates an instance of graphQL service to retrieve site configuration list from Sitecore
55
+ * @param {GraphQLSiteInfoServiceConfig} config instance
56
+ */
57
+ constructor(config) {
58
+ this.config = config;
59
+ this.graphQLClient = this.getGraphQLClient();
60
+ this.cache = this.getCacheClient();
61
+ }
62
+ get query() {
63
+ return defaultQuery;
64
+ }
65
+ fetchSiteInfo() {
66
+ var _a, _b;
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const cachedResult = this.cache.getCacheValue(this.getCacheKey());
69
+ if (cachedResult) {
70
+ return cachedResult;
71
+ }
72
+ if (process.env.SITECORE) {
73
+ debug_1.default.multisite('Skipping site information fetch (building on XM Cloud)');
74
+ return [];
75
+ }
76
+ const results = [];
77
+ let hasNext = true;
78
+ let after = '';
79
+ while (hasNext) {
80
+ const response = yield this.graphQLClient.request(this.query, {
81
+ pageSize: this.config.pageSize,
82
+ after,
83
+ });
84
+ const result = (_b = (_a = response === null || response === void 0 ? void 0 : response.search) === null || _a === void 0 ? void 0 : _a.results) === null || _b === void 0 ? void 0 : _b.reduce((result, current) => {
85
+ result.push({
86
+ name: current.name.value,
87
+ hostName: current.hostName.value,
88
+ language: current.language.value,
89
+ });
90
+ return result;
91
+ }, []);
92
+ results.push(...result);
93
+ hasNext = response.search.pageInfo.hasNext;
94
+ after = response.search.pageInfo.endCursor;
95
+ }
96
+ this.cache.setCacheValue(this.getCacheKey(), results);
97
+ return results;
98
+ });
99
+ }
100
+ /**
101
+ * Gets cache client implementation
102
+ * Override this method if custom cache needs to be used
103
+ * @returns CacheClient instance
104
+ */
105
+ getCacheClient() {
106
+ var _a, _b;
107
+ return new cache_client_1.MemoryCacheClient({
108
+ cacheEnabled: (_a = this.config.cacheEnabled) !== null && _a !== void 0 ? _a : true,
109
+ cacheTimeout: (_b = this.config.cacheTimeout) !== null && _b !== void 0 ? _b : 10,
110
+ });
111
+ }
112
+ /**
113
+ * Gets a GraphQL client that can make requests to the API.
114
+ * @returns {GraphQLClient} implementation
115
+ */
116
+ getGraphQLClient() {
117
+ if (!this.config.clientFactory) {
118
+ throw new Error('You should provide a clientFactory.');
119
+ }
120
+ return this.config.clientFactory({
121
+ debugger: debug_1.default.multisite,
122
+ });
123
+ }
124
+ getCacheKey() {
125
+ return 'siteinfo-service-cache';
126
+ }
127
+ }
128
+ exports.GraphQLSiteInfoService = GraphQLSiteInfoService;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GraphQLSitemapXmlService = void 0;
16
+ const constants_1 = require("../constants");
17
+ const debug_1 = __importDefault(require("../debug"));
18
+ const PREFIX_NAME_SITEMAP = 'sitemap';
19
+ // The default query for request sitemaps
20
+ const defaultQuery = /* GraphQL */ `
21
+ query SitemapQuery($siteName: String!) {
22
+ site {
23
+ siteInfo(site: $siteName) {
24
+ sitemap
25
+ }
26
+ }
27
+ }
28
+ `;
29
+ /**
30
+ * Service that fetch the sitemaps data using Sitecore's GraphQL API.
31
+ */
32
+ class GraphQLSitemapXmlService {
33
+ /**
34
+ * Creates an instance of graphQL sitemaps service with the provided options
35
+ * @param {GraphQLSitemapXmlServiceConfig} options instance
36
+ */
37
+ constructor(options) {
38
+ this.options = options;
39
+ this.graphQLClient = this.getGraphQLClient();
40
+ }
41
+ get query() {
42
+ return defaultQuery;
43
+ }
44
+ /**
45
+ * Fetch list of sitemaps for the site
46
+ * @returns {string[]} list of sitemap paths
47
+ * @throws {Error} if the siteName is empty.
48
+ */
49
+ fetchSitemaps() {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const siteName = this.options.siteName;
52
+ if (!siteName) {
53
+ throw new Error(constants_1.siteNameError);
54
+ }
55
+ const sitemapResult = this.graphQLClient.request(this.query, {
56
+ siteName,
57
+ });
58
+ try {
59
+ return sitemapResult.then((result) => result.site.siteInfo.sitemap);
60
+ }
61
+ catch (e) {
62
+ return Promise.reject(e);
63
+ }
64
+ });
65
+ }
66
+ /**
67
+ * Get sitemap file path for sitemap id
68
+ * @param {string} id the sitemap id (can be empty for default 'sitemap.xml' file)
69
+ * @returns {string | undefined} the sitemap file path or undefined if one doesn't exist
70
+ */
71
+ getSitemap(id) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ const searchSitemap = `${PREFIX_NAME_SITEMAP}${id}.xml`;
74
+ const sitemaps = yield this.fetchSitemaps();
75
+ return sitemaps.find((sitemap) => sitemap.includes(searchSitemap));
76
+ });
77
+ }
78
+ /**
79
+ * Gets a GraphQL client that can make requests to the API.
80
+ * @returns {GraphQLClient} implementation
81
+ */
82
+ getGraphQLClient() {
83
+ if (!this.options.clientFactory) {
84
+ throw new Error('You should provide a clientFactory.');
85
+ }
86
+ return this.options.clientFactory({
87
+ debugger: debug_1.default.sitemap,
88
+ });
89
+ }
90
+ }
91
+ exports.GraphQLSitemapXmlService = GraphQLSitemapXmlService;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SiteResolver = exports.normalizeSiteRewrite = exports.getSiteRewriteData = exports.getSiteRewrite = exports.GraphQLSiteInfoService = exports.GraphQLErrorPagesService = exports.GraphQLSitemapXmlService = exports.GraphQLRedirectsService = exports.REDIRECT_TYPE_SERVER_TRANSFER = exports.REDIRECT_TYPE_302 = exports.REDIRECT_TYPE_301 = exports.GraphQLRobotsService = void 0;
4
+ var graphql_robots_service_1 = require("./graphql-robots-service");
5
+ Object.defineProperty(exports, "GraphQLRobotsService", { enumerable: true, get: function () { return graphql_robots_service_1.GraphQLRobotsService; } });
6
+ var graphql_redirects_service_1 = require("./graphql-redirects-service");
7
+ Object.defineProperty(exports, "REDIRECT_TYPE_301", { enumerable: true, get: function () { return graphql_redirects_service_1.REDIRECT_TYPE_301; } });
8
+ Object.defineProperty(exports, "REDIRECT_TYPE_302", { enumerable: true, get: function () { return graphql_redirects_service_1.REDIRECT_TYPE_302; } });
9
+ Object.defineProperty(exports, "REDIRECT_TYPE_SERVER_TRANSFER", { enumerable: true, get: function () { return graphql_redirects_service_1.REDIRECT_TYPE_SERVER_TRANSFER; } });
10
+ Object.defineProperty(exports, "GraphQLRedirectsService", { enumerable: true, get: function () { return graphql_redirects_service_1.GraphQLRedirectsService; } });
11
+ var graphql_sitemap_service_1 = require("./graphql-sitemap-service");
12
+ Object.defineProperty(exports, "GraphQLSitemapXmlService", { enumerable: true, get: function () { return graphql_sitemap_service_1.GraphQLSitemapXmlService; } });
13
+ var graphql_error_pages_service_1 = require("./graphql-error-pages-service");
14
+ Object.defineProperty(exports, "GraphQLErrorPagesService", { enumerable: true, get: function () { return graphql_error_pages_service_1.GraphQLErrorPagesService; } });
15
+ var graphql_siteinfo_service_1 = require("./graphql-siteinfo-service");
16
+ Object.defineProperty(exports, "GraphQLSiteInfoService", { enumerable: true, get: function () { return graphql_siteinfo_service_1.GraphQLSiteInfoService; } });
17
+ var utils_1 = require("./utils");
18
+ Object.defineProperty(exports, "getSiteRewrite", { enumerable: true, get: function () { return utils_1.getSiteRewrite; } });
19
+ Object.defineProperty(exports, "getSiteRewriteData", { enumerable: true, get: function () { return utils_1.getSiteRewriteData; } });
20
+ Object.defineProperty(exports, "normalizeSiteRewrite", { enumerable: true, get: function () { return utils_1.normalizeSiteRewrite; } });
21
+ var site_resolver_1 = require("./site-resolver");
22
+ Object.defineProperty(exports, "SiteResolver", { enumerable: true, get: function () { return site_resolver_1.SiteResolver; } });
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SiteResolver = void 0;
4
+ // Delimiters for multi-value hostnames
5
+ const DELIMITERS = /\||,|;/g;
6
+ /**
7
+ * Resolves site based on the provided host or site name
8
+ */
9
+ class SiteResolver {
10
+ /**
11
+ * @param {SiteInfo[]} sites Array of sites to be used in resolution
12
+ */
13
+ constructor(sites) {
14
+ this.sites = sites;
15
+ /**
16
+ * Resolve site by host name
17
+ * @param {string} hostName the host name
18
+ * @returns {SiteInfo} the resolved site
19
+ * @throws {Error} if a matching site is not found
20
+ */
21
+ this.getByHost = (hostName) => {
22
+ for (const [hostname, site] of this.getHostMap()) {
23
+ if (this.matchesPattern(hostName, hostname)) {
24
+ return site;
25
+ }
26
+ }
27
+ throw new Error(`Could not resolve site for host ${hostName}`);
28
+ };
29
+ /**
30
+ * Resolve site by site name
31
+ * @param {string} siteName the site name
32
+ * @returns {SiteInfo} the resolved site
33
+ * @throws {Error} if a matching site is not found
34
+ */
35
+ this.getByName = (siteName) => {
36
+ const siteInfo = this.sites.find((info) => info.name.toLocaleLowerCase() === siteName.toLocaleLowerCase());
37
+ if (!siteInfo) {
38
+ throw new Error(`Could not resolve site for name ${siteName}`);
39
+ }
40
+ return siteInfo;
41
+ };
42
+ this.getHostMap = () => {
43
+ const map = new Map();
44
+ // First collect unique hostnames.
45
+ // For sites with same hostname defined, priority is given to the first encountered.
46
+ this.sites.forEach((site) => {
47
+ const hostnames = site.hostName
48
+ .replace(/\s/g, '')
49
+ .toLocaleLowerCase()
50
+ .split(DELIMITERS);
51
+ hostnames.forEach((hostname) => {
52
+ if (!map.has(hostname)) {
53
+ map.set(hostname, site);
54
+ }
55
+ });
56
+ });
57
+ // Now order by specificity.
58
+ // This equivalates to sorting from longest to shortest with the assumption
59
+ // that your match is less specific as wildcards are introduced.
60
+ // E.g. order.eu.site.com → *.eu.site.com → *.site.com → *
61
+ // In case of a tie (e.g. *.site.com vs i.site.com), prefer one with less wildcards.
62
+ return new Map(Array.from(map).sort((a, b) => {
63
+ if (a[0].length === b[0].length) {
64
+ return (a[0].match(/\*/g) || []).length - (b[0].match(/\*/g) || []).length;
65
+ }
66
+ return b[0].length - a[0].length;
67
+ }));
68
+ };
69
+ }
70
+ // b[0].match(/\*/g) || []).length
71
+ matchesPattern(hostname, pattern) {
72
+ // dots should be treated as chars
73
+ // stars should be treated as wildcards
74
+ const regExpPattern = pattern.replace(/\./g, '\\.').replace(/\*/g, '.*');
75
+ const regExp = new RegExp(`^${regExpPattern}$`, 'gi');
76
+ return !!hostname.match(regExp);
77
+ }
78
+ }
79
+ exports.SiteResolver = SiteResolver;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeSiteRewrite = exports.getSiteRewriteData = exports.getSiteRewrite = exports.SITE_PREFIX = void 0;
4
+ exports.SITE_PREFIX = '_site_';
5
+ /**
6
+ * Get a site rewrite path for given pathname
7
+ * @param {string} pathname the pathname
8
+ * @param {SiteRewriteData} data the site data to include in the rewrite
9
+ * @returns {string} the rewrite path
10
+ */
11
+ function getSiteRewrite(pathname, data) {
12
+ const path = pathname.startsWith('/') ? pathname : '/' + pathname;
13
+ return `/${exports.SITE_PREFIX}${data.siteName}${path}`;
14
+ }
15
+ exports.getSiteRewrite = getSiteRewrite;
16
+ /**
17
+ * Get site data from the rewrite path
18
+ * @param {string} pathname the pathname
19
+ * @param {string} defaultSiteName the default site name
20
+ * @returns {SiteRewriteData} the site data from the rewrite
21
+ */
22
+ function getSiteRewriteData(pathname, defaultSiteName) {
23
+ const data = {
24
+ siteName: defaultSiteName,
25
+ };
26
+ const path = pathname.endsWith('/') ? pathname : pathname + '/';
27
+ const result = path.match(`${exports.SITE_PREFIX}(.*?)\\/`);
28
+ if (result && result[1] !== '') {
29
+ data.siteName = result[1];
30
+ }
31
+ return data;
32
+ }
33
+ exports.getSiteRewriteData = getSiteRewriteData;
34
+ /**
35
+ * Normalize a site rewrite path (remove site data)
36
+ * @param {string} pathname the pathname
37
+ * @returns {string} the pathname with site data removed
38
+ */
39
+ function normalizeSiteRewrite(pathname) {
40
+ const result = pathname.match(`${exports.SITE_PREFIX}.*?(?:\\/|$)`);
41
+ return result === null ? pathname : pathname.replace(result[0], '');
42
+ }
43
+ exports.normalizeSiteRewrite = normalizeSiteRewrite;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commandBuilder = exports.mapButtonToCommand = exports.DefaultEditFrameButtons = exports.DefaultEditFrameButton = exports.DefaultEditFrameButtonIds = void 0;
4
+ exports.DefaultEditFrameButtonIds = {
5
+ edit: '{70C4EED5-D4CD-4D7D-9763-80C42504F5E7}',
6
+ };
7
+ exports.DefaultEditFrameButton = {
8
+ insert: {
9
+ header: 'Insert New',
10
+ icon: '/~/icon/Office/16x16/insert_from_template.png',
11
+ click: 'webedit:new',
12
+ tooltip: 'Insert a new item',
13
+ },
14
+ editRelatedItem: {
15
+ header: 'Edit the related item',
16
+ icon: '/~/icon/Office/16x16/cubes.png',
17
+ click: 'webedit:open',
18
+ tooltip: 'Edit the related item in the Content Editor.',
19
+ },
20
+ edit: {
21
+ header: 'Edit Item',
22
+ icon: '/~/icon/people/16x16/cubes_blue.png',
23
+ fields: ['Title', 'Text'],
24
+ tooltip: 'Edit the item fields.',
25
+ },
26
+ };
27
+ exports.DefaultEditFrameButtons = [
28
+ exports.DefaultEditFrameButton.editRelatedItem,
29
+ exports.DefaultEditFrameButton.insert,
30
+ exports.DefaultEditFrameButton.edit,
31
+ ];
32
+ /**
33
+ * @param {WebEditButton | FieldEditButton} button the button to determine the type of
34
+ */
35
+ function isWebEditButton(button) {
36
+ return button.click !== undefined;
37
+ }
38
+ /**
39
+ * Map the edit button types to chrome data
40
+ * @param {EditButtonTypes } button the edit button to build a ChromeCommand for
41
+ * @param {string} itemId the ID of the item the EditFrame is associated with
42
+ * @param {Record<string, string | number | boolean | undefined | null>} frameParameters additional parameters passed to the EditFrame
43
+ */
44
+ function mapButtonToCommand(button, itemId, frameParameters) {
45
+ if (button === '|' || button.isDivider) {
46
+ return {
47
+ click: 'chrome:dummy',
48
+ header: 'Separator',
49
+ icon: '',
50
+ isDivider: true,
51
+ tooltip: null,
52
+ type: 'separator',
53
+ };
54
+ }
55
+ else if (isWebEditButton(button)) {
56
+ return commandBuilder(button, itemId, frameParameters);
57
+ }
58
+ else {
59
+ const fieldsString = button.fields.join('|');
60
+ const editButton = Object.assign({ click: `webedit:fieldeditor(command=${exports.DefaultEditFrameButtonIds.edit},fields=${fieldsString})` }, button);
61
+ return commandBuilder(editButton, itemId, frameParameters);
62
+ }
63
+ }
64
+ exports.mapButtonToCommand = mapButtonToCommand;
65
+ /**
66
+ * Build a ChromeCommand from a web edit button. Merging the parameters from the button, frame and id
67
+ * @param {WebEditButton } button the web edit button to build a ChromeCommand for
68
+ * @param {string} itemId the ID of the item the EditFrame is associated with
69
+ * @param {Record<string, string>} frameParameters additional parameters passed to the EditFrame
70
+ */
71
+ function commandBuilder(button, itemId, frameParameters) {
72
+ if (!button.click) {
73
+ return Object.assign({ isDivider: false, type: button.type || null, header: button.header || '', icon: button.icon || '', tooltip: button.tooltip || '' }, button);
74
+ }
75
+ else if (button.click.startsWith('javascript:') || button.click.startsWith('chrome:')) {
76
+ return Object.assign({ isDivider: false, type: button.type || null, header: button.header || '', icon: button.icon || '', tooltip: button.tooltip || '' }, button);
77
+ }
78
+ else {
79
+ if (!itemId) {
80
+ return Object.assign({ isDivider: false, type: button.type || null, header: button.header || '', icon: button.icon || '', tooltip: button.tooltip || '' }, button);
81
+ }
82
+ else {
83
+ let message = button.click;
84
+ let parameters = {};
85
+ // Extract any parameters already in the command
86
+ const length = button.click.indexOf('(');
87
+ if (length >= 0) {
88
+ const end = button.click.indexOf(')');
89
+ if (end < 0) {
90
+ throw new Error('Message with arguments must end with ")".');
91
+ }
92
+ parameters = button.click
93
+ .substring(length + 1, end)
94
+ .split(',')
95
+ .map((_) => _.trim())
96
+ .reduce((previous, current) => {
97
+ const parts = current.split('=');
98
+ if (parts.length < 2) {
99
+ previous[parts[0]] = '';
100
+ }
101
+ else {
102
+ previous[parts[0]] = parts[1];
103
+ }
104
+ return previous;
105
+ }, {});
106
+ message = button.click.substring(0, length);
107
+ }
108
+ parameters.id = itemId;
109
+ if (button.parameters) {
110
+ Object.keys(button.parameters).forEach((_) => {
111
+ var _a;
112
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
113
+ parameters[_] = ((_a = button.parameters[_]) === null || _a === void 0 ? void 0 : _a.toString()) || '';
114
+ });
115
+ }
116
+ if (frameParameters) {
117
+ Object.keys(frameParameters).forEach((_) => {
118
+ var _a;
119
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
120
+ parameters[_] = ((_a = frameParameters[_]) === null || _a === void 0 ? void 0 : _a.toString()) || '';
121
+ });
122
+ }
123
+ const parameterString = Object.keys(parameters)
124
+ .map((_) => `${_}=${parameters[_]}`)
125
+ .join(', ');
126
+ const click = `${message}(${parameterString})`;
127
+ return {
128
+ isDivider: false,
129
+ click: `javascript:Sitecore.PageModes.PageEditor.postRequest('${click}',null,false)`,
130
+ header: button.header || '',
131
+ icon: button.icon || '',
132
+ tooltip: button.tooltip || '',
133
+ type: button.type || null,
134
+ };
135
+ }
136
+ }
137
+ }
138
+ exports.commandBuilder = commandBuilder;