@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,125 @@
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.GraphQLDictionaryService = exports.queryError = void 0;
16
+ const constants_1 = require("../constants");
17
+ const dictionary_service_1 = require("./dictionary-service");
18
+ const graphql_1 = require("../graphql");
19
+ const debug_1 = __importDefault(require("../debug"));
20
+ /** @private */
21
+ exports.queryError = 'Valid value for rootItemId not provided and failed to auto-resolve app root item.';
22
+ const query = /* GraphQL */ `
23
+ query DictionarySearch(
24
+ $rootItemId: String!
25
+ $language: String!
26
+ $templates: String!
27
+ $pageSize: Int = 10
28
+ $after: String
29
+ ) {
30
+ search(
31
+ where: {
32
+ AND: [
33
+ { name: "_path", value: $rootItemId, operator: CONTAINS }
34
+ { name: "_language", value: $language }
35
+ { name: "_templates", value: $templates, operator: CONTAINS }
36
+ ]
37
+ }
38
+ first: $pageSize
39
+ after: $after
40
+ ) {
41
+ total
42
+ pageInfo {
43
+ endCursor
44
+ hasNext
45
+ }
46
+ results {
47
+ key: field(name: "Key") {
48
+ value
49
+ }
50
+ phrase: field(name: "Phrase") {
51
+ value
52
+ }
53
+ }
54
+ }
55
+ }
56
+ `;
57
+ /**
58
+ * Service that fetch dictionary data using Sitecore's GraphQL API.
59
+ * @augments DictionaryServiceBase
60
+ * @mixes SearchQueryService<DictionaryQueryResult>
61
+ */
62
+ class GraphQLDictionaryService extends dictionary_service_1.DictionaryServiceBase {
63
+ /**
64
+ * Creates an instance of graphQL dictionary service with the provided options
65
+ * @param {GraphQLDictionaryService} options instance
66
+ */
67
+ constructor(options) {
68
+ super(options);
69
+ this.options = options;
70
+ this.graphQLClient = this.getGraphQLClient();
71
+ this.searchService = new graphql_1.SearchQueryService(this.graphQLClient);
72
+ }
73
+ /**
74
+ * Fetches dictionary data for internalization.
75
+ * @param {string} language the language to fetch
76
+ * @default query (@see query)
77
+ * @returns {Promise<DictionaryPhrases>} dictionary phrases
78
+ * @throws {Error} if the app root was not found for the specified site and language.
79
+ */
80
+ fetchDictionaryData(language) {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ const cacheKey = this.options.siteName + language;
83
+ const cachedValue = this.getCacheValue(cacheKey);
84
+ if (cachedValue) {
85
+ debug_1.default.dictionary('using cached dictionary data for %s %s', language, this.options.siteName);
86
+ return cachedValue;
87
+ }
88
+ debug_1.default.dictionary('fetching site root for %s %s', language, this.options.siteName);
89
+ // If the caller does not specify a root item ID, then we try to figure it out
90
+ const rootItemId = this.options.rootItemId ||
91
+ (yield graphql_1.getAppRootId(this.graphQLClient, this.options.siteName, language, this.options.jssAppTemplateId));
92
+ if (!rootItemId) {
93
+ throw new Error(exports.queryError);
94
+ }
95
+ debug_1.default.dictionary('fetching dictionary data for %s %s', language, this.options.siteName);
96
+ const phrases = {};
97
+ yield this.searchService
98
+ .fetch(query, {
99
+ rootItemId,
100
+ language,
101
+ templates: this.options.dictionaryEntryTemplateId || constants_1.SitecoreTemplateId.DictionaryEntry,
102
+ pageSize: this.options.pageSize,
103
+ })
104
+ .then((results) => {
105
+ results.forEach((item) => (phrases[item.key.value] = item.phrase.value));
106
+ });
107
+ this.setCacheValue(cacheKey, phrases);
108
+ return phrases;
109
+ });
110
+ }
111
+ /**
112
+ * Gets a GraphQL client that can make requests to the API.
113
+ * @returns {GraphQLClient} implementation
114
+ */
115
+ getGraphQLClient() {
116
+ if (!this.options.clientFactory) {
117
+ throw new Error('You should provide a clientFactory.');
118
+ }
119
+ return this.options.clientFactory({
120
+ debugger: debug_1.default.dictionary,
121
+ retries: this.options.retries,
122
+ });
123
+ }
124
+ }
125
+ exports.GraphQLDictionaryService = GraphQLDictionaryService;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphQLDictionaryService = exports.DictionaryServiceBase = void 0;
4
+ var dictionary_service_1 = require("./dictionary-service");
5
+ Object.defineProperty(exports, "DictionaryServiceBase", { enumerable: true, get: function () { return dictionary_service_1.DictionaryServiceBase; } });
6
+ var graphql_dictionary_service_1 = require("./graphql-dictionary-service");
7
+ Object.defineProperty(exports, "GraphQLDictionaryService", { enumerable: true, get: function () { return graphql_dictionary_service_1.GraphQLDictionaryService; } });
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ // NOTE: all imports are now named as to not make breaking changes
3
+ // and to keep react-native working with cjs modules.
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
7
+ }) : (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ o[k2] = m[k];
10
+ }));
11
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
12
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
13
+ }) : function(o, v) {
14
+ o["default"] = v;
15
+ });
16
+ var __importStar = (this && this.__importStar) || function (mod) {
17
+ if (mod && mod.__esModule) return mod;
18
+ var result = {};
19
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
20
+ __setModuleDefault(result, mod);
21
+ return result;
22
+ };
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.constants = exports.NativeDataFetcher = exports.GraphQLRequestClient = exports.enableDebug = exports.debug = void 0;
28
+ const constants = __importStar(require("./constants"));
29
+ exports.constants = constants;
30
+ var debug_1 = require("./debug");
31
+ Object.defineProperty(exports, "debug", { enumerable: true, get: function () { return __importDefault(debug_1).default; } });
32
+ Object.defineProperty(exports, "enableDebug", { enumerable: true, get: function () { return debug_1.enableDebug; } });
33
+ var graphql_request_client_1 = require("./graphql-request-client");
34
+ Object.defineProperty(exports, "GraphQLRequestClient", { enumerable: true, get: function () { return graphql_request_client_1.GraphQLRequestClient; } });
35
+ var native_fetcher_1 = require("./native-fetcher");
36
+ Object.defineProperty(exports, "NativeDataFetcher", { enumerable: true, get: function () { return native_fetcher_1.NativeDataFetcher; } });
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.traverseComponent = exports.traverseField = exports.traversePlaceholder = exports.getContentStylesheetUrl = exports.getContentStylesheetLink = void 0;
4
+ const constants_1 = require("../constants");
5
+ /**
6
+ * Regular expression to check if the content styles are used in the field value
7
+ */
8
+ const CLASS_REGEXP = /class=".*(\bck-content\b).*"/g;
9
+ /**
10
+ * Get the content styles link to be loaded from the Sitecore Edge Platform
11
+ * @param {LayoutServiceData} layoutData Layout service data
12
+ * @param {string} sitecoreEdgeContextId Sitecore Edge Context ID
13
+ * @param {string} [sitecoreEdgeUrl] Sitecore Edge Platform URL. Default is https://edge-platform.sitecorecloud.io
14
+ * @returns {HTMLLink | null} content styles link, null if no styles are used in layout
15
+ */
16
+ const getContentStylesheetLink = (layoutData, sitecoreEdgeContextId, sitecoreEdgeUrl = constants_1.SITECORE_EDGE_URL_DEFAULT) => {
17
+ if (!layoutData.sitecore.route)
18
+ return null;
19
+ const config = { loadStyles: false };
20
+ exports.traverseComponent(layoutData.sitecore.route, config);
21
+ if (!config.loadStyles)
22
+ return null;
23
+ return {
24
+ href: exports.getContentStylesheetUrl(sitecoreEdgeContextId, sitecoreEdgeUrl),
25
+ rel: 'stylesheet',
26
+ };
27
+ };
28
+ exports.getContentStylesheetLink = getContentStylesheetLink;
29
+ const getContentStylesheetUrl = (sitecoreEdgeContextId, sitecoreEdgeUrl = constants_1.SITECORE_EDGE_URL_DEFAULT) => `${sitecoreEdgeUrl}/v1/files/pages/styles/content-styles.css?sitecoreContextId=${sitecoreEdgeContextId}`;
30
+ exports.getContentStylesheetUrl = getContentStylesheetUrl;
31
+ const traversePlaceholder = (components, config) => {
32
+ if (config.loadStyles)
33
+ return;
34
+ components.forEach((component) => {
35
+ exports.traverseComponent(component, config);
36
+ });
37
+ };
38
+ exports.traversePlaceholder = traversePlaceholder;
39
+ const traverseField = (field, config) => {
40
+ if (!field || config.loadStyles)
41
+ return;
42
+ if ('editable' in field && field.editable) {
43
+ config.loadStyles = CLASS_REGEXP.test(field.editable);
44
+ }
45
+ else if ('value' in field && typeof field.value === 'string') {
46
+ config.loadStyles = CLASS_REGEXP.test(field.value);
47
+ }
48
+ else if ('fields' in field) {
49
+ Object.values(field.fields).forEach((field) => {
50
+ exports.traverseField(field, config);
51
+ });
52
+ }
53
+ else if (Array.isArray(field)) {
54
+ field.forEach((field) => {
55
+ exports.traverseField(field, config);
56
+ });
57
+ }
58
+ };
59
+ exports.traverseField = traverseField;
60
+ const traverseComponent = (component, config) => {
61
+ if (config.loadStyles)
62
+ return;
63
+ if ('fields' in component && component.fields) {
64
+ Object.values(component.fields).forEach((field) => {
65
+ exports.traverseField(field, config);
66
+ });
67
+ }
68
+ const placeholders = component.placeholders || {};
69
+ Object.keys(placeholders).forEach((placeholder) => {
70
+ exports.traversePlaceholder(placeholders[placeholder], config);
71
+ });
72
+ };
73
+ exports.traverseComponent = traverseComponent;
@@ -0,0 +1,84 @@
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.GraphQLLayoutService = void 0;
16
+ const layout_service_1 = require("./layout-service");
17
+ const debug_1 = __importDefault(require("../debug"));
18
+ /**
19
+ * Service that fetch layout data using Sitecore's GraphQL API.
20
+ * @augments LayoutServiceBase
21
+ * @mixes GraphQLRequestClient
22
+ */
23
+ class GraphQLLayoutService extends layout_service_1.LayoutServiceBase {
24
+ /**
25
+ * Fetch layout data using the Sitecore GraphQL endpoint.
26
+ * @param {GraphQLLayoutServiceConfig} serviceConfig configuration
27
+ */
28
+ constructor(serviceConfig) {
29
+ super();
30
+ this.serviceConfig = serviceConfig;
31
+ this.graphQLClient = this.getGraphQLClient();
32
+ }
33
+ /**
34
+ * Fetch layout data for an item.
35
+ * @param {string} itemPath item path to fetch layout data for.
36
+ * @param {string} [language] the language to fetch layout data for.
37
+ * @returns {Promise<LayoutServiceData>} layout service data
38
+ */
39
+ fetchLayoutData(itemPath, language) {
40
+ var _a, _b;
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ const query = this.getLayoutQuery(itemPath, language);
43
+ debug_1.default.layout('fetching layout data for %s %s %s', itemPath, language, this.serviceConfig.siteName);
44
+ const data = yield this.graphQLClient.request(query);
45
+ // If `rendered` is empty -> not found
46
+ return (((_b = (_a = data === null || data === void 0 ? void 0 : data.layout) === null || _a === void 0 ? void 0 : _a.item) === null || _b === void 0 ? void 0 : _b.rendered) || {
47
+ sitecore: { context: { pageEditing: false, language }, route: null },
48
+ });
49
+ });
50
+ }
51
+ /**
52
+ * Gets a GraphQL client that can make requests to the API.
53
+ * @returns {GraphQLClient} implementation
54
+ */
55
+ getGraphQLClient() {
56
+ if (!this.serviceConfig.clientFactory) {
57
+ throw new Error('You should provide a clientFactory.');
58
+ }
59
+ return this.serviceConfig.clientFactory({
60
+ debugger: debug_1.default.layout,
61
+ retries: this.serviceConfig.retries,
62
+ });
63
+ }
64
+ /**
65
+ * Returns GraphQL Layout query
66
+ * @param {string} itemPath page route
67
+ * @param {string} [language] language
68
+ * @returns {string} GraphQL query
69
+ */
70
+ getLayoutQuery(itemPath, language) {
71
+ const languageVariable = language ? `, language:"${language}"` : '';
72
+ const layoutQuery = this.serviceConfig.formatLayoutQuery
73
+ ? this.serviceConfig.formatLayoutQuery(this.serviceConfig.siteName, itemPath, language)
74
+ : `layout(site:"${this.serviceConfig.siteName}", routePath:"${itemPath}"${languageVariable})`;
75
+ return `query {
76
+ ${layoutQuery}{
77
+ item {
78
+ rendered
79
+ }
80
+ }
81
+ }`;
82
+ }
83
+ }
84
+ exports.GraphQLLayoutService = GraphQLLayoutService;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getComponentLibraryStylesheetLinks = exports.GraphQLLayoutService = exports.getContentStylesheetLink = exports.getChildPlaceholder = exports.getFieldValue = exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = exports.RenderingType = exports.LayoutServicePageState = void 0;
4
+ // layout
5
+ var models_1 = require("./models");
6
+ Object.defineProperty(exports, "LayoutServicePageState", { enumerable: true, get: function () { return models_1.LayoutServicePageState; } });
7
+ Object.defineProperty(exports, "RenderingType", { enumerable: true, get: function () { return models_1.RenderingType; } });
8
+ Object.defineProperty(exports, "EDITING_COMPONENT_PLACEHOLDER", { enumerable: true, get: function () { return models_1.EDITING_COMPONENT_PLACEHOLDER; } });
9
+ Object.defineProperty(exports, "EDITING_COMPONENT_ID", { enumerable: true, get: function () { return models_1.EDITING_COMPONENT_ID; } });
10
+ var utils_1 = require("./utils");
11
+ Object.defineProperty(exports, "getFieldValue", { enumerable: true, get: function () { return utils_1.getFieldValue; } });
12
+ Object.defineProperty(exports, "getChildPlaceholder", { enumerable: true, get: function () { return utils_1.getChildPlaceholder; } });
13
+ var content_styles_1 = require("./content-styles");
14
+ Object.defineProperty(exports, "getContentStylesheetLink", { enumerable: true, get: function () { return content_styles_1.getContentStylesheetLink; } });
15
+ var graphql_layout_service_1 = require("./graphql-layout-service");
16
+ Object.defineProperty(exports, "GraphQLLayoutService", { enumerable: true, get: function () { return graphql_layout_service_1.GraphQLLayoutService; } });
17
+ var themes_1 = require("./themes");
18
+ Object.defineProperty(exports, "getComponentLibraryStylesheetLinks", { enumerable: true, get: function () { return themes_1.getComponentLibraryStylesheetLinks; } });
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LayoutServiceBase = void 0;
4
+ /**
5
+ * Base abstraction to implement custom layout service
6
+ */
7
+ class LayoutServiceBase {
8
+ }
9
+ exports.LayoutServiceBase = LayoutServiceBase;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderingType = exports.LayoutServicePageState = exports.EDITING_COMPONENT_ID = exports.EDITING_COMPONENT_PLACEHOLDER = void 0;
4
+ /**
5
+ * Static placeholder name used for component rendering
6
+ */
7
+ exports.EDITING_COMPONENT_PLACEHOLDER = 'editing-componentmode-placeholder';
8
+ /**
9
+ * Id of wrapper for component rendering
10
+ */
11
+ exports.EDITING_COMPONENT_ID = 'editing-component';
12
+ /**
13
+ * Layout Service page state enum
14
+ */
15
+ var LayoutServicePageState;
16
+ (function (LayoutServicePageState) {
17
+ LayoutServicePageState["Preview"] = "preview";
18
+ LayoutServicePageState["Edit"] = "edit";
19
+ LayoutServicePageState["Normal"] = "normal";
20
+ })(LayoutServicePageState = exports.LayoutServicePageState || (exports.LayoutServicePageState = {}));
21
+ /**
22
+ * Editing rendering type
23
+ */
24
+ var RenderingType;
25
+ (function (RenderingType) {
26
+ RenderingType["Component"] = "component";
27
+ })(RenderingType = exports.RenderingType || (exports.RenderingType = {}));
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStylesheetUrl = exports.getComponentLibraryStylesheetLinks = void 0;
4
+ const _1 = require(".");
5
+ const constants_1 = require("../constants");
6
+ /**
7
+ * Pattern for library ids
8
+ * @example -library--foo
9
+ */
10
+ const STYLES_LIBRARY_ID_REGEX = /-library--([^\s]+)/;
11
+ /**
12
+ * Walks through rendering tree and returns list of links of all FEAAS, BYOC or SXA Component Library Stylesheets that are used
13
+ * @param {LayoutServiceData} layoutData Layout service data
14
+ * @param {string} sitecoreEdgeContextId Sitecore Edge Context ID
15
+ * @param {string} [sitecoreEdgeUrl] Sitecore Edge Platform URL. Default is https://edge-platform.sitecorecloud.io
16
+ * @returns {HTMLLink[]} library stylesheet links
17
+ */
18
+ function getComponentLibraryStylesheetLinks(layoutData, sitecoreEdgeContextId, sitecoreEdgeUrl = constants_1.SITECORE_EDGE_URL_DEFAULT) {
19
+ const ids = new Set();
20
+ if (!layoutData.sitecore.route)
21
+ return [];
22
+ traverseComponent(layoutData.sitecore.route, ids);
23
+ return [...ids].map((id) => ({
24
+ href: exports.getStylesheetUrl(id, sitecoreEdgeContextId, sitecoreEdgeUrl),
25
+ rel: 'stylesheet',
26
+ }));
27
+ }
28
+ exports.getComponentLibraryStylesheetLinks = getComponentLibraryStylesheetLinks;
29
+ const getStylesheetUrl = (id, sitecoreEdgeContextId, sitecoreEdgeUrl = constants_1.SITECORE_EDGE_URL_DEFAULT) => {
30
+ return `${sitecoreEdgeUrl}/v1/files/components/styles/${id}.css?sitecoreContextId=${sitecoreEdgeContextId}`;
31
+ };
32
+ exports.getStylesheetUrl = getStylesheetUrl;
33
+ /**
34
+ * Traverse placeholder and components to add library ids
35
+ * @param {Array<ComponentRendering | HtmlElementRendering>} components
36
+ * @param {Set<string>} ids library ids
37
+ */
38
+ const traversePlaceholder = (components, ids) => {
39
+ components.map((component) => {
40
+ const rendering = component;
41
+ return traverseComponent(rendering, ids);
42
+ });
43
+ };
44
+ /**
45
+ * Traverse component and children to add library ids
46
+ * @param {RouteData | ComponentRendering | HtmlElementRendering} component component data
47
+ * @param {Set<string>} ids library ids
48
+ */
49
+ const traverseComponent = (component, ids) => {
50
+ var _a, _b, _c, _d, _e, _f, _g;
51
+ let libraryId = undefined;
52
+ if ('params' in component && component.params) {
53
+ // LibraryID in css class name takes precedence over LibraryId attribute
54
+ libraryId =
55
+ ((_b = (_a = component.params.CSSStyles) === null || _a === void 0 ? void 0 : _a.match(STYLES_LIBRARY_ID_REGEX)) === null || _b === void 0 ? void 0 : _b[1]) ||
56
+ ((_d = (_c = component.params.Styles) === null || _c === void 0 ? void 0 : _c.match(STYLES_LIBRARY_ID_REGEX)) === null || _d === void 0 ? void 0 : _d[1]) ||
57
+ component.params.LibraryId ||
58
+ undefined;
59
+ }
60
+ // if params are empty we try to fall back to data source or attributes
61
+ if (!libraryId && 'fields' in component && component.fields) {
62
+ libraryId =
63
+ ((_e = _1.getFieldValue(component.fields, 'CSSStyles', '').match(STYLES_LIBRARY_ID_REGEX)) === null || _e === void 0 ? void 0 : _e[1]) ||
64
+ ((_f = _1.getFieldValue(component.fields, 'Styles', '').match(STYLES_LIBRARY_ID_REGEX)) === null || _f === void 0 ? void 0 : _f[1]) ||
65
+ _1.getFieldValue(component.fields, 'LibraryId', '') ||
66
+ undefined;
67
+ }
68
+ // HTMLRendering its class attribute
69
+ if (!libraryId && 'attributes' in component && typeof component.attributes.class === 'string') {
70
+ libraryId = (_g = component.attributes.class.match(STYLES_LIBRARY_ID_REGEX)) === null || _g === void 0 ? void 0 : _g[1];
71
+ }
72
+ if (libraryId) {
73
+ ids.add(libraryId);
74
+ }
75
+ const placeholders = component.placeholders || {};
76
+ Object.keys(placeholders).forEach((placeholder) => {
77
+ traversePlaceholder(placeholders[placeholder], ids);
78
+ });
79
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getChildPlaceholder = exports.getFieldValue = void 0;
4
+ /**
5
+ * @param {ComponentRendering | Fields} renderingOrFields the rendering or fields object to extract the field from
6
+ * @param {string} fieldName the name of the field to extract
7
+ * @param {T} [defaultValue] the default value to return if the field is not defined
8
+ * @returns {Field | T} the field value or the default value if the field is not defined
9
+ */
10
+ // eslint-disable-next-line no-redeclare
11
+ function getFieldValue(renderingOrFields, fieldName, defaultValue) {
12
+ if (!renderingOrFields || !fieldName) {
13
+ return defaultValue;
14
+ }
15
+ const fields = renderingOrFields;
16
+ const field = fields[fieldName];
17
+ if (field && typeof field.value !== 'undefined') {
18
+ return field.value;
19
+ }
20
+ const rendering = renderingOrFields;
21
+ if (!rendering.fields ||
22
+ !rendering.fields[fieldName] ||
23
+ typeof rendering.fields[fieldName].value === 'undefined') {
24
+ return defaultValue;
25
+ }
26
+ return rendering.fields[fieldName].value;
27
+ }
28
+ exports.getFieldValue = getFieldValue;
29
+ /**
30
+ * Gets rendering definitions in a given child placeholder under a current rendering.
31
+ * @param {ComponentRendering} rendering
32
+ * @param {string} placeholderName
33
+ * @returns {Array<ComponentRendering | HtmlElementRendering>} child placeholder
34
+ */
35
+ function getChildPlaceholder(rendering, placeholderName) {
36
+ if (!rendering ||
37
+ !placeholderName ||
38
+ !rendering.placeholders ||
39
+ !rendering.placeholders[placeholderName]) {
40
+ return [];
41
+ }
42
+ return rendering.placeholders[placeholderName];
43
+ }
44
+ exports.getChildPlaceholder = getChildPlaceholder;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.mediaApi = void 0;
23
+ const mediaApi = __importStar(require("./media-api"));
24
+ exports.mediaApi = mediaApi;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getSrcSet = exports.updateImageUrl = exports.replaceMediaUrlPrefix = exports.getRequiredParams = exports.findEditorImageTag = void 0;
7
+ const lodash_unescape_1 = __importDefault(require("lodash.unescape"));
8
+ const url_parse_1 = __importDefault(require("url-parse"));
9
+ // finds an img tag with HTML attributes
10
+ const imgTagRegex = /<img([^>]+)\/>/i;
11
+ // finds all the HTML attributes in a string
12
+ const htmlAttrsRegex = /([^=\s]+)(="([^"]*)")?/gi;
13
+ // finds the Sitecore media URL prefix
14
+ const mediaUrlPrefixRegex = /\/([-~]{1})\/media\//i;
15
+ /**
16
+ * Makes a request to Sitecore Content Service for the specified item path.
17
+ * @param {string} editorMarkup the markup to parse
18
+ * @returns {Object | null} found image tag; null in case if not found
19
+ */
20
+ const findEditorImageTag = (editorMarkup) => {
21
+ // match the tag
22
+ const tagMatch = editorMarkup.match(imgTagRegex);
23
+ if (!tagMatch || tagMatch.length < 2) {
24
+ return null;
25
+ }
26
+ // find the attrs and turn them into a Map
27
+ const attrs = {};
28
+ let match = htmlAttrsRegex.exec(tagMatch[1]);
29
+ while (match !== null) {
30
+ attrs[match[1]] = lodash_unescape_1.default(match[3]);
31
+ match = htmlAttrsRegex.exec(tagMatch[1]);
32
+ }
33
+ return {
34
+ imgTag: tagMatch[0],
35
+ attrs,
36
+ };
37
+ };
38
+ exports.findEditorImageTag = findEditorImageTag;
39
+ /**
40
+ * Get required query string params which should be merged with user params
41
+ * @param {object} qs layout service parsed query string
42
+ * @returns {object} requiredParams
43
+ */
44
+ const getRequiredParams = (qs) => {
45
+ const { rev, db, la, vs, ts } = qs;
46
+ return { rev, db, la, vs, ts };
47
+ };
48
+ exports.getRequiredParams = getRequiredParams;
49
+ /**
50
+ * Replace `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
51
+ * Can use `mediaUrlPrefix` in order to use a custom prefix.
52
+ * @param {string} url The URL to replace the media URL prefix in
53
+ * @param {RegExp} [mediaUrlPrefix=mediaUrlPrefixRegex] The regex to match the media URL prefix
54
+ * @returns {string} The URL with the media URL prefix replaced
55
+ */
56
+ const replaceMediaUrlPrefix = (url, mediaUrlPrefix = mediaUrlPrefixRegex) => {
57
+ const parsed = url_parse_1.default(url, {}, true);
58
+ const match = mediaUrlPrefix.exec(parsed.pathname);
59
+ if (match && match.length > 1) {
60
+ // regex will provide us with /-/ or /~/ type
61
+ parsed.set('pathname', parsed.pathname.replace(mediaUrlPrefix, `/${match[1]}/jssmedia/`));
62
+ }
63
+ return parsed.toString();
64
+ };
65
+ exports.replaceMediaUrlPrefix = replaceMediaUrlPrefix;
66
+ /**
67
+ * Prepares a Sitecore media URL with `params` for use by the JSS media handler.
68
+ * This is done by replacing `/~/media` or `/-/media` with `/~/jssmedia` or `/-/jssmedia`, respectively.
69
+ * Provided `params` are used as the querystring parameters for the media URL.
70
+ * Can use `mediaUrlPrefix` in order to use a custom prefix.
71
+ * If no `params` are sent, the original media URL is returned.
72
+ * @param {string} url The URL to prepare
73
+ * @param {Object} [params] The querystring parameters to use
74
+ * @param {RegExp} [mediaUrlPrefix=mediaUrlPrefixRegex] The regex to match the media URL prefix
75
+ * @returns {string} The prepared URL
76
+ */
77
+ const updateImageUrl = (url, params, mediaUrlPrefix = mediaUrlPrefixRegex) => {
78
+ if (!params || Object.keys(params).length === 0) {
79
+ // if params aren't supplied, no need to run it through JSS media handler
80
+ return url;
81
+ }
82
+ // polyfill node `global` in browser to workaround https://github.com/unshiftio/url-parse/issues/150
83
+ if (typeof window !== 'undefined' && !window.global) {
84
+ window.global = {};
85
+ }
86
+ const parsed = url_parse_1.default(exports.replaceMediaUrlPrefix(url, mediaUrlPrefix), {}, true);
87
+ const requiredParams = exports.getRequiredParams(parsed.query);
88
+ const query = Object.assign({}, params);
89
+ Object.entries(requiredParams).forEach(([key, param]) => {
90
+ if (param) {
91
+ query[key] = param;
92
+ }
93
+ });
94
+ parsed.set('query', query);
95
+ return parsed.toString();
96
+ };
97
+ exports.updateImageUrl = updateImageUrl;
98
+ /**
99
+ * Receives an array of `srcSet` parameters that are iterated and used as parameters to generate
100
+ * a corresponding set of updated Sitecore media URLs via @see updateImageUrl. The result is a comma-delimited
101
+ * list of media URLs with respective dimension parameters.
102
+ *
103
+ * @example
104
+ * // returns '/ipsum.jpg?h=1000&w=1000 1000w, /ipsum.jpg?mh=250&mw=250 250w'
105
+ * getSrcSet('/ipsum.jpg', [{ h: 1000, w: 1000 }, { mh: 250, mw: 250 } ])
106
+ *
107
+ * More information about `srcSet`: {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img}
108
+ *
109
+ * @param {string} url The URL to prepare
110
+ * @param {Array} srcSet The array of parameters to use
111
+ * @param {Object} [imageParams] The querystring parameters to use
112
+ * @param {RegExp} [mediaUrlPrefix] The regex to match the media URL prefix
113
+ * @returns {string} The prepared URL
114
+ */
115
+ const getSrcSet = (url, srcSet, imageParams, mediaUrlPrefix) => {
116
+ return srcSet
117
+ .map((params) => {
118
+ const newParams = Object.assign(Object.assign({}, imageParams), params);
119
+ const imageWidth = newParams.w || newParams.mw;
120
+ if (!imageWidth) {
121
+ return null;
122
+ }
123
+ return `${exports.updateImageUrl(url, newParams, mediaUrlPrefix)} ${imageWidth}w`;
124
+ })
125
+ .filter((value) => value)
126
+ .join(', ');
127
+ };
128
+ exports.getSrcSet = getSrcSet;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });