UNPKG

@sitecore-jss/sitecore-jss

Version:

This module is provided as a part of Sitecore JavaScript Rendering SDK. It contains the core JSS APIs (layout service) and utilities.

208 lines (207 loc) • 8.43 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphQLDictionaryService = exports.queryError = void 0; const constants_1 = require("../constants"); const dictionary_service_1 = require("./dictionary-service"); const graphql_1 = require("../graphql"); const app_root_query_1 = require("../graphql/app-root-query"); const debug_1 = __importDefault(require("../debug")); /** @private */ exports.queryError = 'Valid value for rootItemId not provided and failed to auto-resolve app root item.'; /** @default */ const query = /* GraphQL */ ` query DictionarySearch( $rootItemId: String! $language: String! $templates: String! $pageSize: Int = 10 $after: String ) { search( where: { AND: [ { name: "_path", value: $rootItemId, operator: CONTAINS } { name: "_language", value: $language } { name: "_templates", value: $templates, operator: CONTAINS } ] } first: $pageSize after: $after ) { total pageInfo { endCursor hasNext } results { key: field(name: "Key") { value } phrase: field(name: "Phrase") { value } } } } `; const siteQuery = /* GraphQL */ ` query DictionarySiteQuery( $siteName: String! $language: String! $pageSize: Int = 500 $after: String ) { site { siteInfo(site: $siteName) { dictionary(language: $language, first: $pageSize, after: $after) { pageInfo { endCursor hasNext } results { key value } } } } } `; /** * Service that fetch dictionary data using Sitecore's GraphQL API. * @augments DictionaryServiceBase * @mixes SearchQueryService<DictionaryQueryResult> */ class GraphQLDictionaryService extends dictionary_service_1.DictionaryServiceBase { /** * Creates an instance of graphQL dictionary service with the provided options * @param {GraphQLDictionaryService} options instance */ constructor(options) { super(options); this.options = options; this.graphQLClient = this.getGraphQLClient(); this.searchService = new graphql_1.SearchQueryService(this.graphQLClient); } /** * Fetches dictionary data for internalization. Uses search query by default * @param {string} language the language to fetch * @returns {Promise<DictionaryPhrases>} dictionary phrases * @throws {Error} if the app root was not found for the specified site and language. */ fetchDictionaryData(language) { return __awaiter(this, void 0, void 0, function* () { const cacheKey = this.options.siteName + language; const cachedValue = this.getCacheValue(cacheKey); if (cachedValue) { debug_1.default.dictionary('using cached dictionary data for %s %s', language, this.options.siteName); return cachedValue; } const phrases = this.options.useSiteQuery ? yield this.fetchWithSiteQuery(language) : yield this.fetchWithSearchQuery(language); this.setCacheValue(cacheKey, phrases); return phrases; }); } /** * Fetches dictionary data with search query * This is the default behavior for non-XMCloud deployments. Uses `query` to retrieve data. * @param {string} language the language to fetch * @returns {Promise<DictionaryPhrases>} dictionary phrases * @throws {Error} if the app root was not found for the specified site and language. */ fetchWithSearchQuery(language) { return __awaiter(this, void 0, void 0, function* () { debug_1.default.dictionary('fetching site root for %s %s', language, this.options.siteName); // If the caller does not specify a root item ID, then we try to figure it out const rootItemId = this.options.rootItemId || (yield (0, graphql_1.getAppRootId)(this.graphQLClient, this.options.siteName, language, this.options.jssAppTemplateId)); if (!rootItemId) { throw new Error(exports.queryError); } debug_1.default.dictionary('fetching dictionary data for %s %s', language, this.options.siteName); const phrases = {}; yield this.searchService .fetch(query, { rootItemId, language, templates: this.options.dictionaryEntryTemplateId || constants_1.SitecoreTemplateId.DictionaryEntry, pageSize: this.options.pageSize, }) .then((results) => { results.forEach((item) => (phrases[item.key.value] = item.phrase.value)); }); return phrases; }); } /** * Fetches dictionary data with site query * This is the default behavior for XMCloud deployments. Uses `siteQuery` to retrieve data. * @param {string} language the language to fetch * @returns {Promise<DictionaryPhrases>} dictionary phrases */ fetchWithSiteQuery(language) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const phrases = {}; debug_1.default.dictionary('fetching dictionary data for %s %s', language, this.options.siteName); let results = []; let hasNext = true; let after = ''; if (!this.options.siteName) { throw new RangeError(app_root_query_1.siteNameError); } if (!language) { throw new RangeError(app_root_query_1.languageError); } while (hasNext) { const fetchResponse = yield this.graphQLClient.request(siteQuery, { siteName: this.options.siteName, language, pageSize: this.options.pageSize, after, }); if ((_b = (_a = fetchResponse === null || fetchResponse === void 0 ? void 0 : fetchResponse.site) === null || _a === void 0 ? void 0 : _a.siteInfo) === null || _b === void 0 ? void 0 : _b.dictionary) { results = results.concat(fetchResponse.site.siteInfo.dictionary.results); after = fetchResponse.site.siteInfo.dictionary.pageInfo.endCursor; hasNext = fetchResponse.site.siteInfo.dictionary.pageInfo.hasNext; } else { hasNext = false; } } results.forEach((item) => (phrases[item.key] = item.value)); return phrases; }); } /** * Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default * library for fetching graphql data (@see GraphQLRequestClient). Override this method if you * want to use something else. * @returns {GraphQLClient} implementation */ getGraphQLClient() { if (!this.options.clientFactory) { throw new Error('clientFactory needs to be provided when initializing GraphQL client.'); } return this.options.clientFactory({ debugger: debug_1.default.dictionary, retries: this.options.retries, retryStrategy: this.options.retryStrategy, }); } } exports.GraphQLDictionaryService = GraphQLDictionaryService;