@sitecore-content-sdk/core 1.2.0-canary.2 → 1.2.0-canary.20

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.
@@ -10,6 +10,7 @@ const site_1 = require("../site");
10
10
  const utils_2 = require("./utils");
11
11
  const native_fetcher_1 = require("../native-fetcher");
12
12
  const robots_service_1 = require("../site/robots-service");
13
+ const models_1 = require("../editing/models");
13
14
  /**
14
15
  * Error page codes
15
16
  */
@@ -102,8 +103,9 @@ class SitecoreClient {
102
103
  */
103
104
  getHeadLinks(layoutData, options = {}) {
104
105
  const { enableStyles = true, enableThemes = true } = options;
105
- const { contextId, edgeUrl } = this.initOptions.api.edge;
106
+ const { contextId: serverContextId, clientContextId, edgeUrl } = this.initOptions.api.edge;
106
107
  const headLinks = [];
108
+ const contextId = serverContextId || clientContextId;
107
109
  if (enableStyles) {
108
110
  const contentStyles = (0, layout_1.getContentStylesheetLink)(layoutData, contextId, edgeUrl);
109
111
  if (contentStyles)
@@ -149,7 +151,10 @@ class SitecoreClient {
149
151
  return null;
150
152
  }
151
153
  // If we're in Pages preview (editing) mode, prefetch the editing data
152
- const { site, itemId, language, version, variantIds, layoutKind, mode } = previewData;
154
+ const { site, itemId, language, version, layoutKind, mode } = previewData;
155
+ const variantIds = Array.isArray(previewData.variantIds)
156
+ ? previewData.variantIds
157
+ : previewData.variantIds.split(',');
153
158
  const data = await this.editingService.fetchEditingData({
154
159
  itemId,
155
160
  language,
@@ -181,17 +186,14 @@ class SitecoreClient {
181
186
  if (!this.initOptions.api.local) {
182
187
  throw new Error('Component Library requires Sitecore apiHost and apiKey to be provided');
183
188
  }
184
- const { itemId, componentUid, site, language, renderingId, dataSourceId, version, mode } = designLibData;
185
- const componentData = await this.componentService.fetchComponentData({
186
- siteName: site,
187
- itemId,
189
+ const { itemId, componentUid, site, language, renderingId, dataSourceId, version, mode, generation, } = designLibData;
190
+ const componentData = await this.componentService.fetchComponentData(Object.assign({ siteName: site, itemId,
188
191
  language,
189
192
  componentUid,
190
193
  renderingId,
191
194
  dataSourceId,
192
195
  version,
193
- mode,
194
- }, fetchOptions);
196
+ mode }, (generation ? { generation } : {})), fetchOptions);
195
197
  if (!componentData) {
196
198
  throw new Error(`Unable to fetch editing data for preview ${JSON.stringify(designLibData)}`);
197
199
  }
@@ -199,7 +201,7 @@ class SitecoreClient {
199
201
  locale: designLibData.language,
200
202
  layout: componentData,
201
203
  siteName: ((_a = componentData.sitecore.context.site) === null || _a === void 0 ? void 0 : _a.name) || site,
202
- mode: this.getPageMode(mode),
204
+ mode: this.getPageMode(mode, generation),
203
205
  };
204
206
  return page;
205
207
  }
@@ -333,18 +335,17 @@ class SitecoreClient {
333
335
  /**
334
336
  * Get page mode based on mode name
335
337
  * @param {PageModeName} mode - The mode name to get the page mode for
338
+ * @param { DesignLibraryVariantGeneration} generation - The variant generation mode, if applicable
336
339
  * @returns {PageMode} The page mode
337
340
  */
338
- getPageMode(mode) {
341
+ getPageMode(mode, generation) {
339
342
  const pageMode = {
340
343
  name: mode,
341
344
  isNormal: false,
342
345
  isPreview: false,
343
346
  isEditing: false,
344
347
  isDesignLibrary: false,
345
- designLibrary: {
346
- isVariantGeneration: false,
347
- },
348
+ designLibrary: { isVariantGeneration: false },
348
349
  };
349
350
  switch (mode) {
350
351
  case layout_1.LayoutServicePageState.Normal:
@@ -363,14 +364,13 @@ class SitecoreClient {
363
364
  pageMode.isDesignLibrary = true;
364
365
  pageMode.isEditing = true;
365
366
  break;
366
- case editing_1.DesignLibraryMode.VariantGeneration:
367
- pageMode.isDesignLibrary = true;
368
- pageMode.isEditing = true;
369
- pageMode.designLibrary.isVariantGeneration = true;
370
- break;
371
367
  default:
372
368
  break;
373
369
  }
370
+ if (pageMode.isDesignLibrary && generation === models_1.DesignLibraryVariantGeneration.Variant) {
371
+ pageMode.designLibrary.isVariantGeneration = true;
372
+ pageMode.isEditing = true;
373
+ }
374
374
  return pageMode;
375
375
  }
376
376
  getClientFactory() {
package/dist/cjs/debug.js CHANGED
@@ -40,6 +40,7 @@ exports.default = {
40
40
  robots: (0, debug_1.default)(`${rootNamespace}:robots`),
41
41
  redirects: (0, debug_1.default)(`${rootNamespace}:redirects`),
42
42
  personalize: (0, debug_1.default)(`${rootNamespace}:personalize`),
43
+ locale: (0, debug_1.default)(`${rootNamespace}:locale`),
43
44
  errorpages: (0, debug_1.default)(`${rootNamespace}:errorpages`),
44
45
  proxy: (0, debug_1.default)(`${rootNamespace}:proxy`),
45
46
  };
@@ -122,7 +122,5 @@ function getDesignLibraryScriptLink(sitecoreEdgeUrl = constants_1.SITECORE_EDGE_
122
122
  * @returns {boolean} True if the mode is a Design Library mode, false otherwise.
123
123
  */
124
124
  function isDesignLibraryMode(mode) {
125
- return (mode === models_1.DesignLibraryMode.Normal ||
126
- mode === models_1.DesignLibraryMode.Metadata ||
127
- mode === models_1.DesignLibraryMode.VariantGeneration);
125
+ return mode === models_1.DesignLibraryMode.Normal || mode === models_1.DesignLibraryMode.Metadata;
128
126
  }
@@ -10,12 +10,14 @@ const trackedScopes = [
10
10
  ];
11
11
  /**
12
12
  * Get application metadata
13
+ * @param {boolean} allowWorkspaces - Whether to allow workspaces in the metadata generation.
14
+ * @returns {Metadata} The generated metadata.
13
15
  */
14
- function getMetadata() {
16
+ function getMetadata(allowWorkspaces = false) {
15
17
  const metadata = { packages: {} };
16
18
  let queryResult = [];
17
19
  try {
18
- queryResult = JSON.parse((0, child_process_1.execSync)('npm query [name*=@sitecore] --workspaces false').toString());
20
+ queryResult = JSON.parse((0, child_process_1.execSync)(`npm query [name*=@sitecore] --workspaces ${allowWorkspaces}`).toString());
19
21
  }
20
22
  catch (error) {
21
23
  console.error('Failed to retrieve sitecore packages using npm query', error);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DesignLibraryMode = exports.MetadataKind = exports.LayoutKind = void 0;
3
+ exports.DesignLibraryVariantGeneration = exports.DesignLibraryMode = exports.MetadataKind = exports.LayoutKind = void 0;
4
4
  /**
5
5
  * Represents the Editing Layout variant.
6
6
  * - shared - shared layout
@@ -28,6 +28,11 @@ var DesignLibraryMode;
28
28
  DesignLibraryMode["Normal"] = "library";
29
29
  /** Metadata mode */
30
30
  DesignLibraryMode["Metadata"] = "library-metadata";
31
- /** Variant generation mode */
32
- DesignLibraryMode["VariantGeneration"] = "library-variant-generation";
33
31
  })(DesignLibraryMode || (exports.DesignLibraryMode = DesignLibraryMode = {}));
32
+ /**
33
+ * Variant generation mode for Design Library
34
+ */
35
+ var DesignLibraryVariantGeneration;
36
+ (function (DesignLibraryVariantGeneration) {
37
+ DesignLibraryVariantGeneration["Variant"] = "variant";
38
+ })(DesignLibraryVariantGeneration || (exports.DesignLibraryVariantGeneration = DesignLibraryVariantGeneration = {}));
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DictionaryService = void 0;
3
+ exports.getLocaleRewrite = exports.DictionaryService = void 0;
4
4
  var dictionary_service_1 = require("./dictionary-service");
5
5
  Object.defineProperty(exports, "DictionaryService", { enumerable: true, get: function () { return dictionary_service_1.DictionaryService; } });
6
+ var utils_1 = require("./utils");
7
+ Object.defineProperty(exports, "getLocaleRewrite", { enumerable: true, get: function () { return utils_1.getLocaleRewrite; } });
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLocaleRewrite = getLocaleRewrite;
4
+ /**
5
+ * Get a locale rewrite path for given pathname
6
+ * @param {string} pathname the pathname
7
+ * @param {string} locale the site data to include in the rewrite
8
+ * @returns {string} the rewrite path
9
+ */
10
+ function getLocaleRewrite(pathname, locale) {
11
+ const path = pathname.startsWith('/') ? pathname : '/' + pathname;
12
+ return `/${locale}${path}`;
13
+ }
@@ -14,8 +14,8 @@ exports.VARIANT_PREFIX = '_variantId_';
14
14
  * @returns {string} the rewrite path
15
15
  */
16
16
  function getPersonalizedRewrite(pathname, variantIds) {
17
- const path = pathname.startsWith('/') ? pathname : '/' + pathname;
18
- return `${variantIds.map((variantId) => `/${exports.VARIANT_PREFIX}${variantId}`).join('')}${path}`;
17
+ const path = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
18
+ return `${path}${variantIds.map((variantId) => `/${exports.VARIANT_PREFIX}${variantId}`).join('')}`;
19
19
  }
20
20
  /**
21
21
  * Get personalize data from the rewrite path
@@ -11,13 +11,13 @@ const ensurePath_1 = require("../utils/ensurePath");
11
11
  /**
12
12
  * Generate application metadata
13
13
  * @param {GenerateMetadataConfig} config - Optional configuration for generating metadata.
14
- * If not provided, the default '.sitecore/metadata.json' will be used.
14
+ * If not provided, the default '.sitecore/metadata.json' will be used and allowWorkspaces will be set to false.
15
15
  * @returns {Promise<void>} A promise that resolves when the metadata generation is complete.
16
16
  */
17
17
  const generateMetadata = (config) => {
18
18
  return async () => {
19
19
  var _a;
20
- const metadata = (0, metadata_1.getMetadata)();
20
+ const metadata = (0, metadata_1.getMetadata)(!!(config === null || config === void 0 ? void 0 : config.allowWorkspaces));
21
21
  writeMetadata(metadata, (_a = config === null || config === void 0 ? void 0 : config.destinationPath) !== null && _a !== void 0 ? _a : '.sitecore/metadata.json');
22
22
  };
23
23
  };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.tryParseEnvValue = exports.mergeURLSearchParams = exports.escapeNonSpecialQuestionMarks = exports.areURLSearchParamsEqual = exports.isRegexOrUrl = exports.getAllowedOriginsFromEnv = exports.enforceCors = exports.isTimeoutError = exports.isAbsoluteUrl = exports.resolveUrl = exports.isServer = void 0;
6
+ exports.tryParseEnvValue = exports.mergeURLSearchParams = exports.escapeNonSpecialQuestionMarks = exports.areURLSearchParamsEqual = exports.isRegexOrUrl = exports.getAllowedOriginsFromEnv = exports.getEnforcedCorsHeaders = exports.enforceCors = exports.isTimeoutError = exports.isAbsoluteUrl = exports.resolveUrl = exports.isServer = void 0;
7
7
  var is_server_1 = require("./is-server");
8
8
  Object.defineProperty(exports, "isServer", { enumerable: true, get: function () { return __importDefault(is_server_1).default; } });
9
9
  var utils_1 = require("./utils");
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "resolveUrl", { enumerable: true, get: function (
11
11
  Object.defineProperty(exports, "isAbsoluteUrl", { enumerable: true, get: function () { return utils_1.isAbsoluteUrl; } });
12
12
  Object.defineProperty(exports, "isTimeoutError", { enumerable: true, get: function () { return utils_1.isTimeoutError; } });
13
13
  Object.defineProperty(exports, "enforceCors", { enumerable: true, get: function () { return utils_1.enforceCors; } });
14
+ Object.defineProperty(exports, "getEnforcedCorsHeaders", { enumerable: true, get: function () { return utils_1.getEnforcedCorsHeaders; } });
14
15
  Object.defineProperty(exports, "getAllowedOriginsFromEnv", { enumerable: true, get: function () { return utils_1.getAllowedOriginsFromEnv; } });
15
16
  Object.defineProperty(exports, "isRegexOrUrl", { enumerable: true, get: function () { return utils_1.isRegexOrUrl; } });
16
17
  Object.defineProperty(exports, "areURLSearchParamsEqual", { enumerable: true, get: function () { return utils_1.areURLSearchParamsEqual; } });
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.mergeURLSearchParams = exports.escapeNonSpecialQuestionMarks = exports.areURLSearchParamsEqual = exports.isRegexOrUrl = exports.enforceCors = exports.getAllowedOriginsFromEnv = exports.isTimeoutError = exports.isAbsoluteUrl = void 0;
6
+ exports.mergeURLSearchParams = exports.escapeNonSpecialQuestionMarks = exports.areURLSearchParamsEqual = exports.isRegexOrUrl = exports.getEnforcedCorsHeaders = exports.enforceCors = exports.getAllowedOriginsFromEnv = exports.isTimeoutError = exports.isAbsoluteUrl = void 0;
7
7
  exports.resolveUrl = resolveUrl;
8
8
  const is_server_1 = __importDefault(require("./is-server"));
9
9
  /**
@@ -94,6 +94,7 @@ exports.getAllowedOriginsFromEnv = getAllowedOriginsFromEnv;
94
94
  * @param {OutgoingMessage} res response to set CORS headers for
95
95
  * @param {string[]} [allowedOrigins] additional list of origins to test against
96
96
  * @returns true if incoming origin matches the allowed lists, false when it does not
97
+ * @deprecated use getEnforcedCorsHeaders instead
97
98
  */
98
99
  const enforceCors = (req, res, allowedOrigins) => {
99
100
  // origin in not present for non-CORS requests (e.g. server-side) - so we skip the checks
@@ -124,6 +125,38 @@ const enforceCors = (req, res, allowedOrigins) => {
124
125
  return false;
125
126
  };
126
127
  exports.enforceCors = enforceCors;
128
+ const getEnforcedCorsHeaders = ({ requestMethod, headers, presetCorsHeader, allowedOrigins = [], }) => {
129
+ // ugly but gotta satisfy both node.js and web fetch Headers interface somehow
130
+ const origin = headers.get
131
+ ? headers.get('origin')
132
+ : headers.origin;
133
+ if (!origin) {
134
+ return {};
135
+ }
136
+ // 3 sources of allowed origins are considered:
137
+ // the env value
138
+ const defaultAllowedOrigins = (0, exports.getAllowedOriginsFromEnv)();
139
+ // the allowedOrigins prop
140
+ allowedOrigins = defaultAllowedOrigins.concat(allowedOrigins || []);
141
+ // and the existing CORS header, if provided (i.e. from nextjs config)
142
+ if (presetCorsHeader) {
143
+ allowedOrigins.push(presetCorsHeader);
144
+ }
145
+ if (origin &&
146
+ allowedOrigins.some((allowedOrigin) => origin === allowedOrigin || new RegExp(convertToWildcardRegex(allowedOrigin)).test(origin))) {
147
+ const corsHeaders = {
148
+ 'Access-Control-Allow-Origin': origin,
149
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, DELETE, PUT, PATCH',
150
+ };
151
+ // set the allowed headers for preflight requests
152
+ if (requestMethod === 'OPTIONS') {
153
+ corsHeaders['Access-Control-Allow-Headers'] = 'Content-Type, Authorization';
154
+ }
155
+ return corsHeaders;
156
+ }
157
+ return null;
158
+ };
159
+ exports.getEnforcedCorsHeaders = getEnforcedCorsHeaders;
127
160
  /**
128
161
  * Determines whether the given input is a regular expression or resembles a URL.
129
162
  * @param {string} input - The input string to evaluate.
@@ -7,6 +7,7 @@ import { ErrorPagesService, SitePathService, SitemapXmlService } from '../site';
7
7
  import { createGraphQLClientFactory } from './utils';
8
8
  import { NativeDataFetcher } from '../native-fetcher';
9
9
  import { RobotsService } from '../site/robots-service';
10
+ import { DesignLibraryVariantGeneration } from '../editing/models';
10
11
  /**
11
12
  * Error page codes
12
13
  */
@@ -99,8 +100,9 @@ export class SitecoreClient {
99
100
  */
100
101
  getHeadLinks(layoutData, options = {}) {
101
102
  const { enableStyles = true, enableThemes = true } = options;
102
- const { contextId, edgeUrl } = this.initOptions.api.edge;
103
+ const { contextId: serverContextId, clientContextId, edgeUrl } = this.initOptions.api.edge;
103
104
  const headLinks = [];
105
+ const contextId = serverContextId || clientContextId;
104
106
  if (enableStyles) {
105
107
  const contentStyles = getContentStylesheetLink(layoutData, contextId, edgeUrl);
106
108
  if (contentStyles)
@@ -146,7 +148,10 @@ export class SitecoreClient {
146
148
  return null;
147
149
  }
148
150
  // If we're in Pages preview (editing) mode, prefetch the editing data
149
- const { site, itemId, language, version, variantIds, layoutKind, mode } = previewData;
151
+ const { site, itemId, language, version, layoutKind, mode } = previewData;
152
+ const variantIds = Array.isArray(previewData.variantIds)
153
+ ? previewData.variantIds
154
+ : previewData.variantIds.split(',');
150
155
  const data = await this.editingService.fetchEditingData({
151
156
  itemId,
152
157
  language,
@@ -178,17 +183,14 @@ export class SitecoreClient {
178
183
  if (!this.initOptions.api.local) {
179
184
  throw new Error('Component Library requires Sitecore apiHost and apiKey to be provided');
180
185
  }
181
- const { itemId, componentUid, site, language, renderingId, dataSourceId, version, mode } = designLibData;
182
- const componentData = await this.componentService.fetchComponentData({
183
- siteName: site,
184
- itemId,
186
+ const { itemId, componentUid, site, language, renderingId, dataSourceId, version, mode, generation, } = designLibData;
187
+ const componentData = await this.componentService.fetchComponentData(Object.assign({ siteName: site, itemId,
185
188
  language,
186
189
  componentUid,
187
190
  renderingId,
188
191
  dataSourceId,
189
192
  version,
190
- mode,
191
- }, fetchOptions);
193
+ mode }, (generation ? { generation } : {})), fetchOptions);
192
194
  if (!componentData) {
193
195
  throw new Error(`Unable to fetch editing data for preview ${JSON.stringify(designLibData)}`);
194
196
  }
@@ -196,7 +198,7 @@ export class SitecoreClient {
196
198
  locale: designLibData.language,
197
199
  layout: componentData,
198
200
  siteName: ((_a = componentData.sitecore.context.site) === null || _a === void 0 ? void 0 : _a.name) || site,
199
- mode: this.getPageMode(mode),
201
+ mode: this.getPageMode(mode, generation),
200
202
  };
201
203
  return page;
202
204
  }
@@ -330,18 +332,17 @@ export class SitecoreClient {
330
332
  /**
331
333
  * Get page mode based on mode name
332
334
  * @param {PageModeName} mode - The mode name to get the page mode for
335
+ * @param { DesignLibraryVariantGeneration} generation - The variant generation mode, if applicable
333
336
  * @returns {PageMode} The page mode
334
337
  */
335
- getPageMode(mode) {
338
+ getPageMode(mode, generation) {
336
339
  const pageMode = {
337
340
  name: mode,
338
341
  isNormal: false,
339
342
  isPreview: false,
340
343
  isEditing: false,
341
344
  isDesignLibrary: false,
342
- designLibrary: {
343
- isVariantGeneration: false,
344
- },
345
+ designLibrary: { isVariantGeneration: false },
345
346
  };
346
347
  switch (mode) {
347
348
  case LayoutServicePageState.Normal:
@@ -360,14 +361,13 @@ export class SitecoreClient {
360
361
  pageMode.isDesignLibrary = true;
361
362
  pageMode.isEditing = true;
362
363
  break;
363
- case DesignLibraryMode.VariantGeneration:
364
- pageMode.isDesignLibrary = true;
365
- pageMode.isEditing = true;
366
- pageMode.designLibrary.isVariantGeneration = true;
367
- break;
368
364
  default:
369
365
  break;
370
366
  }
367
+ if (pageMode.isDesignLibrary && generation === DesignLibraryVariantGeneration.Variant) {
368
+ pageMode.designLibrary.isVariantGeneration = true;
369
+ pageMode.isEditing = true;
370
+ }
371
371
  return pageMode;
372
372
  }
373
373
  getClientFactory() {
package/dist/esm/debug.js CHANGED
@@ -33,6 +33,7 @@ export default {
33
33
  robots: debug(`${rootNamespace}:robots`),
34
34
  redirects: debug(`${rootNamespace}:redirects`),
35
35
  personalize: debug(`${rootNamespace}:personalize`),
36
+ locale: debug(`${rootNamespace}:locale`),
36
37
  errorpages: debug(`${rootNamespace}:errorpages`),
37
38
  proxy: debug(`${rootNamespace}:proxy`),
38
39
  };
@@ -113,7 +113,5 @@ export function getDesignLibraryScriptLink(sitecoreEdgeUrl = SITECORE_EDGE_URL_D
113
113
  * @returns {boolean} True if the mode is a Design Library mode, false otherwise.
114
114
  */
115
115
  export function isDesignLibraryMode(mode) {
116
- return (mode === DesignLibraryMode.Normal ||
117
- mode === DesignLibraryMode.Metadata ||
118
- mode === DesignLibraryMode.VariantGeneration);
116
+ return mode === DesignLibraryMode.Normal || mode === DesignLibraryMode.Metadata;
119
117
  }
@@ -7,12 +7,14 @@ const trackedScopes = [
7
7
  ];
8
8
  /**
9
9
  * Get application metadata
10
+ * @param {boolean} allowWorkspaces - Whether to allow workspaces in the metadata generation.
11
+ * @returns {Metadata} The generated metadata.
10
12
  */
11
- export function getMetadata() {
13
+ export function getMetadata(allowWorkspaces = false) {
12
14
  const metadata = { packages: {} };
13
15
  let queryResult = [];
14
16
  try {
15
- queryResult = JSON.parse(execSync('npm query [name*=@sitecore] --workspaces false').toString());
17
+ queryResult = JSON.parse(execSync(`npm query [name*=@sitecore] --workspaces ${allowWorkspaces}`).toString());
16
18
  }
17
19
  catch (error) {
18
20
  console.error('Failed to retrieve sitecore packages using npm query', error);
@@ -25,6 +25,11 @@ export var DesignLibraryMode;
25
25
  DesignLibraryMode["Normal"] = "library";
26
26
  /** Metadata mode */
27
27
  DesignLibraryMode["Metadata"] = "library-metadata";
28
- /** Variant generation mode */
29
- DesignLibraryMode["VariantGeneration"] = "library-variant-generation";
30
28
  })(DesignLibraryMode || (DesignLibraryMode = {}));
29
+ /**
30
+ * Variant generation mode for Design Library
31
+ */
32
+ export var DesignLibraryVariantGeneration;
33
+ (function (DesignLibraryVariantGeneration) {
34
+ DesignLibraryVariantGeneration["Variant"] = "variant";
35
+ })(DesignLibraryVariantGeneration || (DesignLibraryVariantGeneration = {}));
@@ -1 +1,2 @@
1
1
  export { DictionaryService, } from './dictionary-service';
2
+ export { getLocaleRewrite } from './utils';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Get a locale rewrite path for given pathname
3
+ * @param {string} pathname the pathname
4
+ * @param {string} locale the site data to include in the rewrite
5
+ * @returns {string} the rewrite path
6
+ */
7
+ export function getLocaleRewrite(pathname, locale) {
8
+ const path = pathname.startsWith('/') ? pathname : '/' + pathname;
9
+ return `/${locale}${path}`;
10
+ }
@@ -7,8 +7,8 @@ export const VARIANT_PREFIX = '_variantId_';
7
7
  * @returns {string} the rewrite path
8
8
  */
9
9
  export function getPersonalizedRewrite(pathname, variantIds) {
10
- const path = pathname.startsWith('/') ? pathname : '/' + pathname;
11
- return `${variantIds.map((variantId) => `/${VARIANT_PREFIX}${variantId}`).join('')}${path}`;
10
+ const path = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
11
+ return `${path}${variantIds.map((variantId) => `/${VARIANT_PREFIX}${variantId}`).join('')}`;
12
12
  }
13
13
  /**
14
14
  * Get personalize data from the rewrite path
@@ -5,13 +5,13 @@ import { ensurePathExists } from '../utils/ensurePath';
5
5
  /**
6
6
  * Generate application metadata
7
7
  * @param {GenerateMetadataConfig} config - Optional configuration for generating metadata.
8
- * If not provided, the default '.sitecore/metadata.json' will be used.
8
+ * If not provided, the default '.sitecore/metadata.json' will be used and allowWorkspaces will be set to false.
9
9
  * @returns {Promise<void>} A promise that resolves when the metadata generation is complete.
10
10
  */
11
11
  export const generateMetadata = (config) => {
12
12
  return async () => {
13
13
  var _a;
14
- const metadata = getMetadata();
14
+ const metadata = getMetadata(!!(config === null || config === void 0 ? void 0 : config.allowWorkspaces));
15
15
  writeMetadata(metadata, (_a = config === null || config === void 0 ? void 0 : config.destinationPath) !== null && _a !== void 0 ? _a : '.sitecore/metadata.json');
16
16
  };
17
17
  };
@@ -1,3 +1,3 @@
1
1
  export { default as isServer } from './is-server';
2
- export { resolveUrl, isAbsoluteUrl, isTimeoutError, enforceCors, getAllowedOriginsFromEnv, isRegexOrUrl, areURLSearchParamsEqual, escapeNonSpecialQuestionMarks, mergeURLSearchParams, } from './utils';
2
+ export { resolveUrl, isAbsoluteUrl, isTimeoutError, enforceCors, getEnforcedCorsHeaders, getAllowedOriginsFromEnv, isRegexOrUrl, areURLSearchParamsEqual, escapeNonSpecialQuestionMarks, mergeURLSearchParams, } from './utils';
3
3
  export { tryParseEnvValue } from './env';
@@ -84,6 +84,7 @@ export const getAllowedOriginsFromEnv = () => process.env.JSS_ALLOWED_ORIGINS
84
84
  * @param {OutgoingMessage} res response to set CORS headers for
85
85
  * @param {string[]} [allowedOrigins] additional list of origins to test against
86
86
  * @returns true if incoming origin matches the allowed lists, false when it does not
87
+ * @deprecated use getEnforcedCorsHeaders instead
87
88
  */
88
89
  export const enforceCors = (req, res, allowedOrigins) => {
89
90
  // origin in not present for non-CORS requests (e.g. server-side) - so we skip the checks
@@ -113,6 +114,37 @@ export const enforceCors = (req, res, allowedOrigins) => {
113
114
  }
114
115
  return false;
115
116
  };
117
+ export const getEnforcedCorsHeaders = ({ requestMethod, headers, presetCorsHeader, allowedOrigins = [], }) => {
118
+ // ugly but gotta satisfy both node.js and web fetch Headers interface somehow
119
+ const origin = headers.get
120
+ ? headers.get('origin')
121
+ : headers.origin;
122
+ if (!origin) {
123
+ return {};
124
+ }
125
+ // 3 sources of allowed origins are considered:
126
+ // the env value
127
+ const defaultAllowedOrigins = getAllowedOriginsFromEnv();
128
+ // the allowedOrigins prop
129
+ allowedOrigins = defaultAllowedOrigins.concat(allowedOrigins || []);
130
+ // and the existing CORS header, if provided (i.e. from nextjs config)
131
+ if (presetCorsHeader) {
132
+ allowedOrigins.push(presetCorsHeader);
133
+ }
134
+ if (origin &&
135
+ allowedOrigins.some((allowedOrigin) => origin === allowedOrigin || new RegExp(convertToWildcardRegex(allowedOrigin)).test(origin))) {
136
+ const corsHeaders = {
137
+ 'Access-Control-Allow-Origin': origin,
138
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, DELETE, PUT, PATCH',
139
+ };
140
+ // set the allowed headers for preflight requests
141
+ if (requestMethod === 'OPTIONS') {
142
+ corsHeaders['Access-Control-Allow-Headers'] = 'Content-Type, Authorization';
143
+ }
144
+ return corsHeaders;
145
+ }
146
+ return null;
147
+ };
116
148
  /**
117
149
  * Determines whether the given input is a regular expression or resembles a URL.
118
150
  * @param {string} input - The input string to evaluate.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/core",
3
- "version": "1.2.0-canary.2",
3
+ "version": "1.2.0-canary.20",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "description": "",
87
87
  "types": "types/index.d.ts",
88
- "gitHead": "91681af284f72808222c3648de790d2bba5c5953",
88
+ "gitHead": "c37f5159bbc1ade9567748eee4ca47e0158e2d89",
89
89
  "files": [
90
90
  "dist",
91
91
  "types",
@@ -294,6 +294,7 @@ export declare class SitecoreClient implements BaseSitecoreClient {
294
294
  /**
295
295
  * Get page mode based on mode name
296
296
  * @param {PageModeName} mode - The mode name to get the page mode for
297
+ * @param { DesignLibraryVariantGeneration} generation - The variant generation mode, if applicable
297
298
  * @returns {PageMode} The page mode
298
299
  */
299
300
  private getPageMode;
package/types/debug.d.ts CHANGED
@@ -21,6 +21,7 @@ declare const _default: {
21
21
  robots: debug.Debugger;
22
22
  redirects: debug.Debugger;
23
23
  personalize: debug.Debugger;
24
+ locale: debug.Debugger;
24
25
  errorpages: debug.Debugger;
25
26
  proxy: debug.Debugger;
26
27
  };
@@ -1,5 +1,5 @@
1
1
  import { LayoutServiceData } from '../layout/models';
2
- import { DesignLibraryMode } from './models';
2
+ import { DesignLibraryMode, DesignLibraryVariantGeneration } from './models';
3
3
  import { FetchOptions } from '../models';
4
4
  /**
5
5
  * Params for requesting component data in Design Library mode
@@ -14,6 +14,10 @@ export interface ComponentLayoutRequestParams {
14
14
  * an arbitrary one (component renderingId and datasource would be used for identification then)
15
15
  */
16
16
  componentUid: string;
17
+ /**
18
+ * site name to be used as context for rendering the component
19
+ */
20
+ siteName: string;
17
21
  /**
18
22
  * language to render component in
19
23
  */
@@ -30,14 +34,14 @@ export interface ComponentLayoutRequestParams {
30
34
  * version of the context item (latest by default)
31
35
  */
32
36
  version?: string;
33
- /**
34
- * site name to be used as context for rendering the component
35
- */
36
- siteName: string;
37
37
  /**
38
38
  * mode to be used for rendering the component
39
39
  */
40
40
  mode?: DesignLibraryMode;
41
+ /**
42
+ * design library variant generation mode
43
+ */
44
+ generation?: DesignLibraryVariantGeneration;
41
45
  }
42
46
  /**
43
47
  * Config for ComponentLayoutService.
@@ -1,5 +1,7 @@
1
1
  import { Metadata } from './';
2
2
  /**
3
3
  * Get application metadata
4
+ * @param {boolean} allowWorkspaces - Whether to allow workspaces in the metadata generation.
5
+ * @returns {Metadata} The generated metadata.
4
6
  */
5
- export declare function getMetadata(): Metadata;
7
+ export declare function getMetadata(allowWorkspaces?: boolean): Metadata;
@@ -58,7 +58,7 @@ export type EditingPreviewData = {
58
58
  itemId: string;
59
59
  language: string;
60
60
  mode: Exclude<LayoutServicePageState, 'Normal'>;
61
- variantIds: string[];
61
+ variantIds: string[] | string;
62
62
  version?: string;
63
63
  layoutKind?: LayoutKind;
64
64
  };
@@ -67,9 +67,13 @@ export declare enum DesignLibraryMode {
67
67
  /** Normal mode */
68
68
  Normal = "library",
69
69
  /** Metadata mode */
70
- Metadata = "library-metadata",
71
- /** Variant generation mode */
72
- VariantGeneration = "library-variant-generation"
70
+ Metadata = "library-metadata"
71
+ }
72
+ /**
73
+ * Variant generation mode for Design Library
74
+ */
75
+ export declare enum DesignLibraryVariantGeneration {
76
+ Variant = "variant"
73
77
  }
74
78
  /**
75
79
  * Data for Design Library rendering mode
@@ -84,4 +88,5 @@ export interface DesignLibraryRenderPreviewData {
84
88
  variant?: string;
85
89
  version?: string;
86
90
  dataSourceId?: string;
91
+ generation?: DesignLibraryVariantGeneration;
87
92
  }
@@ -1 +1,2 @@
1
1
  export { DictionaryPhrases, DictionaryServiceConfig, DictionaryService, } from './dictionary-service';
2
+ export { getLocaleRewrite } from './utils';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Get a locale rewrite path for given pathname
3
+ * @param {string} pathname the pathname
4
+ * @param {string} locale the site data to include in the rewrite
5
+ * @returns {string} the rewrite path
6
+ */
7
+ export declare function getLocaleRewrite(pathname: string, locale: string): string;
@@ -7,11 +7,16 @@ export type GenerateMetadataConfig = {
7
7
  * If not provided, the default '.sitecore/metadata.json' will be used.
8
8
  */
9
9
  destinationPath?: string;
10
+ /**
11
+ * Optional flag to allow npm workspaces in the metadata generation. Should be kept as false for non-npm monorepos.
12
+ * If not provided, the default is false.
13
+ */
14
+ allowWorkspaces?: boolean;
10
15
  };
11
16
  /**
12
17
  * Generate application metadata
13
18
  * @param {GenerateMetadataConfig} config - Optional configuration for generating metadata.
14
- * If not provided, the default '.sitecore/metadata.json' will be used.
19
+ * If not provided, the default '.sitecore/metadata.json' will be used and allowWorkspaces will be set to false.
15
20
  * @returns {Promise<void>} A promise that resolves when the metadata generation is complete.
16
21
  */
17
22
  export declare const generateMetadata: (config?: GenerateMetadataConfig) => (() => Promise<void>);
@@ -1,3 +1,3 @@
1
1
  export { default as isServer } from './is-server';
2
- export { resolveUrl, isAbsoluteUrl, isTimeoutError, enforceCors, EnhancedOmit, getAllowedOriginsFromEnv, isRegexOrUrl, areURLSearchParamsEqual, escapeNonSpecialQuestionMarks, mergeURLSearchParams, } from './utils';
2
+ export { resolveUrl, isAbsoluteUrl, isTimeoutError, enforceCors, getEnforcedCorsHeaders, EnhancedOmit, getAllowedOriginsFromEnv, isRegexOrUrl, areURLSearchParamsEqual, escapeNonSpecialQuestionMarks, mergeURLSearchParams, } from './utils';
3
3
  export { tryParseEnvValue } from './env';
@@ -1,4 +1,4 @@
1
- import { IncomingMessage, OutgoingMessage } from 'http';
1
+ import { IncomingHttpHeaders, IncomingMessage, OutgoingMessage } from 'http';
2
2
  import { ParsedUrlQueryInput } from 'querystring';
3
3
  /**
4
4
  * Omit properties from T that are in K. This is a simplified version of TypeScript's built-in `Omit` utility type.
@@ -38,8 +38,17 @@ export declare const getAllowedOriginsFromEnv: () => string[];
38
38
  * @param {OutgoingMessage} res response to set CORS headers for
39
39
  * @param {string[]} [allowedOrigins] additional list of origins to test against
40
40
  * @returns true if incoming origin matches the allowed lists, false when it does not
41
+ * @deprecated use getEnforcedCorsHeaders instead
41
42
  */
42
43
  export declare const enforceCors: (req: IncomingMessage, res: OutgoingMessage, allowedOrigins?: string[]) => boolean;
44
+ export declare const getEnforcedCorsHeaders: ({ requestMethod, headers, presetCorsHeader, allowedOrigins, }: {
45
+ requestMethod: string | undefined;
46
+ headers: IncomingHttpHeaders | Headers;
47
+ presetCorsHeader?: string | string[];
48
+ allowedOrigins?: string[];
49
+ }) => {
50
+ [key: string]: string;
51
+ } | null;
43
52
  /**
44
53
  * Determines whether the given input is a regular expression or resembles a URL.
45
54
  * @param {string} input - The input string to evaluate.