@sitecore-content-sdk/core 0.2.0-beta.4 → 0.2.0-beta.6

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.
package/content.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './types/content/index';
package/content.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/cjs/content/index');
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HIDDEN_RENDERING_NAME = exports.SITECORE_EDGE_URL_DEFAULT = exports.siteNameError = exports.SitecoreTemplateId = void 0;
3
+ exports.DEFAULT_SITECORE_AUTH_AUDIENCE = exports.DEFAULT_SITECORE_AUTH_ENDPOINT = exports.HIDDEN_RENDERING_NAME = exports.SITECORE_EDGE_URL_DEFAULT = exports.siteNameError = exports.SitecoreTemplateId = void 0;
4
4
  var SitecoreTemplateId;
5
5
  (function (SitecoreTemplateId) {
6
6
  // /sitecore/templates/Foundation/JavaScript Services/App
@@ -11,3 +11,5 @@ var SitecoreTemplateId;
11
11
  exports.siteNameError = 'The siteName cannot be empty';
12
12
  exports.SITECORE_EDGE_URL_DEFAULT = 'https://edge-platform.sitecorecloud.io';
13
13
  exports.HIDDEN_RENDERING_NAME = 'Hidden Rendering';
14
+ exports.DEFAULT_SITECORE_AUTH_ENDPOINT = 'https://auth.sitecorecloud.io/oauth/token';
15
+ exports.DEFAULT_SITECORE_AUTH_AUDIENCE = 'https://api.sitecorecloud.io';
@@ -0,0 +1,89 @@
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.ContentClient = void 0;
7
+ const graphql_request_client_1 = require("../graphql-request-client");
8
+ const utils_1 = require("./utils");
9
+ const debug_1 = __importDefault(require("../debug"));
10
+ const locales_1 = require("./locales");
11
+ /**
12
+ * Class representing a client for interacting with the Content API.
13
+ */
14
+ class ContentClient {
15
+ constructor({ url, tenant, environment, preview = false, token }) {
16
+ this.endpoint = (0, utils_1.getContentUrl)({
17
+ environment,
18
+ preview,
19
+ tenant,
20
+ url,
21
+ });
22
+ this.graphqlClient = new graphql_request_client_1.GraphQLRequestClient(this.endpoint, {
23
+ headers: {
24
+ Authorization: `Bearer ${token}`,
25
+ },
26
+ debugger: debug_1.default.content,
27
+ });
28
+ }
29
+ /**
30
+ * Factory method for creating a ContentClient instance. This method allows you to create a client with the values populated from environment variables or provided as arguments.
31
+ * @param {Partial<ContentClientOptions>} [options] - client configuration options
32
+ * @param {string} [options.url] - Content base graphql endpoint url. If not provided, it will be read from the SITECORE_CS_URL environment variable. Otherwise, it defaults to https://cs-graphqlapi-staging.sitecore-staging.cloud.
33
+ * @param {string} [options.tenant] - Tenant name. If not provided, it will be read from the SITECORE_CS_TENANT environment variable
34
+ * @param {string} [options.environment] - Environment name. If not provided, it will be read from the SITECORE_CS_ENVIRONMENT environment variable. Otherwise, it defaults to 'main'
35
+ * @param {boolean} [options.preview] - Indicates if preview mode is enabled. If not provided, it will be read from the SITECORE_CS_PREVIEW environment variable. Otherwise, it defaults to false
36
+ * @param {string} [options.token] - Token for authentication. If not provided, it will be read from the SITECORE_CS_TOKEN environment variable.
37
+ * @returns {ContentClient} ContentClient instance
38
+ * @throws {Error} If tenant or token is not provided
39
+ */
40
+ static createClient({ url, tenant, environment, preview, token, } = {}) {
41
+ const options = {
42
+ url: url || process.env.SITECORE_CS_URL,
43
+ tenant: tenant || process.env.SITECORE_CS_TENANT || '',
44
+ environment: environment || process.env.SITECORE_CS_ENVIRONMENT || 'main',
45
+ preview: preview || process.env.SITECORE_CS_PREVIEW === 'true',
46
+ token: token || process.env.SITECORE_CS_TOKEN || '',
47
+ };
48
+ if (!options.tenant) {
49
+ throw new Error('Tenant is required to be provided as an argument or as a SITECORE_CS_TENANT environment variable');
50
+ }
51
+ if (!options.token) {
52
+ throw new Error('Token is required to be provided as an argument or as a SITECORE_CS_TOKEN environment variable');
53
+ }
54
+ return new ContentClient(options);
55
+ }
56
+ /**
57
+ * Execute graphql request
58
+ * @param {string | DocumentNode} query graphql query
59
+ * @param {object} variables variables for the query
60
+ * @param {FetchOptions} options options for configuring the request
61
+ * @returns {T} response data
62
+ */
63
+ async get(query, variables = {}, options = {}) {
64
+ debug_1.default.content('fetching content data');
65
+ return this.graphqlClient.request(query, variables, options);
66
+ }
67
+ /**
68
+ * Retrieves the locale information for a given locale ID.
69
+ *
70
+ * @param id - The unique identifier of the locale item.
71
+ * @returns A promise that resolves to the locale information associated with the specified locale ID.
72
+ */
73
+ async getLocale(id) {
74
+ debug_1.default.content('Getting locale for id: %s', id);
75
+ const response = await this.get(locales_1.GET_LOCALE_QUERY, { id });
76
+ return response.locale;
77
+ }
78
+ /**
79
+ * Retrieves all available locales from the content service.
80
+ *
81
+ * @returns A promise that resolves to an array of locales.
82
+ */
83
+ async getLocales() {
84
+ debug_1.default.content('Getting all locales');
85
+ const response = await this.get(locales_1.GET_LOCALES_QUERY);
86
+ return response.manyLocale;
87
+ }
88
+ }
89
+ exports.ContentClient = ContentClient;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getContentUrl = exports.GET_LOCALES_QUERY = exports.GET_LOCALE_QUERY = exports.ContentClient = void 0;
4
+ var content_client_1 = require("./content-client");
5
+ Object.defineProperty(exports, "ContentClient", { enumerable: true, get: function () { return content_client_1.ContentClient; } });
6
+ var locales_1 = require("./locales");
7
+ Object.defineProperty(exports, "GET_LOCALE_QUERY", { enumerable: true, get: function () { return locales_1.GET_LOCALE_QUERY; } });
8
+ Object.defineProperty(exports, "GET_LOCALES_QUERY", { enumerable: true, get: function () { return locales_1.GET_LOCALES_QUERY; } });
9
+ var utils_1 = require("./utils");
10
+ Object.defineProperty(exports, "getContentUrl", { enumerable: true, get: function () { return utils_1.getContentUrl; } });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET_LOCALES_QUERY = exports.GET_LOCALE_QUERY = void 0;
4
+ /**
5
+ * GraphQL query to retrieve a specific locale by its ID.
6
+ *
7
+ * Variables:
8
+ * - id: The ID of the locale to retrieve.
9
+ */
10
+ exports.GET_LOCALE_QUERY = `
11
+ query GetLocaleById ($id: ID!) {
12
+ locale(id: $id) {
13
+ id
14
+ label
15
+ }
16
+ }
17
+ `;
18
+ /**
19
+ * GraphQL query to retrieve all available locales.
20
+ */
21
+ exports.GET_LOCALES_QUERY = `
22
+ query GetAllLocales{
23
+ manyLocale {
24
+ id
25
+ label
26
+ }
27
+ }
28
+ `;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getContentUrl = getContentUrl;
4
+ const normalize_url_1 = require("../utils/normalize-url");
5
+ /**
6
+ * Get the Content graphql endpoint url
7
+ * @param {object} params Parameters
8
+ * @param {string} [params.url] Content base graphql endpoint url
9
+ * @param {string} params.tenant Tenant name
10
+ * @param {string} params.environment Environment name
11
+ * @param {boolean} params.preview Indicates if preview mode is enabled
12
+ * @returns {string} Content graphql endpoint url
13
+ */
14
+ function getContentUrl({ url = 'https://cs-graphqlapi-staging.sitecore-staging.cloud', tenant, environment, preview, }) {
15
+ return `${(0, normalize_url_1.normalizeUrl)(url)}/api/graphql/v1/${tenant}/${environment}?preview=${preview}`;
16
+ }
package/dist/cjs/debug.js CHANGED
@@ -29,6 +29,7 @@ exports.enableDebug = enableDebug;
29
29
  */
30
30
  exports.default = {
31
31
  common: (0, debug_1.default)(`${rootNamespace}:common`),
32
+ content: (0, debug_1.default)(`${rootNamespace}:content`),
32
33
  form: (0, debug_1.default)(`${rootNamespace}:form`),
33
34
  http: (0, debug_1.default)(`${rootNamespace}:http`),
34
35
  layout: (0, debug_1.default)(`${rootNamespace}:layout`),
package/dist/cjs/index.js CHANGED
@@ -38,9 +38,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  return (mod && mod.__esModule) ? mod : { "default": mod };
39
39
  };
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.defineConfig = exports.constants = exports.NativeDataFetcher = exports.ClientError = exports.MemoryCacheClient = exports.DefaultRetryStrategy = exports.GraphQLRequestClient = exports.enableDebug = exports.debug = void 0;
41
+ exports.defineConfig = exports.form = exports.constants = exports.NativeDataFetcher = exports.ClientError = exports.MemoryCacheClient = exports.DefaultRetryStrategy = exports.GraphQLRequestClient = exports.enableDebug = exports.debug = void 0;
42
42
  const constants = __importStar(require("./constants"));
43
43
  exports.constants = constants;
44
+ const form = __importStar(require("./form"));
45
+ exports.form = form;
44
46
  var debug_1 = require("./debug");
45
47
  Object.defineProperty(exports, "debug", { enumerable: true, get: function () { return __importDefault(debug_1).default; } });
46
48
  Object.defineProperty(exports, "enableDebug", { enumerable: true, get: function () { return debug_1.enableDebug; } });
@@ -0,0 +1,41 @@
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.fetchBearerToken = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const constants_1 = require("../../constants");
9
+ /**
10
+ * Connects to M2M endpoint and fetches the bearer token
11
+ * Uses client_id and client_secret from environment variables
12
+ * @param {FetchBearerTokenOptions} options client id, secret, and other parameters for connection to m2m endpoint
13
+ * @returns {string} bearer token string
14
+ */
15
+ const fetchBearerToken = async (options) => {
16
+ const { clientId, clientSecret } = options;
17
+ const audience = options.audience || constants_1.DEFAULT_SITECORE_AUTH_AUDIENCE;
18
+ const endpoint = options.endpoint || constants_1.DEFAULT_SITECORE_AUTH_ENDPOINT;
19
+ try {
20
+ // TODO:adjust when M2M endpoint is live
21
+ const authenticateResponse = await fetch(endpoint, {
22
+ method: 'POST',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ },
26
+ body: JSON.stringify({
27
+ client_id: clientId,
28
+ client_secret: clientSecret,
29
+ audience: audience,
30
+ grant_type: 'client_credentials',
31
+ }),
32
+ });
33
+ const jsonResponse = await authenticateResponse.json();
34
+ return jsonResponse.access_token;
35
+ }
36
+ catch (error) {
37
+ console.error(chalk_1.default.red('Error authenticating with Sitecore Auth endpoint:', error));
38
+ return null;
39
+ }
40
+ };
41
+ exports.fetchBearerToken = fetchBearerToken;
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.scaffoldComponent = exports.generateMetadata = exports.generateSites = void 0;
17
+ exports.fetchBearerToken = exports.scaffoldComponent = exports.generateMetadata = exports.generateSites = void 0;
18
18
  var generateSites_1 = require("./generateSites");
19
19
  Object.defineProperty(exports, "generateSites", { enumerable: true, get: function () { return generateSites_1.generateSites; } });
20
20
  var generateMetadata_1 = require("./generateMetadata");
@@ -22,3 +22,5 @@ Object.defineProperty(exports, "generateMetadata", { enumerable: true, get: func
22
22
  var scaffold_1 = require("./scaffold");
23
23
  Object.defineProperty(exports, "scaffoldComponent", { enumerable: true, get: function () { return scaffold_1.scaffoldComponent; } });
24
24
  __exportStar(require("./templating"), exports);
25
+ var fetch_bearer_token_1 = require("./auth/fetch-bearer-token");
26
+ Object.defineProperty(exports, "fetchBearerToken", { enumerable: true, get: function () { return fetch_bearer_token_1.fetchBearerToken; } });
@@ -173,7 +173,7 @@ exports.areURLSearchParamsEqual = areURLSearchParamsEqual;
173
173
  * @returns {string} - The modified string or regex with non-special "?" characters escaped.
174
174
  */
175
175
  const escapeNonSpecialQuestionMarks = (input) => {
176
- const regexPattern = /(?<!\\)\?/g; // Match unescaped "?" characters
176
+ const regexPattern = /(\\)?\?/g; // Match "?" that may or may not be preceded by a backslash
177
177
  const negativeLookaheadPattern = /\(\?!$/; // Detect the start of a Negative Lookahead pattern
178
178
  const specialRegexSymbols = /[.*+)\[\]|\(]$/; // Check for special regex symbols before "?"
179
179
  let result = '';
@@ -182,12 +182,14 @@ const escapeNonSpecialQuestionMarks = (input) => {
182
182
  while ((match = regexPattern.exec(input)) !== null) {
183
183
  const index = match.index; // Position of the "?" in the string
184
184
  const before = input.slice(lastIndex, index); // Context before the "?"
185
+ // Check if "?" is preceded by a backslash (escaped)
186
+ const isEscaped = match[1] !== undefined; // match[1] is the backslash group
185
187
  // Check if "?" is part of a Negative Lookahead
186
188
  const isNegativeLookahead = negativeLookaheadPattern.test(before.slice(-3));
187
189
  // Check if "?" follows a special regex symbol
188
190
  const isSpecialRegexSymbol = specialRegexSymbols.test(before.slice(-1));
189
- if (isNegativeLookahead || isSpecialRegexSymbol) {
190
- // If it's a special case, keep the "?" as is
191
+ if (isEscaped || isNegativeLookahead || isSpecialRegexSymbol) {
192
+ // If it's escaped, part of a Negative Lookahead, or follows a special regex symbol, keep the "?" as is
191
193
  result += input.slice(lastIndex, index + 1);
192
194
  }
193
195
  else {
@@ -8,3 +8,5 @@ export var SitecoreTemplateId;
8
8
  export const siteNameError = 'The siteName cannot be empty';
9
9
  export const SITECORE_EDGE_URL_DEFAULT = 'https://edge-platform.sitecorecloud.io';
10
10
  export const HIDDEN_RENDERING_NAME = 'Hidden Rendering';
11
+ export const DEFAULT_SITECORE_AUTH_ENDPOINT = 'https://auth.sitecorecloud.io/oauth/token';
12
+ export const DEFAULT_SITECORE_AUTH_AUDIENCE = 'https://api.sitecorecloud.io';
@@ -0,0 +1,82 @@
1
+ import { GraphQLRequestClient } from '../graphql-request-client';
2
+ import { getContentUrl } from './utils';
3
+ import debug from '../debug';
4
+ import { GET_LOCALE_QUERY, GET_LOCALES_QUERY, } from './locales';
5
+ /**
6
+ * Class representing a client for interacting with the Content API.
7
+ */
8
+ export class ContentClient {
9
+ constructor({ url, tenant, environment, preview = false, token }) {
10
+ this.endpoint = getContentUrl({
11
+ environment,
12
+ preview,
13
+ tenant,
14
+ url,
15
+ });
16
+ this.graphqlClient = new GraphQLRequestClient(this.endpoint, {
17
+ headers: {
18
+ Authorization: `Bearer ${token}`,
19
+ },
20
+ debugger: debug.content,
21
+ });
22
+ }
23
+ /**
24
+ * Factory method for creating a ContentClient instance. This method allows you to create a client with the values populated from environment variables or provided as arguments.
25
+ * @param {Partial<ContentClientOptions>} [options] - client configuration options
26
+ * @param {string} [options.url] - Content base graphql endpoint url. If not provided, it will be read from the SITECORE_CS_URL environment variable. Otherwise, it defaults to https://cs-graphqlapi-staging.sitecore-staging.cloud.
27
+ * @param {string} [options.tenant] - Tenant name. If not provided, it will be read from the SITECORE_CS_TENANT environment variable
28
+ * @param {string} [options.environment] - Environment name. If not provided, it will be read from the SITECORE_CS_ENVIRONMENT environment variable. Otherwise, it defaults to 'main'
29
+ * @param {boolean} [options.preview] - Indicates if preview mode is enabled. If not provided, it will be read from the SITECORE_CS_PREVIEW environment variable. Otherwise, it defaults to false
30
+ * @param {string} [options.token] - Token for authentication. If not provided, it will be read from the SITECORE_CS_TOKEN environment variable.
31
+ * @returns {ContentClient} ContentClient instance
32
+ * @throws {Error} If tenant or token is not provided
33
+ */
34
+ static createClient({ url, tenant, environment, preview, token, } = {}) {
35
+ const options = {
36
+ url: url || process.env.SITECORE_CS_URL,
37
+ tenant: tenant || process.env.SITECORE_CS_TENANT || '',
38
+ environment: environment || process.env.SITECORE_CS_ENVIRONMENT || 'main',
39
+ preview: preview || process.env.SITECORE_CS_PREVIEW === 'true',
40
+ token: token || process.env.SITECORE_CS_TOKEN || '',
41
+ };
42
+ if (!options.tenant) {
43
+ throw new Error('Tenant is required to be provided as an argument or as a SITECORE_CS_TENANT environment variable');
44
+ }
45
+ if (!options.token) {
46
+ throw new Error('Token is required to be provided as an argument or as a SITECORE_CS_TOKEN environment variable');
47
+ }
48
+ return new ContentClient(options);
49
+ }
50
+ /**
51
+ * Execute graphql request
52
+ * @param {string | DocumentNode} query graphql query
53
+ * @param {object} variables variables for the query
54
+ * @param {FetchOptions} options options for configuring the request
55
+ * @returns {T} response data
56
+ */
57
+ async get(query, variables = {}, options = {}) {
58
+ debug.content('fetching content data');
59
+ return this.graphqlClient.request(query, variables, options);
60
+ }
61
+ /**
62
+ * Retrieves the locale information for a given locale ID.
63
+ *
64
+ * @param id - The unique identifier of the locale item.
65
+ * @returns A promise that resolves to the locale information associated with the specified locale ID.
66
+ */
67
+ async getLocale(id) {
68
+ debug.content('Getting locale for id: %s', id);
69
+ const response = await this.get(GET_LOCALE_QUERY, { id });
70
+ return response.locale;
71
+ }
72
+ /**
73
+ * Retrieves all available locales from the content service.
74
+ *
75
+ * @returns A promise that resolves to an array of locales.
76
+ */
77
+ async getLocales() {
78
+ debug.content('Getting all locales');
79
+ const response = await this.get(GET_LOCALES_QUERY);
80
+ return response.manyLocale;
81
+ }
82
+ }
@@ -0,0 +1,3 @@
1
+ export { ContentClient } from './content-client';
2
+ export { GET_LOCALE_QUERY, GET_LOCALES_QUERY, } from './locales';
3
+ export { getContentUrl } from './utils';
@@ -0,0 +1,25 @@
1
+ /**
2
+ * GraphQL query to retrieve a specific locale by its ID.
3
+ *
4
+ * Variables:
5
+ * - id: The ID of the locale to retrieve.
6
+ */
7
+ export const GET_LOCALE_QUERY = `
8
+ query GetLocaleById ($id: ID!) {
9
+ locale(id: $id) {
10
+ id
11
+ label
12
+ }
13
+ }
14
+ `;
15
+ /**
16
+ * GraphQL query to retrieve all available locales.
17
+ */
18
+ export const GET_LOCALES_QUERY = `
19
+ query GetAllLocales{
20
+ manyLocale {
21
+ id
22
+ label
23
+ }
24
+ }
25
+ `;
@@ -0,0 +1,13 @@
1
+ import { normalizeUrl } from '../utils/normalize-url';
2
+ /**
3
+ * Get the Content graphql endpoint url
4
+ * @param {object} params Parameters
5
+ * @param {string} [params.url] Content base graphql endpoint url
6
+ * @param {string} params.tenant Tenant name
7
+ * @param {string} params.environment Environment name
8
+ * @param {boolean} params.preview Indicates if preview mode is enabled
9
+ * @returns {string} Content graphql endpoint url
10
+ */
11
+ export function getContentUrl({ url = 'https://cs-graphqlapi-staging.sitecore-staging.cloud', tenant, environment, preview, }) {
12
+ return `${normalizeUrl(url)}/api/graphql/v1/${tenant}/${environment}?preview=${preview}`;
13
+ }
package/dist/esm/debug.js CHANGED
@@ -22,6 +22,7 @@ export const enableDebug = (namespaces) => debug.enable(namespaces);
22
22
  */
23
23
  export default {
24
24
  common: debug(`${rootNamespace}:common`),
25
+ content: debug(`${rootNamespace}:content`),
25
26
  form: debug(`${rootNamespace}:form`),
26
27
  http: debug(`${rootNamespace}:http`),
27
28
  layout: debug(`${rootNamespace}:layout`),
package/dist/esm/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // NOTE: all imports are now named as to not make breaking changes
2
2
  // and to keep react-native working with cjs modules.
3
3
  import * as constants from './constants';
4
+ import * as form from './form';
4
5
  export { default as debug, enableDebug } from './debug';
5
6
  export { GraphQLRequestClient, } from './graphql-request-client';
6
7
  export { DefaultRetryStrategy } from './retries';
@@ -8,4 +9,5 @@ export { MemoryCacheClient } from './cache-client';
8
9
  export { ClientError } from 'graphql-request';
9
10
  export { NativeDataFetcher, } from './native-fetcher';
10
11
  export { constants };
12
+ export { form };
11
13
  export { defineConfig } from './config';
@@ -0,0 +1,34 @@
1
+ import chalk from 'chalk';
2
+ import { DEFAULT_SITECORE_AUTH_AUDIENCE, DEFAULT_SITECORE_AUTH_ENDPOINT } from '../../constants';
3
+ /**
4
+ * Connects to M2M endpoint and fetches the bearer token
5
+ * Uses client_id and client_secret from environment variables
6
+ * @param {FetchBearerTokenOptions} options client id, secret, and other parameters for connection to m2m endpoint
7
+ * @returns {string} bearer token string
8
+ */
9
+ export const fetchBearerToken = async (options) => {
10
+ const { clientId, clientSecret } = options;
11
+ const audience = options.audience || DEFAULT_SITECORE_AUTH_AUDIENCE;
12
+ const endpoint = options.endpoint || DEFAULT_SITECORE_AUTH_ENDPOINT;
13
+ try {
14
+ // TODO:adjust when M2M endpoint is live
15
+ const authenticateResponse = await fetch(endpoint, {
16
+ method: 'POST',
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ },
20
+ body: JSON.stringify({
21
+ client_id: clientId,
22
+ client_secret: clientSecret,
23
+ audience: audience,
24
+ grant_type: 'client_credentials',
25
+ }),
26
+ });
27
+ const jsonResponse = await authenticateResponse.json();
28
+ return jsonResponse.access_token;
29
+ }
30
+ catch (error) {
31
+ console.error(chalk.red('Error authenticating with Sitecore Auth endpoint:', error));
32
+ return null;
33
+ }
34
+ };
@@ -2,3 +2,4 @@ export { generateSites } from './generateSites';
2
2
  export { generateMetadata } from './generateMetadata';
3
3
  export { scaffoldComponent } from './scaffold';
4
4
  export * from './templating';
5
+ export { fetchBearerToken } from './auth/fetch-bearer-token';
@@ -160,7 +160,7 @@ export const areURLSearchParamsEqual = (params1, params2) => {
160
160
  * @returns {string} - The modified string or regex with non-special "?" characters escaped.
161
161
  */
162
162
  export const escapeNonSpecialQuestionMarks = (input) => {
163
- const regexPattern = /(?<!\\)\?/g; // Match unescaped "?" characters
163
+ const regexPattern = /(\\)?\?/g; // Match "?" that may or may not be preceded by a backslash
164
164
  const negativeLookaheadPattern = /\(\?!$/; // Detect the start of a Negative Lookahead pattern
165
165
  const specialRegexSymbols = /[.*+)\[\]|\(]$/; // Check for special regex symbols before "?"
166
166
  let result = '';
@@ -169,12 +169,14 @@ export const escapeNonSpecialQuestionMarks = (input) => {
169
169
  while ((match = regexPattern.exec(input)) !== null) {
170
170
  const index = match.index; // Position of the "?" in the string
171
171
  const before = input.slice(lastIndex, index); // Context before the "?"
172
+ // Check if "?" is preceded by a backslash (escaped)
173
+ const isEscaped = match[1] !== undefined; // match[1] is the backslash group
172
174
  // Check if "?" is part of a Negative Lookahead
173
175
  const isNegativeLookahead = negativeLookaheadPattern.test(before.slice(-3));
174
176
  // Check if "?" follows a special regex symbol
175
177
  const isSpecialRegexSymbol = specialRegexSymbols.test(before.slice(-1));
176
- if (isNegativeLookahead || isSpecialRegexSymbol) {
177
- // If it's a special case, keep the "?" as is
178
+ if (isEscaped || isNegativeLookahead || isSpecialRegexSymbol) {
179
+ // If it's escaped, part of a Negative Lookahead, or follows a special regex symbol, keep the "?" as is
178
180
  result += input.slice(lastIndex, index + 1);
179
181
  }
180
182
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/core",
3
- "version": "0.2.0-beta.4",
3
+ "version": "0.2.0-beta.6",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -15,7 +15,7 @@
15
15
  "test": "mocha \"./src/**/*.test.ts\"",
16
16
  "prepublishOnly": "npm run build",
17
17
  "coverage": "nyc npm test",
18
- "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --outputFileStrategy Members --parametersFormat table --readme none --out ../../ref-docs/core --entryPoints src/index.ts --entryPoints src/config/index.ts --entryPoints src/form/index.ts --entryPoints src/client/index.ts --entryPoints src/i18n/index.ts --entryPoints src/layout/index.ts --entryPoints src/media/index.ts --entryPoints src/personalize/index.ts --entryPoints src/site/index.ts --entryPoints src/tracking/index.ts --entryPoints src/utils/index.ts --entryPoints src/editing/index.ts --entryPoints src/tools/index.ts --githubPages false"
18
+ "generate-docs": "npx typedoc --plugin typedoc-plugin-markdown --outputFileStrategy Members --parametersFormat table --readme none --out ../../ref-docs/core --entryPoints src/index.ts --entryPoints src/config/index.ts --entryPoints src/client/index.ts --entryPoints src/i18n/index.ts --entryPoints src/layout/index.ts --entryPoints src/media/index.ts --entryPoints src/personalize/index.ts --entryPoints src/site/index.ts --entryPoints src/tracking/index.ts --entryPoints src/utils/index.ts --entryPoints src/editing/index.ts --entryPoints src/tools/index.ts src/content/index.ts --githubPages false"
19
19
  },
20
20
  "engines": {
21
21
  "node": ">=22"
@@ -58,7 +58,7 @@
58
58
  "nock": "14.0.0-beta.7",
59
59
  "nyc": "^17.1.0",
60
60
  "proxyquire": "^2.1.3",
61
- "sinon": "^19.0.2",
61
+ "sinon": "^20.0.0",
62
62
  "tslib": "^2.8.1",
63
63
  "tsx": "^4.19.2",
64
64
  "typescript": "~5.7.3"
@@ -77,7 +77,7 @@
77
77
  },
78
78
  "description": "",
79
79
  "types": "types/index.d.ts",
80
- "gitHead": "750ea744c6ba45e5480c921acf549ec48c53b303",
80
+ "gitHead": "a56ee0c0a3897b5f9915329e20469fa427ee13a8",
81
81
  "files": [
82
82
  "dist",
83
83
  "types",
@@ -5,3 +5,5 @@ export declare enum SitecoreTemplateId {
5
5
  export declare const siteNameError = "The siteName cannot be empty";
6
6
  export declare const SITECORE_EDGE_URL_DEFAULT = "https://edge-platform.sitecorecloud.io";
7
7
  export declare const HIDDEN_RENDERING_NAME = "Hidden Rendering";
8
+ export declare const DEFAULT_SITECORE_AUTH_ENDPOINT = "https://auth.sitecorecloud.io/oauth/token";
9
+ export declare const DEFAULT_SITECORE_AUTH_AUDIENCE = "https://api.sitecorecloud.io";
@@ -0,0 +1,59 @@
1
+ import { DocumentNode } from 'graphql';
2
+ import { GraphQLRequestClient } from '../graphql-request-client';
3
+ import { FetchOptions } from '../models';
4
+ /**
5
+ * Interface representing the options for the ContentClient.
6
+ */
7
+ export interface ContentClientOptions {
8
+ /** The base URL for the Content API. */
9
+ url?: string;
10
+ /** The tenant name. */
11
+ tenant: string;
12
+ /** The environment name. */
13
+ environment: string;
14
+ /** Indicates if preview mode is enabled. */
15
+ preview?: boolean;
16
+ /** The authentication token. */
17
+ token: string;
18
+ }
19
+ /**
20
+ * Class representing a client for interacting with the Content API.
21
+ */
22
+ export declare class ContentClient {
23
+ endpoint: string;
24
+ graphqlClient: GraphQLRequestClient;
25
+ constructor({ url, tenant, environment, preview, token }: ContentClientOptions);
26
+ /**
27
+ * Factory method for creating a ContentClient instance. This method allows you to create a client with the values populated from environment variables or provided as arguments.
28
+ * @param {Partial<ContentClientOptions>} [options] - client configuration options
29
+ * @param {string} [options.url] - Content base graphql endpoint url. If not provided, it will be read from the SITECORE_CS_URL environment variable. Otherwise, it defaults to https://cs-graphqlapi-staging.sitecore-staging.cloud.
30
+ * @param {string} [options.tenant] - Tenant name. If not provided, it will be read from the SITECORE_CS_TENANT environment variable
31
+ * @param {string} [options.environment] - Environment name. If not provided, it will be read from the SITECORE_CS_ENVIRONMENT environment variable. Otherwise, it defaults to 'main'
32
+ * @param {boolean} [options.preview] - Indicates if preview mode is enabled. If not provided, it will be read from the SITECORE_CS_PREVIEW environment variable. Otherwise, it defaults to false
33
+ * @param {string} [options.token] - Token for authentication. If not provided, it will be read from the SITECORE_CS_TOKEN environment variable.
34
+ * @returns {ContentClient} ContentClient instance
35
+ * @throws {Error} If tenant or token is not provided
36
+ */
37
+ static createClient({ url, tenant, environment, preview, token, }?: Partial<ContentClientOptions>): ContentClient;
38
+ /**
39
+ * Execute graphql request
40
+ * @param {string | DocumentNode} query graphql query
41
+ * @param {object} variables variables for the query
42
+ * @param {FetchOptions} options options for configuring the request
43
+ * @returns {T} response data
44
+ */
45
+ get<T>(query: string | DocumentNode, variables?: Record<string, unknown>, options?: FetchOptions): Promise<T>;
46
+ /**
47
+ * Retrieves the locale information for a given locale ID.
48
+ *
49
+ * @param id - The unique identifier of the locale item.
50
+ * @returns A promise that resolves to the locale information associated with the specified locale ID.
51
+ */
52
+ getLocale(id: string): Promise<import("./locales").Locale | null>;
53
+ /**
54
+ * Retrieves all available locales from the content service.
55
+ *
56
+ * @returns A promise that resolves to an array of locales.
57
+ */
58
+ getLocales(): Promise<import("./locales").Locale[]>;
59
+ }
@@ -0,0 +1,3 @@
1
+ export { ContentClient, ContentClientOptions } from './content-client';
2
+ export { GET_LOCALE_QUERY, GET_LOCALES_QUERY, LocaleQueryResponse, LocalesQueryResponse, Locale, } from './locales';
3
+ export { getContentUrl } from './utils';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Represents the response structure for a query that retrieves a locale.
3
+ */
4
+ export interface LocaleQueryResponse {
5
+ locale: Locale | null;
6
+ }
7
+ /**
8
+ * Represents the response structure for a query that retrieves multiple locales.
9
+ */
10
+ export interface LocalesQueryResponse {
11
+ manyLocale: Locale[];
12
+ }
13
+ /**
14
+ * Represents a locale with an id and a label.
15
+ */
16
+ export type Locale = {
17
+ /** The unique identifier for the locale. */
18
+ id: string;
19
+ /** The display name or label for the locale. */
20
+ label: string;
21
+ };
22
+ /**
23
+ * GraphQL query to retrieve a specific locale by its ID.
24
+ *
25
+ * Variables:
26
+ * - id: The ID of the locale to retrieve.
27
+ */
28
+ export declare const GET_LOCALE_QUERY = "\n query GetLocaleById ($id: ID!) {\n locale(id: $id) {\n id\n label\n }\n }\n";
29
+ /**
30
+ * GraphQL query to retrieve all available locales.
31
+ */
32
+ export declare const GET_LOCALES_QUERY = "\n query GetAllLocales{\n manyLocale {\n id\n label\n }\n }\n";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Get the Content graphql endpoint url
3
+ * @param {object} params Parameters
4
+ * @param {string} [params.url] Content base graphql endpoint url
5
+ * @param {string} params.tenant Tenant name
6
+ * @param {string} params.environment Environment name
7
+ * @param {boolean} params.preview Indicates if preview mode is enabled
8
+ * @returns {string} Content graphql endpoint url
9
+ */
10
+ export declare function getContentUrl({ url, tenant, environment, preview, }: {
11
+ url?: string;
12
+ tenant: string;
13
+ environment: string;
14
+ preview: boolean;
15
+ }): string;
package/types/debug.d.ts CHANGED
@@ -11,6 +11,7 @@ export declare const enableDebug: (namespaces: string) => void;
11
11
  */
12
12
  declare const _default: {
13
13
  common: debug.Debugger;
14
+ content: debug.Debugger;
14
15
  form: debug.Debugger;
15
16
  http: debug.Debugger;
16
17
  layout: debug.Debugger;
package/types/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as constants from './constants';
2
+ import * as form from './form';
2
3
  export { default as debug, Debugger, enableDebug } from './debug';
3
4
  export { GraphQLClient, GraphQLRequestClient, GraphQLRequestClientConfig, GraphQLRequestClientFactory, GraphQLRequestClientFactoryConfig, } from './graphql-request-client';
4
5
  export { DefaultRetryStrategy } from './retries';
@@ -7,4 +8,5 @@ export { ClientError } from 'graphql-request';
7
8
  export { NativeDataFetcher, NativeDataFetcherConfig, NativeDataFetcherError, NativeDataFetcherResponse, } from './native-fetcher';
8
9
  export { HTMLLink, RetryStrategy, GenericGraphQLClientError, StaticPath } from './models';
9
10
  export { constants };
11
+ export { form };
10
12
  export { defineConfig } from './config';
@@ -0,0 +1,13 @@
1
+ export type FetchBearerTokenOptions = {
2
+ clientId: string;
3
+ clientSecret: string;
4
+ audience?: string;
5
+ endpoint?: string;
6
+ };
7
+ /**
8
+ * Connects to M2M endpoint and fetches the bearer token
9
+ * Uses client_id and client_secret from environment variables
10
+ * @param {FetchBearerTokenOptions} options client id, secret, and other parameters for connection to m2m endpoint
11
+ * @returns {string} bearer token string
12
+ */
13
+ export declare const fetchBearerToken: (options: FetchBearerTokenOptions) => Promise<any>;
@@ -2,3 +2,4 @@ export { generateSites, GenerateSitesConfig } from './generateSites';
2
2
  export { generateMetadata } from './generateMetadata';
3
3
  export { scaffoldComponent } from './scaffold';
4
4
  export * from './templating';
5
+ export { fetchBearerToken } from './auth/fetch-bearer-token';
package/form.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './types/form/index';
package/form.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./dist/cjs/form/index');