@volvo-cars/content-delivery-client
Advanced tools
Comparing version 0.4.6 to 0.5.0
export {}; |
export {}; |
export {}; |
@@ -0,0 +0,0 @@ /// <reference types="node" /> |
@@ -0,0 +0,0 @@ import type { ClientConfig } from '..'; |
import { Dictionary } from './types'; | ||
export declare function getLocalDictionary(canonicalDictionaryName: string, rootPath: string): Promise<Dictionary['items']>; | ||
export declare function getLocalDictionaries(canonicalDictionaryNames: string[], rootPath: string): Promise<[string, Dictionary['items']][]>; |
@@ -0,0 +0,0 @@ export type DictionaryItems = { |
@@ -0,0 +0,0 @@ import type { ContentEnvironment } from '../ContentDeliveryClient'; |
import { ClientConfig, GetOptions } from '../ContentDeliveryClient'; | ||
export declare function fetchEntry<T>(canonicalName: string, config: ClientConfig, options: GetOptions): Promise<T>; |
export declare function getLocalEntry<T>(canonicalEntryName: string, rootPath: string): Promise<T>; |
import { ClientConfig, GetOptions } from '../ContentDeliveryClient'; | ||
import { ContentType, ListEntriesResponseData } from './types'; | ||
export declare function listEntries<T extends ContentType>(contentType: T, config: ClientConfig, options: GetOptions): Promise<ListEntriesResponseData<T>>; |
declare const traverse: (obj: any) => any; | ||
export default traverse; |
@@ -0,0 +0,0 @@ export type ContentType = 'ContentType' | 'EditorialComponent' | 'PageType'; |
@@ -0,0 +0,0 @@ import type { ContentEnvironment } from './ContentDeliveryClient'; |
@@ -0,0 +0,0 @@ export { createClient } from './ContentDeliveryClient'; |
@@ -13,3 +13,2 @@ import flatten from 'flat'; | ||
const stale = []; | ||
for (const name of canonicalDictionaryNames) { | ||
@@ -28,3 +27,2 @@ if (!cache.has({ | ||
} | ||
return { | ||
@@ -42,7 +40,5 @@ missing, | ||
this.isValidating = false; | ||
if (!config.path) { | ||
throw new TypeError(`'path' to local fallback content missing in config. Required when using local data options.`); | ||
} | ||
this.config = config; | ||
@@ -52,10 +48,8 @@ this.applicationId = config.applicationId; | ||
} | ||
async getDictionary(canonicalDictionaryName, _options) { | ||
var _this$config$path; | ||
validateCanonicalDictionaryName(canonicalDictionaryName); | ||
const { | ||
getLocalDictionary | ||
} = await import('./getLocalDictionaries-2f9f1d49.js'); | ||
} = await import('./getLocalDictionaries-687d3c8d.js'); | ||
return this.flattenDictionaries({ | ||
@@ -65,35 +59,27 @@ [canonicalDictionaryName]: await getLocalDictionary(canonicalDictionaryName, (_this$config$path = this.config.path) != null ? _this$config$path : '') | ||
} | ||
async getDictionaries(canonicalDictionaryNames, _options) { | ||
var _this$config$path2; | ||
const { | ||
getLocalDictionaries | ||
} = await import('./getLocalDictionaries-2f9f1d49.js'); | ||
} = await import('./getLocalDictionaries-687d3c8d.js'); | ||
canonicalDictionaryNames.forEach(validateCanonicalDictionaryName); | ||
return this.flattenDictionaries(Object.fromEntries(await getLocalDictionaries(canonicalDictionaryNames, (_this$config$path2 = this.config.path) != null ? _this$config$path2 : ''))); | ||
} | ||
async getAllDictionaries(_options) { | ||
var _this$config$path3; | ||
const { | ||
getLocalDictionaries | ||
} = await import('./getLocalDictionaries-2f9f1d49.js'); | ||
} = await import('./getLocalDictionaries-687d3c8d.js'); | ||
return this.flattenDictionaries(Object.fromEntries(await getLocalDictionaries([], (_this$config$path3 = this.config.path) != null ? _this$config$path3 : ''))); | ||
} | ||
async getEntry(_canonicalName, _options) { | ||
var _this$config$path4; | ||
const { | ||
getLocalEntry | ||
} = await import('./getLocalEntry-3337a1be.js'); | ||
} = await import('./getLocalEntry-98f1ae6f.js'); | ||
return getLocalEntry(_canonicalName, (_this$config$path4 = this.config.path) != null ? _this$config$path4 : ''); | ||
} | ||
async listEntries(_contentType, _options) { | ||
return []; | ||
} | ||
async flattenDictionaries(target) { | ||
@@ -105,3 +91,2 @@ const { | ||
} | ||
} | ||
@@ -118,3 +103,2 @@ | ||
} | ||
} | ||
@@ -126,3 +110,2 @@ class ContentDeliveryClientError extends Error { | ||
} | ||
} | ||
@@ -134,3 +117,2 @@ class ContentDeliveryClientValidationError extends ContentDeliveryClientError { | ||
} | ||
} | ||
@@ -144,3 +126,2 @@ class TimeoutError extends Error { | ||
} | ||
} | ||
@@ -169,9 +150,6 @@ class ContentDeliveryError extends Error { | ||
this.locale = locale; | ||
if (market) { | ||
this.market = market; | ||
} | ||
this.environment = environment; | ||
if (error) { | ||
@@ -187,3 +165,2 @@ if (Array.isArray(error)) { | ||
} | ||
} | ||
@@ -196,7 +173,6 @@ class DictionaryNotFoundError extends ContentDeliveryError { | ||
} | ||
} | ||
// Market nodes are expected to have the same name as the region/country | ||
// in English with whitespace removed, unless otherwise specified here. | ||
const marketNodeNames = { | ||
@@ -214,13 +190,9 @@ AE: 'AE', | ||
*/ | ||
function getMarketItemName(siteSlug) { | ||
const market = getMarketSite(siteSlug); | ||
if (market.regionCode && market.marketName) { | ||
let itemName = marketNodeNames[market.regionCode] || market.marketName.replace(/\s/g, ''); | ||
if (minisites.includes(market.regionCode)) { | ||
itemName = 'minisites/' + itemName; | ||
} | ||
return itemName; | ||
@@ -236,3 +208,2 @@ } | ||
} | ||
run() { | ||
@@ -242,3 +213,2 @@ if (this.timeoutId) { | ||
} | ||
return new Promise((_, reject) => { | ||
@@ -248,3 +218,2 @@ if (this.timeout) { | ||
var _this$timeout; | ||
reject(new TimeoutError((_this$timeout = this.timeout) != null ? _this$timeout : -1)); | ||
@@ -255,3 +224,2 @@ }, this.timeout * 1000); | ||
} | ||
clear() { | ||
@@ -262,3 +230,2 @@ if (this.timeoutId) { | ||
} | ||
} | ||
@@ -284,3 +251,2 @@ | ||
var _fetchOptions; | ||
const timer = new Timeout(timeout); | ||
@@ -290,14 +256,10 @@ const url = new URL(BASE_API_URL); | ||
url.searchParams.set('Locale', locale); | ||
if (dataSource) { | ||
url.searchParams.set('DataSource', dataSource); | ||
} // Remove when CM Admin supports `environment` param | ||
} | ||
// Remove when CM Admin supports `environment` param | ||
if (environment === 'authoringPreview') { | ||
url.searchParams.set('preview', 'true'); | ||
} | ||
url.searchParams.set('environment', environment); | ||
if (market) { | ||
@@ -308,3 +270,2 @@ const { | ||
const marketItemName = getMarketItemName(siteSlug); | ||
if (marketItemName) { | ||
@@ -314,19 +275,15 @@ url.searchParams.set('market', marketItemName); | ||
} | ||
if (contentType) { | ||
url.searchParams.set('contentType', contentType); | ||
} | ||
if (limit) { | ||
url.searchParams.set('limit', limit.toString()); | ||
} | ||
let fetchOptions = config.fetchOptions; | ||
if (typeof window === 'undefined' && typeof ((_fetchOptions = fetchOptions) == null ? void 0 : _fetchOptions.agent) === 'undefined') { | ||
fetchOptions = { ...fetchOptions, | ||
fetchOptions = { | ||
...fetchOptions, | ||
agent: await getKeepAliveAgent() | ||
}; | ||
} | ||
const response = await Promise.race([timer.run(), fetch(url.href, { | ||
@@ -348,6 +305,5 @@ headers: { | ||
})]); | ||
if (response.status === 429 && retry && !timeout) { | ||
const retryAfter = Number(response.headers.get('Retry-After') || 10) + 5; // Avoid blocking for too long time | ||
const retryAfter = Number(response.headers.get('Retry-After') || 10) + 5; | ||
// Avoid blocking for too long time | ||
if (retryAfter <= 120) { | ||
@@ -373,13 +329,9 @@ console.warn(`Too many requests. Retrying in ${retryAfter} seconds...`); | ||
} | ||
const result = await response.json(); | ||
if (response.ok && 'data' in result && result.status === 200) { | ||
return result.data; | ||
} | ||
throw new RequestError('error' in result ? result.error.message : result.message, response.status, response.url); | ||
} | ||
let keepAliveAgent; | ||
async function getKeepAliveAgent() { | ||
@@ -396,3 +348,2 @@ if (!keepAliveAgent) { | ||
} | ||
return keepAliveAgent; | ||
@@ -408,3 +359,2 @@ } | ||
let dictionary; | ||
try { | ||
@@ -419,10 +369,8 @@ dictionary = await fetchDictionary(canonicalDictionaryName, config, options); | ||
} | ||
return [canonicalDictionaryName, dictionary]; | ||
}))).filter(([, value]) => !!value); // If a single dictionary failed, throw an error but include the successful | ||
}))).filter(([, value]) => !!value); | ||
// If a single dictionary failed, throw an error but include the successful | ||
// fetches on the `data` property. | ||
if (errors.length > 0) { | ||
let error; | ||
if (errors.length === 1) { | ||
@@ -432,3 +380,2 @@ error = errors[0]; | ||
var _options$environment; | ||
error = new DictionaryNotFoundError(`${errors.length} dictionaries not found`, { | ||
@@ -442,7 +389,5 @@ applicationId: config.applicationId, | ||
} | ||
error.data = dictionaries; | ||
throw error; | ||
} | ||
return dictionaries; | ||
@@ -458,6 +403,4 @@ } | ||
} | ||
async function sendFetchDictionary(canonicalDictionaryName, config, options) { | ||
var _options$environment2; | ||
const requestDetails = { | ||
@@ -473,5 +416,5 @@ applicationId: config.applicationId, | ||
let results; | ||
try { | ||
results = await sendRequest({ ...requestDetails, | ||
results = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -483,3 +426,2 @@ path: `/dictionaries/${canonicalDictionaryName}`, | ||
let message = `Failed fetching dictionary '${canonicalDictionaryName}'`; | ||
if (error instanceof RequestError) { | ||
@@ -492,3 +434,2 @@ if (error.status === 404) { | ||
} | ||
if (error.message.includes(canonicalDictionaryName)) { | ||
@@ -499,3 +440,2 @@ // Throw a NotFoundError to allow catching and falling back to local data | ||
} | ||
message += ` '${error.status}: ${error.message}'`; | ||
@@ -505,12 +445,8 @@ } else if (error.message) { | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
return results.items; | ||
} | ||
async function sendFetchAllDictionaries(config, options) { | ||
var _options$environment3; | ||
const requestDetails = { | ||
@@ -526,5 +462,5 @@ applicationId: config.applicationId, | ||
let results; | ||
try { | ||
results = await sendRequest({ ...requestDetails, | ||
results = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -536,3 +472,2 @@ path: '/dictionaries', | ||
let message = `Failed fetching dictionaries`; | ||
if (error instanceof RequestError) { | ||
@@ -544,3 +479,2 @@ // 404 will be returned from ListDictionaries endpoint if the application | ||
} | ||
message += ` '${error.status}: ${error.message}'`; | ||
@@ -550,6 +484,4 @@ } else if (error.message) { | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
if (results.length === 0) { | ||
@@ -559,3 +491,2 @@ // Throw a NotFoundError to allow catching and falling back to local data | ||
} | ||
return results; | ||
@@ -566,17 +497,13 @@ } | ||
var _obj$file, _obj$file2; | ||
if (typeof obj !== 'object' || !obj) return handleBooleans(obj); // handle images and files | ||
if (typeof obj !== 'object' || !obj) return handleBooleans(obj); | ||
// handle images and files | ||
if (obj != null && (_obj$file = obj.file) != null && _obj$file.mediaType || obj != null && (_obj$file2 = obj.file) != null && _obj$file2.details) { | ||
return transformImageOrFile(obj); | ||
} | ||
if (Array.isArray(obj)) { | ||
return obj.map(traverse); | ||
} | ||
if ('fields' in obj && Object.keys(obj.fields).length === 0) { | ||
return {}; | ||
} | ||
return Object.entries(obj).reduce((acc, [key, value]) => { | ||
@@ -586,3 +513,2 @@ // rename fields and flatten renderingParams | ||
var _obj$contentType; | ||
if ((obj == null ? void 0 : (_obj$contentType = obj.contentType) == null ? void 0 : _obj$contentType.type) === 'EditorialComponent' && key === 'fields') { | ||
@@ -599,3 +525,2 @@ acc['content'] = traverse(value); | ||
} | ||
acc[key] = traverse(value); | ||
@@ -606,17 +531,12 @@ } else if (key !== 'sys') { | ||
} | ||
return acc; | ||
}, {}); | ||
}; | ||
function transformImageOrFile(value) { | ||
var _value$file, _value$file2, _value$file2$mediaTyp, _value$file9, _value$file10; | ||
if (!(value != null && (_value$file = value.file) != null && _value$file.url)) { | ||
return null; | ||
} | ||
if (value != null && (_value$file2 = value.file) != null && (_value$file2$mediaTyp = _value$file2.mediaType) != null && _value$file2$mediaTyp.includes('image')) { | ||
var _value$file3, _value$file4, _value$file4$details, _value$file4$details$, _value$file5, _value$file6, _value$file7, _value$file7$details, _value$file7$details$, _value$file8, _value$file8$details, _value$file8$details$; | ||
return { | ||
@@ -631,3 +551,2 @@ src: (value == null ? void 0 : (_value$file3 = value.file) == null ? void 0 : _value$file3.url) || '', | ||
} | ||
return { | ||
@@ -640,3 +559,2 @@ mimeType: (value == null ? void 0 : (_value$file9 = value.file) == null ? void 0 : _value$file9.mediaType) || '', | ||
} | ||
function handleBooleans(value) { | ||
@@ -648,3 +566,2 @@ return value === 'true' ? true : value === 'false' ? false : typeof value === 'undefined' ? null : value; | ||
var _options$environment; | ||
const requestDetails = { | ||
@@ -660,5 +577,5 @@ applicationId: config.applicationId, | ||
let result; | ||
try { | ||
result = await sendRequest({ ...requestDetails, | ||
result = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -670,3 +587,2 @@ path: `/entries/${canonicalName}`, | ||
let message = 'Failed fetching entry'; | ||
if (error instanceof RequestError) { | ||
@@ -677,6 +593,4 @@ message += ` '${error.status}: ${error.message}'`; | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
return traverse(result); | ||
@@ -687,3 +601,2 @@ } | ||
var _options$environment; | ||
const requestDetails = { | ||
@@ -696,7 +609,8 @@ applicationId: config.applicationId, | ||
market: options.market, | ||
timeout: options.timeout, | ||
contentType | ||
}; | ||
try { | ||
const result = await sendRequest({ ...requestDetails, | ||
const result = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -709,3 +623,2 @@ path: `/entries`, | ||
let message = 'Failed fetching entries list'; | ||
if (error instanceof RequestError) { | ||
@@ -716,3 +629,2 @@ message += ` '${error.status}: ${error.message}'`; | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
@@ -738,3 +650,2 @@ } | ||
} | ||
set(keyConfig, value) { | ||
@@ -745,7 +656,5 @@ const cacheKey = getCacheKey(keyConfig); | ||
} | ||
has(keyConfig) { | ||
return this.values.has(getCacheKey(keyConfig)); | ||
} | ||
get(keyConfig) { | ||
@@ -757,21 +666,14 @@ return this.values.get(getCacheKey(keyConfig)); | ||
*/ | ||
isStale(keyConfig) { | ||
var _this$lastUpdated$get; | ||
const cacheKey = getCacheKey(keyConfig); | ||
if (!this.lastUpdated.has(cacheKey)) { | ||
return false; | ||
} | ||
if (this.revalidateMs === 0) { | ||
return true; | ||
} | ||
const currentTime = this.now(); | ||
return currentTime - ((_this$lastUpdated$get = this == null ? void 0 : this.lastUpdated.get(cacheKey)) != null ? _this$lastUpdated$get : 0) >= this.revalidateMs; | ||
} | ||
delete(keyConfig) { | ||
@@ -781,3 +683,2 @@ const cacheKey = getCacheKey(keyConfig); | ||
} | ||
} | ||
@@ -812,3 +713,2 @@ function getCacheKey(config) { | ||
this.pendingRevalidations = 0; | ||
if (!config.allowedDataSources) { | ||
@@ -819,3 +719,2 @@ config.allowedDataSources = []; | ||
} | ||
if (!config.allowedEnvironments) { | ||
@@ -826,7 +725,5 @@ config.allowedEnvironments = []; | ||
} | ||
if (!config.defaultEnvironment) { | ||
config.defaultEnvironment = 'live'; | ||
} | ||
validateDataSourceAndEnvironment(config, { | ||
@@ -842,5 +739,5 @@ dataSource: config.defaultDataSource, | ||
}; | ||
if (typeof config.revalidate === 'object') { | ||
config.revalidate = { ...revalidate, | ||
config.revalidate = { | ||
...revalidate, | ||
...config.revalidate | ||
@@ -851,3 +748,2 @@ }; | ||
} | ||
this.applicationId = config.applicationId; | ||
@@ -862,10 +758,7 @@ this.defaultDataSource = config.defaultDataSource; | ||
} | ||
get isValidating() { | ||
return this.pendingRevalidations > 0; | ||
} | ||
async getDictionary(canonicalDictionaryName, rawOptions) { | ||
var _this$dictionariesCac2; | ||
validateCanonicalDictionaryName(canonicalDictionaryName); | ||
@@ -879,7 +772,7 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: canonicalDictionaryName, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || !this.dictionariesCache.has(cacheKey)) { | ||
@@ -894,7 +787,5 @@ try { | ||
var _this$dictionariesCac; | ||
this.logError('dictionaries', operationDetails, error); | ||
return flattenDictionaries([[canonicalDictionaryName, (_this$dictionariesCac = this.dictionariesCache.get(cacheKey)) != null ? _this$dictionariesCac : {}]]); | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -905,8 +796,6 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} // Fetch stale entry in the background, intentionally don't await | ||
} | ||
// Fetch stale entry in the background, intentionally don't await | ||
if (this.dictionariesCache.isStale(cacheKey)) { | ||
@@ -924,6 +813,4 @@ this.pendingRevalidations++; | ||
} | ||
return flattenDictionaries([[canonicalDictionaryName, (_this$dictionariesCac2 = this.dictionariesCache.get(cacheKey)) != null ? _this$dictionariesCac2 : {}]]); | ||
} | ||
async getDictionaries(canonicalDictionaryNames, rawOptions) { | ||
@@ -938,6 +825,6 @@ canonicalDictionaryNames.forEach(validateCanonicalDictionaryName); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || canonicalDictionaryNames.some(name => !this.dictionariesCache.has({ | ||
@@ -949,3 +836,2 @@ name, | ||
const dictionaries = await fetchDictionaries(canonicalDictionaryNames, this.config, options); | ||
for (const [name, items] of dictionaries) { | ||
@@ -957,3 +843,2 @@ this.dictionariesCache.set({ | ||
} | ||
return flattenDictionaries(dictionaries); | ||
@@ -969,6 +854,4 @@ } catch (error) { | ||
} | ||
error.data = flattenDictionaries(error.data); | ||
} | ||
if (canonicalDictionaryNames.every(name => this.dictionariesCache.has({ | ||
@@ -978,7 +861,6 @@ name, | ||
}))) { | ||
this.logError('dictionaries', operationDetails, error); // Return stale content if everything is now available in the cache | ||
this.logError('dictionaries', operationDetails, error); | ||
// Return stale content if everything is now available in the cache | ||
return flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac3; | ||
return [name, (_this$dictionariesCac3 = this.dictionariesCache.get({ | ||
@@ -990,3 +872,2 @@ name, | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -997,14 +878,12 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} | ||
const { | ||
missing, | ||
stale | ||
} = sortCanonicalDictionaryNames(canonicalDictionaryNames, this.dictionariesCache, cacheKey); // Fetch stale entries in the background, intentionally don't await | ||
} = sortCanonicalDictionaryNames(canonicalDictionaryNames, this.dictionariesCache, cacheKey); | ||
// Fetch stale entries in the background, intentionally don't await | ||
// Some might return before all missing requests are done, otherwise | ||
// they will be available at the next request | ||
stale.forEach(canonicalDictionaryName => { | ||
@@ -1024,9 +903,8 @@ this.pendingRevalidations++; | ||
}); | ||
}); // Fetch all missing dictionaries. | ||
}); | ||
// Fetch all missing dictionaries. | ||
// Errors are fatal unless there is a `localDataClient`. | ||
if (missing.length > 0) { | ||
try { | ||
const dictionaries = await fetchDictionaries(missing, this.config, options); | ||
for (const [name, items] of dictionaries) { | ||
@@ -1048,14 +926,12 @@ this.dictionariesCache.set({ | ||
} | ||
error.data = flattenDictionaries(error.data); | ||
} | ||
if (this.localDataClient) { | ||
this.logError('dictionaries', operationDetails, error); | ||
this.logFallback(); // Return everything that's in the cache, merged with the missing entries | ||
this.logFallback(); | ||
// Return everything that's in the cache, merged with the missing entries | ||
// from the local fallback | ||
return { ...flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
return { | ||
...flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac4; | ||
return [name, (_this$dictionariesCac4 = this.dictionariesCache.get({ | ||
@@ -1070,11 +946,8 @@ name, | ||
} | ||
throw error; | ||
} | ||
} // By now all requested dictionaries are available in the cache | ||
} | ||
// By now all requested dictionaries are available in the cache | ||
return flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac5; | ||
return [name, (_this$dictionariesCac5 = this.dictionariesCache.get({ | ||
@@ -1086,6 +959,4 @@ name, | ||
} | ||
async getAllDictionaries(rawOptions) { | ||
var _this$dictionariesLis2; | ||
const options = getOptionsWithDefaults(rawOptions, this.config); | ||
@@ -1098,21 +969,19 @@ validateDataSourceAndEnvironment(this.config, options); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: 'all', | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || !this.dictionariesListCache.has(cacheKey)) { | ||
try { | ||
const dictionaries = await fetchAllDictionaries(this.config, options); | ||
if (dictionaries.length > 0) { | ||
for (const [name, items] of dictionaries) { | ||
this.dictionariesCache.set({ ...cacheKey, | ||
this.dictionariesCache.set({ | ||
...cacheKey, | ||
name | ||
}, items); | ||
} | ||
this.dictionariesListCache.set(cacheKey, dictionaries); | ||
} | ||
return flattenDictionaries(dictionaries); | ||
@@ -1123,7 +992,5 @@ } catch (error) { | ||
var _this$dictionariesLis; | ||
this.logError('dictionaries', operationDetails, error); | ||
return flattenDictionaries((_this$dictionariesLis = this.dictionariesListCache.get(cacheKey)) != null ? _this$dictionariesLis : []); | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -1134,7 +1001,5 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} | ||
if (this.dictionariesListCache.isStale(cacheKey)) { | ||
@@ -1145,7 +1010,7 @@ // Fetch stale entries in the background, intentionally don't await | ||
for (const [name, items] of dictionaries) { | ||
this.dictionariesCache.set({ ...cacheKey, | ||
this.dictionariesCache.set({ | ||
...cacheKey, | ||
name | ||
}, items); | ||
} | ||
this.dictionariesListCache.set(cacheKey, dictionaries); | ||
@@ -1160,6 +1025,4 @@ }).catch(error => { | ||
} | ||
return flattenDictionaries((_this$dictionariesLis2 = this.dictionariesListCache.get(cacheKey)) != null ? _this$dictionariesLis2 : []); | ||
} | ||
async getEntry(canonicalName, rawOptions) { | ||
@@ -1173,15 +1036,13 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: canonicalName, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.entries === 0 || !this.entriesCache.has(cacheKey)) { | ||
try { | ||
const entry = await fetchEntry(canonicalName, this.config, options); | ||
if (this.entriesCache) { | ||
this.entriesCache.set(cacheKey, entry); | ||
} | ||
return entry; | ||
@@ -1192,5 +1053,4 @@ } catch (error) { | ||
} | ||
} // Fetch stale entry in the background, intentionally don't await | ||
} | ||
// Fetch stale entry in the background, intentionally don't await | ||
if (this.entriesCache.isStale(cacheKey)) { | ||
@@ -1204,6 +1064,5 @@ this.pendingRevalidations++; | ||
this.entriesCache.delete(cacheKey); | ||
} // Failing to refresh a stale entry is not a fatal error, because | ||
} | ||
// Failing to refresh a stale entry is not a fatal error, because | ||
// there's already some content in the cache. | ||
this.logError('entries', operationDetails, error); | ||
@@ -1214,6 +1073,4 @@ }).finally(() => { | ||
} | ||
return this.entriesCache.get(cacheKey); | ||
} | ||
async listEntries(contentType, rawOptions) { | ||
@@ -1227,15 +1084,13 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: contentType, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.listEntries === 0 || !this.listEntriesCache.has(cacheKey)) { | ||
try { | ||
const entriesList = await listEntries(contentType, this.config, options); | ||
if (this.listEntriesCache) { | ||
this.listEntriesCache.set(cacheKey, entriesList); | ||
} | ||
return entriesList; | ||
@@ -1246,5 +1101,4 @@ } catch (error) { | ||
} | ||
} // Fetch stale entries list in the background, intentionally don't await | ||
} | ||
// Fetch stale entries list in the background, intentionally don't await | ||
if (this.listEntriesCache.isStale(cacheKey)) { | ||
@@ -1262,6 +1116,4 @@ this.pendingRevalidations++; | ||
} | ||
return this.listEntriesCache.get(cacheKey); | ||
} | ||
logError(type, { | ||
@@ -1277,3 +1129,2 @@ locale, | ||
} | ||
logFallback() { | ||
@@ -1284,15 +1135,10 @@ if (process.env.NODE_ENV !== 'test') { | ||
} | ||
} | ||
function getMessages(error) { | ||
var _error$errors; | ||
const message = error.message; | ||
let childrenMessages = []; | ||
if ((_error$errors = error.errors) != null && _error$errors.length) { | ||
childrenMessages = error.errors.map(e => e.message); | ||
} | ||
return `${message}: | ||
@@ -1302,3 +1148,2 @@ ${childrenMessages.join('\n')} | ||
} | ||
function validateDataSourceAndEnvironment(config, options) { | ||
@@ -1308,3 +1153,2 @@ if (options.dataSource && config.allowedDataSources.length > 0 && !config.allowedDataSources.includes(options.dataSource)) { | ||
} | ||
if (options.environment && config.allowedEnvironments.length > 0 && !config.allowedEnvironments.includes(options.environment)) { | ||
@@ -1314,3 +1158,2 @@ throw new ContentDeliveryClientValidationError(options.environment, config.allowedEnvironments, 'config.allowedEnvironments'); | ||
} | ||
function flattenDictionaries(entries) { | ||
@@ -1328,3 +1171,2 @@ return flatten(Object.fromEntries(entries)); | ||
} | ||
if (typeof window !== 'undefined') { | ||
@@ -1334,3 +1176,2 @@ if (forceLocalData) { | ||
} | ||
if (fallbackToLocalData) { | ||
@@ -1343,3 +1184,2 @@ throw new Error(`The 'fallbackToLocalData' option is only available in SSR.`); | ||
} | ||
if (fallbackToLocalData) { | ||
@@ -1349,3 +1189,2 @@ return new RemoteDataClient(config, new LocalDataClient(config)); | ||
} | ||
return new RemoteDataClient(config); | ||
@@ -1352,0 +1191,0 @@ } |
@@ -15,5 +15,3 @@ var flatten = require('flat'); | ||
enumerable: true, | ||
get: function () { | ||
return e[k]; | ||
} | ||
get: function () { return e[k]; } | ||
}); | ||
@@ -23,3 +21,3 @@ } | ||
} | ||
n['default'] = e; | ||
n["default"] = e; | ||
return n; | ||
@@ -39,3 +37,2 @@ } | ||
const stale = []; | ||
for (const name of canonicalDictionaryNames) { | ||
@@ -54,3 +51,2 @@ if (!cache.has({ | ||
} | ||
return { | ||
@@ -68,7 +64,5 @@ missing, | ||
this.isValidating = false; | ||
if (!config.path) { | ||
throw new TypeError(`'path' to local fallback content missing in config. Required when using local data options.`); | ||
} | ||
this.config = config; | ||
@@ -78,10 +72,8 @@ this.applicationId = config.applicationId; | ||
} | ||
async getDictionary(canonicalDictionaryName, _options) { | ||
var _this$config$path; | ||
validateCanonicalDictionaryName(canonicalDictionaryName); | ||
const { | ||
getLocalDictionary | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-0bf811c5.js'); }); | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-c67434bc.js'); }); | ||
return this.flattenDictionaries({ | ||
@@ -91,35 +83,27 @@ [canonicalDictionaryName]: await getLocalDictionary(canonicalDictionaryName, (_this$config$path = this.config.path) != null ? _this$config$path : '') | ||
} | ||
async getDictionaries(canonicalDictionaryNames, _options) { | ||
var _this$config$path2; | ||
const { | ||
getLocalDictionaries | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-0bf811c5.js'); }); | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-c67434bc.js'); }); | ||
canonicalDictionaryNames.forEach(validateCanonicalDictionaryName); | ||
return this.flattenDictionaries(Object.fromEntries(await getLocalDictionaries(canonicalDictionaryNames, (_this$config$path2 = this.config.path) != null ? _this$config$path2 : ''))); | ||
} | ||
async getAllDictionaries(_options) { | ||
var _this$config$path3; | ||
const { | ||
getLocalDictionaries | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-0bf811c5.js'); }); | ||
} = await Promise.resolve().then(function () { return require('./getLocalDictionaries-c67434bc.js'); }); | ||
return this.flattenDictionaries(Object.fromEntries(await getLocalDictionaries([], (_this$config$path3 = this.config.path) != null ? _this$config$path3 : ''))); | ||
} | ||
async getEntry(_canonicalName, _options) { | ||
var _this$config$path4; | ||
const { | ||
getLocalEntry | ||
} = await Promise.resolve().then(function () { return require('./getLocalEntry-2a7f4892.js'); }); | ||
} = await Promise.resolve().then(function () { return require('./getLocalEntry-d8c829fa.js'); }); | ||
return getLocalEntry(_canonicalName, (_this$config$path4 = this.config.path) != null ? _this$config$path4 : ''); | ||
} | ||
async listEntries(_contentType, _options) { | ||
return []; | ||
} | ||
async flattenDictionaries(target) { | ||
@@ -131,3 +115,2 @@ const { | ||
} | ||
} | ||
@@ -144,3 +127,2 @@ | ||
} | ||
} | ||
@@ -152,3 +134,2 @@ class ContentDeliveryClientError extends Error { | ||
} | ||
} | ||
@@ -160,3 +141,2 @@ class ContentDeliveryClientValidationError extends ContentDeliveryClientError { | ||
} | ||
} | ||
@@ -170,3 +150,2 @@ class TimeoutError extends Error { | ||
} | ||
} | ||
@@ -195,9 +174,6 @@ class ContentDeliveryError extends Error { | ||
this.locale = locale; | ||
if (market) { | ||
this.market = market; | ||
} | ||
this.environment = environment; | ||
if (error) { | ||
@@ -213,3 +189,2 @@ if (Array.isArray(error)) { | ||
} | ||
} | ||
@@ -222,7 +197,6 @@ class DictionaryNotFoundError extends ContentDeliveryError { | ||
} | ||
} | ||
// Market nodes are expected to have the same name as the region/country | ||
// in English with whitespace removed, unless otherwise specified here. | ||
const marketNodeNames = { | ||
@@ -240,13 +214,9 @@ AE: 'AE', | ||
*/ | ||
function getMarketItemName(siteSlug) { | ||
const market = marketSites.getMarketSite(siteSlug); | ||
if (market.regionCode && market.marketName) { | ||
let itemName = marketNodeNames[market.regionCode] || market.marketName.replace(/\s/g, ''); | ||
if (minisites.includes(market.regionCode)) { | ||
itemName = 'minisites/' + itemName; | ||
} | ||
return itemName; | ||
@@ -262,3 +232,2 @@ } | ||
} | ||
run() { | ||
@@ -268,3 +237,2 @@ if (this.timeoutId) { | ||
} | ||
return new Promise((_, reject) => { | ||
@@ -274,3 +242,2 @@ if (this.timeout) { | ||
var _this$timeout; | ||
reject(new TimeoutError((_this$timeout = this.timeout) != null ? _this$timeout : -1)); | ||
@@ -281,3 +248,2 @@ }, this.timeout * 1000); | ||
} | ||
clear() { | ||
@@ -288,3 +254,2 @@ if (this.timeoutId) { | ||
} | ||
} | ||
@@ -310,3 +275,2 @@ | ||
var _fetchOptions; | ||
const timer = new Timeout(timeout); | ||
@@ -316,14 +280,10 @@ const url = new URL(BASE_API_URL); | ||
url.searchParams.set('Locale', locale); | ||
if (dataSource) { | ||
url.searchParams.set('DataSource', dataSource); | ||
} // Remove when CM Admin supports `environment` param | ||
} | ||
// Remove when CM Admin supports `environment` param | ||
if (environment === 'authoringPreview') { | ||
url.searchParams.set('preview', 'true'); | ||
} | ||
url.searchParams.set('environment', environment); | ||
if (market) { | ||
@@ -334,3 +294,2 @@ const { | ||
const marketItemName = getMarketItemName(siteSlug); | ||
if (marketItemName) { | ||
@@ -340,19 +299,15 @@ url.searchParams.set('market', marketItemName); | ||
} | ||
if (contentType) { | ||
url.searchParams.set('contentType', contentType); | ||
} | ||
if (limit) { | ||
url.searchParams.set('limit', limit.toString()); | ||
} | ||
let fetchOptions = config.fetchOptions; | ||
if (typeof window === 'undefined' && typeof ((_fetchOptions = fetchOptions) == null ? void 0 : _fetchOptions.agent) === 'undefined') { | ||
fetchOptions = { ...fetchOptions, | ||
fetchOptions = { | ||
...fetchOptions, | ||
agent: await getKeepAliveAgent() | ||
}; | ||
} | ||
const response = await Promise.race([timer.run(), fetch(url.href, { | ||
@@ -374,6 +329,5 @@ headers: { | ||
})]); | ||
if (response.status === 429 && retry && !timeout) { | ||
const retryAfter = Number(response.headers.get('Retry-After') || 10) + 5; // Avoid blocking for too long time | ||
const retryAfter = Number(response.headers.get('Retry-After') || 10) + 5; | ||
// Avoid blocking for too long time | ||
if (retryAfter <= 120) { | ||
@@ -399,13 +353,9 @@ console.warn(`Too many requests. Retrying in ${retryAfter} seconds...`); | ||
} | ||
const result = await response.json(); | ||
if (response.ok && 'data' in result && result.status === 200) { | ||
return result.data; | ||
} | ||
throw new RequestError('error' in result ? result.error.message : result.message, response.status, response.url); | ||
} | ||
let keepAliveAgent; | ||
async function getKeepAliveAgent() { | ||
@@ -422,3 +372,2 @@ if (!keepAliveAgent) { | ||
} | ||
return keepAliveAgent; | ||
@@ -434,3 +383,2 @@ } | ||
let dictionary; | ||
try { | ||
@@ -445,10 +393,8 @@ dictionary = await fetchDictionary(canonicalDictionaryName, config, options); | ||
} | ||
return [canonicalDictionaryName, dictionary]; | ||
}))).filter(([, value]) => !!value); // If a single dictionary failed, throw an error but include the successful | ||
}))).filter(([, value]) => !!value); | ||
// If a single dictionary failed, throw an error but include the successful | ||
// fetches on the `data` property. | ||
if (errors.length > 0) { | ||
let error; | ||
if (errors.length === 1) { | ||
@@ -458,3 +404,2 @@ error = errors[0]; | ||
var _options$environment; | ||
error = new DictionaryNotFoundError(`${errors.length} dictionaries not found`, { | ||
@@ -468,7 +413,5 @@ applicationId: config.applicationId, | ||
} | ||
error.data = dictionaries; | ||
throw error; | ||
} | ||
return dictionaries; | ||
@@ -484,6 +427,4 @@ } | ||
} | ||
async function sendFetchDictionary(canonicalDictionaryName, config, options) { | ||
var _options$environment2; | ||
const requestDetails = { | ||
@@ -499,5 +440,5 @@ applicationId: config.applicationId, | ||
let results; | ||
try { | ||
results = await sendRequest({ ...requestDetails, | ||
results = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -509,3 +450,2 @@ path: `/dictionaries/${canonicalDictionaryName}`, | ||
let message = `Failed fetching dictionary '${canonicalDictionaryName}'`; | ||
if (error instanceof RequestError) { | ||
@@ -518,3 +458,2 @@ if (error.status === 404) { | ||
} | ||
if (error.message.includes(canonicalDictionaryName)) { | ||
@@ -525,3 +464,2 @@ // Throw a NotFoundError to allow catching and falling back to local data | ||
} | ||
message += ` '${error.status}: ${error.message}'`; | ||
@@ -531,12 +469,8 @@ } else if (error.message) { | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
return results.items; | ||
} | ||
async function sendFetchAllDictionaries(config, options) { | ||
var _options$environment3; | ||
const requestDetails = { | ||
@@ -552,5 +486,5 @@ applicationId: config.applicationId, | ||
let results; | ||
try { | ||
results = await sendRequest({ ...requestDetails, | ||
results = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -562,3 +496,2 @@ path: '/dictionaries', | ||
let message = `Failed fetching dictionaries`; | ||
if (error instanceof RequestError) { | ||
@@ -570,3 +503,2 @@ // 404 will be returned from ListDictionaries endpoint if the application | ||
} | ||
message += ` '${error.status}: ${error.message}'`; | ||
@@ -576,6 +508,4 @@ } else if (error.message) { | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
if (results.length === 0) { | ||
@@ -585,3 +515,2 @@ // Throw a NotFoundError to allow catching and falling back to local data | ||
} | ||
return results; | ||
@@ -592,17 +521,13 @@ } | ||
var _obj$file, _obj$file2; | ||
if (typeof obj !== 'object' || !obj) return handleBooleans(obj); // handle images and files | ||
if (typeof obj !== 'object' || !obj) return handleBooleans(obj); | ||
// handle images and files | ||
if (obj != null && (_obj$file = obj.file) != null && _obj$file.mediaType || obj != null && (_obj$file2 = obj.file) != null && _obj$file2.details) { | ||
return transformImageOrFile(obj); | ||
} | ||
if (Array.isArray(obj)) { | ||
return obj.map(traverse); | ||
} | ||
if ('fields' in obj && Object.keys(obj.fields).length === 0) { | ||
return {}; | ||
} | ||
return Object.entries(obj).reduce((acc, [key, value]) => { | ||
@@ -612,3 +537,2 @@ // rename fields and flatten renderingParams | ||
var _obj$contentType; | ||
if ((obj == null ? void 0 : (_obj$contentType = obj.contentType) == null ? void 0 : _obj$contentType.type) === 'EditorialComponent' && key === 'fields') { | ||
@@ -625,3 +549,2 @@ acc['content'] = traverse(value); | ||
} | ||
acc[key] = traverse(value); | ||
@@ -632,17 +555,12 @@ } else if (key !== 'sys') { | ||
} | ||
return acc; | ||
}, {}); | ||
}; | ||
function transformImageOrFile(value) { | ||
var _value$file, _value$file2, _value$file2$mediaTyp, _value$file9, _value$file10; | ||
if (!(value != null && (_value$file = value.file) != null && _value$file.url)) { | ||
return null; | ||
} | ||
if (value != null && (_value$file2 = value.file) != null && (_value$file2$mediaTyp = _value$file2.mediaType) != null && _value$file2$mediaTyp.includes('image')) { | ||
var _value$file3, _value$file4, _value$file4$details, _value$file4$details$, _value$file5, _value$file6, _value$file7, _value$file7$details, _value$file7$details$, _value$file8, _value$file8$details, _value$file8$details$; | ||
return { | ||
@@ -657,3 +575,2 @@ src: (value == null ? void 0 : (_value$file3 = value.file) == null ? void 0 : _value$file3.url) || '', | ||
} | ||
return { | ||
@@ -666,3 +583,2 @@ mimeType: (value == null ? void 0 : (_value$file9 = value.file) == null ? void 0 : _value$file9.mediaType) || '', | ||
} | ||
function handleBooleans(value) { | ||
@@ -674,3 +590,2 @@ return value === 'true' ? true : value === 'false' ? false : typeof value === 'undefined' ? null : value; | ||
var _options$environment; | ||
const requestDetails = { | ||
@@ -686,5 +601,5 @@ applicationId: config.applicationId, | ||
let result; | ||
try { | ||
result = await sendRequest({ ...requestDetails, | ||
result = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -696,3 +611,2 @@ path: `/entries/${canonicalName}`, | ||
let message = 'Failed fetching entry'; | ||
if (error instanceof RequestError) { | ||
@@ -703,6 +617,4 @@ message += ` '${error.status}: ${error.message}'`; | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
} | ||
return traverse(result); | ||
@@ -713,3 +625,2 @@ } | ||
var _options$environment; | ||
const requestDetails = { | ||
@@ -722,7 +633,8 @@ applicationId: config.applicationId, | ||
market: options.market, | ||
timeout: options.timeout, | ||
contentType | ||
}; | ||
try { | ||
const result = await sendRequest({ ...requestDetails, | ||
const result = await sendRequest({ | ||
...requestDetails, | ||
config, | ||
@@ -735,3 +647,2 @@ path: `/entries`, | ||
let message = 'Failed fetching entries list'; | ||
if (error instanceof RequestError) { | ||
@@ -742,3 +653,2 @@ message += ` '${error.status}: ${error.message}'`; | ||
} | ||
throw new ContentDeliveryError(message, requestDetails, error); | ||
@@ -764,3 +674,2 @@ } | ||
} | ||
set(keyConfig, value) { | ||
@@ -771,7 +680,5 @@ const cacheKey = getCacheKey(keyConfig); | ||
} | ||
has(keyConfig) { | ||
return this.values.has(getCacheKey(keyConfig)); | ||
} | ||
get(keyConfig) { | ||
@@ -783,21 +690,14 @@ return this.values.get(getCacheKey(keyConfig)); | ||
*/ | ||
isStale(keyConfig) { | ||
var _this$lastUpdated$get; | ||
const cacheKey = getCacheKey(keyConfig); | ||
if (!this.lastUpdated.has(cacheKey)) { | ||
return false; | ||
} | ||
if (this.revalidateMs === 0) { | ||
return true; | ||
} | ||
const currentTime = this.now(); | ||
return currentTime - ((_this$lastUpdated$get = this == null ? void 0 : this.lastUpdated.get(cacheKey)) != null ? _this$lastUpdated$get : 0) >= this.revalidateMs; | ||
} | ||
delete(keyConfig) { | ||
@@ -807,3 +707,2 @@ const cacheKey = getCacheKey(keyConfig); | ||
} | ||
} | ||
@@ -838,3 +737,2 @@ function getCacheKey(config) { | ||
this.pendingRevalidations = 0; | ||
if (!config.allowedDataSources) { | ||
@@ -845,3 +743,2 @@ config.allowedDataSources = []; | ||
} | ||
if (!config.allowedEnvironments) { | ||
@@ -852,7 +749,5 @@ config.allowedEnvironments = []; | ||
} | ||
if (!config.defaultEnvironment) { | ||
config.defaultEnvironment = 'live'; | ||
} | ||
validateDataSourceAndEnvironment(config, { | ||
@@ -868,5 +763,5 @@ dataSource: config.defaultDataSource, | ||
}; | ||
if (typeof config.revalidate === 'object') { | ||
config.revalidate = { ...revalidate, | ||
config.revalidate = { | ||
...revalidate, | ||
...config.revalidate | ||
@@ -877,3 +772,2 @@ }; | ||
} | ||
this.applicationId = config.applicationId; | ||
@@ -888,10 +782,7 @@ this.defaultDataSource = config.defaultDataSource; | ||
} | ||
get isValidating() { | ||
return this.pendingRevalidations > 0; | ||
} | ||
async getDictionary(canonicalDictionaryName, rawOptions) { | ||
var _this$dictionariesCac2; | ||
validateCanonicalDictionaryName(canonicalDictionaryName); | ||
@@ -905,7 +796,7 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: canonicalDictionaryName, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || !this.dictionariesCache.has(cacheKey)) { | ||
@@ -920,7 +811,5 @@ try { | ||
var _this$dictionariesCac; | ||
this.logError('dictionaries', operationDetails, error); | ||
return flattenDictionaries([[canonicalDictionaryName, (_this$dictionariesCac = this.dictionariesCache.get(cacheKey)) != null ? _this$dictionariesCac : {}]]); | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -931,8 +820,6 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} // Fetch stale entry in the background, intentionally don't await | ||
} | ||
// Fetch stale entry in the background, intentionally don't await | ||
if (this.dictionariesCache.isStale(cacheKey)) { | ||
@@ -950,6 +837,4 @@ this.pendingRevalidations++; | ||
} | ||
return flattenDictionaries([[canonicalDictionaryName, (_this$dictionariesCac2 = this.dictionariesCache.get(cacheKey)) != null ? _this$dictionariesCac2 : {}]]); | ||
} | ||
async getDictionaries(canonicalDictionaryNames, rawOptions) { | ||
@@ -964,6 +849,6 @@ canonicalDictionaryNames.forEach(validateCanonicalDictionaryName); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || canonicalDictionaryNames.some(name => !this.dictionariesCache.has({ | ||
@@ -975,3 +860,2 @@ name, | ||
const dictionaries = await fetchDictionaries(canonicalDictionaryNames, this.config, options); | ||
for (const [name, items] of dictionaries) { | ||
@@ -983,3 +867,2 @@ this.dictionariesCache.set({ | ||
} | ||
return flattenDictionaries(dictionaries); | ||
@@ -995,6 +878,4 @@ } catch (error) { | ||
} | ||
error.data = flattenDictionaries(error.data); | ||
} | ||
if (canonicalDictionaryNames.every(name => this.dictionariesCache.has({ | ||
@@ -1004,7 +885,6 @@ name, | ||
}))) { | ||
this.logError('dictionaries', operationDetails, error); // Return stale content if everything is now available in the cache | ||
this.logError('dictionaries', operationDetails, error); | ||
// Return stale content if everything is now available in the cache | ||
return flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac3; | ||
return [name, (_this$dictionariesCac3 = this.dictionariesCache.get({ | ||
@@ -1016,3 +896,2 @@ name, | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -1023,14 +902,12 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} | ||
const { | ||
missing, | ||
stale | ||
} = sortCanonicalDictionaryNames(canonicalDictionaryNames, this.dictionariesCache, cacheKey); // Fetch stale entries in the background, intentionally don't await | ||
} = sortCanonicalDictionaryNames(canonicalDictionaryNames, this.dictionariesCache, cacheKey); | ||
// Fetch stale entries in the background, intentionally don't await | ||
// Some might return before all missing requests are done, otherwise | ||
// they will be available at the next request | ||
stale.forEach(canonicalDictionaryName => { | ||
@@ -1050,9 +927,8 @@ this.pendingRevalidations++; | ||
}); | ||
}); // Fetch all missing dictionaries. | ||
}); | ||
// Fetch all missing dictionaries. | ||
// Errors are fatal unless there is a `localDataClient`. | ||
if (missing.length > 0) { | ||
try { | ||
const dictionaries = await fetchDictionaries(missing, this.config, options); | ||
for (const [name, items] of dictionaries) { | ||
@@ -1074,14 +950,12 @@ this.dictionariesCache.set({ | ||
} | ||
error.data = flattenDictionaries(error.data); | ||
} | ||
if (this.localDataClient) { | ||
this.logError('dictionaries', operationDetails, error); | ||
this.logFallback(); // Return everything that's in the cache, merged with the missing entries | ||
this.logFallback(); | ||
// Return everything that's in the cache, merged with the missing entries | ||
// from the local fallback | ||
return { ...flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
return { | ||
...flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac4; | ||
return [name, (_this$dictionariesCac4 = this.dictionariesCache.get({ | ||
@@ -1096,11 +970,8 @@ name, | ||
} | ||
throw error; | ||
} | ||
} // By now all requested dictionaries are available in the cache | ||
} | ||
// By now all requested dictionaries are available in the cache | ||
return flattenDictionaries(canonicalDictionaryNames.map(name => { | ||
var _this$dictionariesCac5; | ||
return [name, (_this$dictionariesCac5 = this.dictionariesCache.get({ | ||
@@ -1112,6 +983,4 @@ name, | ||
} | ||
async getAllDictionaries(rawOptions) { | ||
var _this$dictionariesLis2; | ||
const options = getOptionsWithDefaults(rawOptions, this.config); | ||
@@ -1124,21 +993,19 @@ validateDataSourceAndEnvironment(this.config, options); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: 'all', | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.dictionaries === 0 || !this.dictionariesListCache.has(cacheKey)) { | ||
try { | ||
const dictionaries = await fetchAllDictionaries(this.config, options); | ||
if (dictionaries.length > 0) { | ||
for (const [name, items] of dictionaries) { | ||
this.dictionariesCache.set({ ...cacheKey, | ||
this.dictionariesCache.set({ | ||
...cacheKey, | ||
name | ||
}, items); | ||
} | ||
this.dictionariesListCache.set(cacheKey, dictionaries); | ||
} | ||
return flattenDictionaries(dictionaries); | ||
@@ -1149,7 +1016,5 @@ } catch (error) { | ||
var _this$dictionariesLis; | ||
this.logError('dictionaries', operationDetails, error); | ||
return flattenDictionaries((_this$dictionariesLis = this.dictionariesListCache.get(cacheKey)) != null ? _this$dictionariesLis : []); | ||
} | ||
if (error.name === 'DictionaryNotFoundError' && this.localDataClient) { | ||
@@ -1160,7 +1025,5 @@ this.logError('dictionaries', operationDetails, error); | ||
} | ||
throw error; | ||
} | ||
} | ||
if (this.dictionariesListCache.isStale(cacheKey)) { | ||
@@ -1171,7 +1034,7 @@ // Fetch stale entries in the background, intentionally don't await | ||
for (const [name, items] of dictionaries) { | ||
this.dictionariesCache.set({ ...cacheKey, | ||
this.dictionariesCache.set({ | ||
...cacheKey, | ||
name | ||
}, items); | ||
} | ||
this.dictionariesListCache.set(cacheKey, dictionaries); | ||
@@ -1186,6 +1049,4 @@ }).catch(error => { | ||
} | ||
return flattenDictionaries((_this$dictionariesLis2 = this.dictionariesListCache.get(cacheKey)) != null ? _this$dictionariesLis2 : []); | ||
} | ||
async getEntry(canonicalName, rawOptions) { | ||
@@ -1199,15 +1060,13 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: canonicalName, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.entries === 0 || !this.entriesCache.has(cacheKey)) { | ||
try { | ||
const entry = await fetchEntry(canonicalName, this.config, options); | ||
if (this.entriesCache) { | ||
this.entriesCache.set(cacheKey, entry); | ||
} | ||
return entry; | ||
@@ -1218,5 +1077,4 @@ } catch (error) { | ||
} | ||
} // Fetch stale entry in the background, intentionally don't await | ||
} | ||
// Fetch stale entry in the background, intentionally don't await | ||
if (this.entriesCache.isStale(cacheKey)) { | ||
@@ -1230,6 +1088,5 @@ this.pendingRevalidations++; | ||
this.entriesCache.delete(cacheKey); | ||
} // Failing to refresh a stale entry is not a fatal error, because | ||
} | ||
// Failing to refresh a stale entry is not a fatal error, because | ||
// there's already some content in the cache. | ||
this.logError('entries', operationDetails, error); | ||
@@ -1240,6 +1097,4 @@ }).finally(() => { | ||
} | ||
return this.entriesCache.get(cacheKey); | ||
} | ||
async listEntries(contentType, rawOptions) { | ||
@@ -1253,15 +1108,13 @@ const options = getOptionsWithDefaults(rawOptions, this.config); | ||
}; | ||
const cacheKey = { ...operationDetails, | ||
const cacheKey = { | ||
...operationDetails, | ||
name: contentType, | ||
market: options.market | ||
}; | ||
if (this.config.revalidate.listEntries === 0 || !this.listEntriesCache.has(cacheKey)) { | ||
try { | ||
const entriesList = await listEntries(contentType, this.config, options); | ||
if (this.listEntriesCache) { | ||
this.listEntriesCache.set(cacheKey, entriesList); | ||
} | ||
return entriesList; | ||
@@ -1272,5 +1125,4 @@ } catch (error) { | ||
} | ||
} // Fetch stale entries list in the background, intentionally don't await | ||
} | ||
// Fetch stale entries list in the background, intentionally don't await | ||
if (this.listEntriesCache.isStale(cacheKey)) { | ||
@@ -1288,6 +1140,4 @@ this.pendingRevalidations++; | ||
} | ||
return this.listEntriesCache.get(cacheKey); | ||
} | ||
logError(type, { | ||
@@ -1303,3 +1153,2 @@ locale, | ||
} | ||
logFallback() { | ||
@@ -1310,15 +1159,10 @@ if (process.env.NODE_ENV !== 'test') { | ||
} | ||
} | ||
function getMessages(error) { | ||
var _error$errors; | ||
const message = error.message; | ||
let childrenMessages = []; | ||
if ((_error$errors = error.errors) != null && _error$errors.length) { | ||
childrenMessages = error.errors.map(e => e.message); | ||
} | ||
return `${message}: | ||
@@ -1328,3 +1172,2 @@ ${childrenMessages.join('\n')} | ||
} | ||
function validateDataSourceAndEnvironment(config, options) { | ||
@@ -1334,3 +1177,2 @@ if (options.dataSource && config.allowedDataSources.length > 0 && !config.allowedDataSources.includes(options.dataSource)) { | ||
} | ||
if (options.environment && config.allowedEnvironments.length > 0 && !config.allowedEnvironments.includes(options.environment)) { | ||
@@ -1340,5 +1182,4 @@ throw new ContentDeliveryClientValidationError(options.environment, config.allowedEnvironments, 'config.allowedEnvironments'); | ||
} | ||
function flattenDictionaries(entries) { | ||
return flatten__default['default'](Object.fromEntries(entries)); | ||
return flatten__default["default"](Object.fromEntries(entries)); | ||
} | ||
@@ -1354,3 +1195,2 @@ | ||
} | ||
if (typeof window !== 'undefined') { | ||
@@ -1360,3 +1200,2 @@ if (forceLocalData) { | ||
} | ||
if (fallbackToLocalData) { | ||
@@ -1369,3 +1208,2 @@ throw new Error(`The 'fallbackToLocalData' option is only available in SSR.`); | ||
} | ||
if (fallbackToLocalData) { | ||
@@ -1375,3 +1213,2 @@ return new RemoteDataClient(config, new LocalDataClient(config)); | ||
} | ||
return new RemoteDataClient(config); | ||
@@ -1378,0 +1215,0 @@ } |
@@ -0,0 +0,0 @@ import type { ClientConfig, ContentDeliveryClient, GetOptions } from './ContentDeliveryClient'; |
@@ -0,0 +0,0 @@ import { ClientConfig } from '.'; |
@@ -0,0 +0,0 @@ import { SiteSlug } from '@volvo-cars/market-sites'; |
@@ -0,0 +0,0 @@ /// <reference types="node" /> |
@@ -0,0 +0,0 @@ import type { ContentEnvironment } from '../ContentDeliveryClient'; |
export declare function getLocalDataPaths(rootPath: string, canonicalNames?: string[], isDictionary?: boolean): Promise<string[]>; |
@@ -0,0 +0,0 @@ import { GetOptions } from '../../ContentDeliveryClient'; |
@@ -0,0 +0,0 @@ import type { ClientConfig, ContentEnvironment } from '../ContentDeliveryClient'; |
{ | ||
"name": "@volvo-cars/content-delivery-client", | ||
"version": "0.4.6", | ||
"version": "0.5.0", | ||
"license": "UNLICENSED", | ||
"source": "index.ts", | ||
"main": "dist/index.js", | ||
"sideEffects": false, | ||
"publishConfig": { | ||
@@ -33,3 +34,3 @@ "access": "public", | ||
"flat": "^5.0.0", | ||
"glob": "^8.0.3" | ||
"glob": "^8.1.0" | ||
}, | ||
@@ -39,8 +40,8 @@ "devDependencies": { | ||
"@vcc-www/utils": "0.0.0", | ||
"@volvo-cars/content-management-client": "0.17.0", | ||
"@volvo-cars/content-management-client": "0.21.0", | ||
"microbundle": "^0.15.1", | ||
"nock": "^13.0.5", | ||
"typescript": "4.9.4" | ||
"msw": "^1.2.1", | ||
"typescript": "5.0.2" | ||
}, | ||
"module": "dist/index.esm.js" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
316299
50
3001
10
Updatedglob@^8.1.0