Skip to content

Commit e153ad8

Browse files
fix: update how subsequent node data caching is executed
1 parent 9e82e9e commit e153ad8

File tree

1 file changed

+114
-96
lines changed

1 file changed

+114
-96
lines changed

src/gatsby-node.js

Lines changed: 114 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
} from "./constants";
1919
import { Optimizely } from "./libs/optimizely";
2020
import { convertObjectToString, convertStringToCamelCase } from "./utils/convertValues";
21-
import { isEqual } from "./utils/isEqual";
2221
import { isArrayType, isEmpty, isObjectType, isStringType } from "./utils/typeCheck";
2322

2423
/**
@@ -132,33 +131,40 @@ exports.pluginOptionsSchema = ({ Joi }) =>
132131
// .description("The webhook URL for the Optimizely/Episerver site")
133132
// })
134133
// }).description("The preview options for the plugin"),
135-
globals: Joi.object({
136-
schema: Joi.string().when("enabled", {
134+
globals: Joi.object()
135+
.when("enabled", {
137136
is: true,
138-
then: Joi.string()
139-
.required()
140-
.messages({
141-
"string.empty": "The `globals.schema` is empty. Please provide a valid schema.",
142-
"string.required": "The `globals.schema` is required."
143-
})
144-
.description("The schema for the Optimizely/Episerver site")
137+
then: Joi.object({
138+
schema: Joi.string()
139+
.required()
140+
.allow(null)
141+
.default(null)
142+
.messages({
143+
"string.empty": "The `globals.schema` is empty. Please provide a valid schema.",
144+
"string.required": "The `globals.schema` is required."
145+
})
146+
.description("The schema for the Optimizely/Episerver site")
147+
})
145148
})
146-
}).description("The global options for the plugin"),
149+
.messages({
150+
"object.required": "The `globals` object is required."
151+
})
152+
.description("The global options for the plugin"),
147153
endpoints: Joi.array()
148154
.required()
149155
.items({
150156
nodeName: Joi.string()
151157
.required()
152158
.messages({
153-
"string.empty": "The `endpoints[].nodeName` is empty. Please provide a valid node name.",
154-
"string.required": "The `endpoints[].nodeName` is required."
159+
"string.empty": "The `endpoints[index].nodeName` is empty. Please provide a valid node name.",
160+
"string.required": "The `endpoints[index].nodeName` is required."
155161
})
156162
.description("The name of the node to create"),
157163
endpoint: Joi.string()
158164
.required()
159165
.messages({
160-
"string.empty": "The `endpoints[].endpoint` is empty. Please provide a valid endpoint.",
161-
"string.required": "The `endpoints[].endpoint` is required."
166+
"string.empty": "The `endpoints[index].endpoint` is empty. Please provide a valid endpoint.",
167+
"string.required": "The `endpoints[index].endpoint` is required."
162168
})
163169
.description("The endpoint to create nodes for"),
164170
schema: Joi.string().allow(null).default(null).description("The schema to use for the node")
@@ -231,92 +237,107 @@ exports.sourceNodes = async ({ actions: { createNode }, cache, createNodeId, cre
231237
// Authenticate with the Optimizely/Episerver
232238
const auth = await optimizely.authenticate();
233239

234-
if (!isEmpty(auth?.access_token)) {
235-
// Send log message to console if authentication was successful
236-
console.info(`[AUTH] ${convertObjectToString(auth?.access_token)}`);
237-
238-
await Promise.allSettled(
239-
endpoints?.map(async ({ nodeName = null, endpoint = null }) => {
240-
const url = site_url + endpoint;
241-
242-
const results = await optimizely.get({
243-
url,
244-
headers: {
245-
...headers,
246-
"Authorization": `Bearer ${auth?.access_token}`,
247-
"Access-Control-Allow-Credentials": ACCESS_CONTROL_ALLOW_CREDENTIALS
248-
},
249-
endpoint: nodeName
250-
});
251-
252-
// Resolve the promise
253-
return {
254-
nodeName,
255-
data: results || null,
256-
endpoint
257-
};
258-
})
259-
)
260-
.then(async (res) => {
261-
// Store the data in the cache
262-
if (!isEmpty(res)) {
263-
sourceData = res;
240+
/**
241+
* @description Handle node creation
242+
* @param {*} sourceData
243+
* @returns {Promise<void>} Node creation promise
244+
*/
245+
const handleNodeCreation = async (sourceData = null) => {
246+
sourceData
247+
?.filter(({ status = null, value: { nodeName = null, data = null, endpoint = null } }) => status === "fulfilled" && !isEmpty(nodeName) && !isEmpty(data) && !isEmpty(endpoint))
248+
?.map(async ({ status = null, value: { nodeName = null, data = null, endpoint = null } }) => {
249+
// Check if the data was retrieved successfully
250+
if (status === "fulfilled" && !isEmpty(data) && !isEmpty(nodeName) && isStringType(nodeName)) {
251+
const updatedData = handleCamelizeKeys(data);
252+
253+
if (!isEmpty(updatedData)) {
254+
// Create nodes from the data
255+
if (isArrayType(updatedData)) {
256+
updatedData?.map(async (datum) => {
257+
await handleCreateNodeFromData(datum, nodeName, helpers, datum?.contentLink?.url || site_url + endpoint);
258+
});
259+
} else {
260+
await handleCreateNodeFromData(updatedData, nodeName, helpers, updatedData?.contentLink?.url || site_url + endpoint);
261+
}
262+
} else {
263+
// Send log message to console if an error occurred
264+
console.error(`[ERROR] No data was retrieved from the Optimizely/Episerver API. Please check your credentials and try again.`);
265+
}
264266
}
267+
});
265268

266-
// Stringify both the cached data and the source data and compare them
267-
const stringifiedCachedData = convertObjectToString(cachedData);
268-
const stringifiedSourceData = convertObjectToString(sourceData);
269+
// Cache the data
270+
await cache
271+
.set(CACHE_KEY, sourceData)
272+
.then(() => console.info(`[CACHE] Node creation performed successfully!`))
273+
.catch((error) => console.error(`[ERROR] There was an error caching the data. ${convertObjectToString(error)}`))
274+
.finally(() => console.info("@epicdesignlabs/gatsby-source-optimizely finished sourcing nodes successfully!"));
269275

270-
// Check if cached data exists and if the cached data is the same as the source data
271-
if (!isEmpty(cachedData) && !isEmpty(sourceData) && isEqual(stringifiedCachedData, stringifiedSourceData)) {
272-
// Send log message to console if the cached data is the same as the source data
273-
console.warn(`[CACHE] Current cache is the same as the source data. Proceeding to node creation...`);
274-
} else {
275-
// Send log message to console if the cached data is not the same as the source data
276-
console.warn(`[CACHE] Current cache is not the same as the source data. Proceeding to cache update...`);
276+
// Resolve the promise
277+
return sourceData;
278+
};
277279

278-
// Cache the data
279-
await cache.set(CACHE_KEY, sourceData).then(() => console.info(`[CACHE] Updated source data cached successfully! Proceeding to node creation...`));
280-
}
280+
if (!isEmpty(auth?.access_token)) {
281+
// Send log message to console if authentication was successful
282+
console.info(`[AUTH] ${convertObjectToString(auth?.access_token)}`);
281283

282-
sourceData
283-
?.filter(({ status = null, value: { nodeName = null, data = null, endpoint = null } }) => status === "fulfilled" && !isEmpty(nodeName) && !isEmpty(data) && !isEmpty(endpoint))
284-
?.map(async ({ status = null, value: { nodeName = null, data = null, endpoint = null } }) => {
285-
// Check if the data was retrieved successfully
286-
if (status === "fulfilled" && !isEmpty(data) && !isEmpty(nodeName) && isStringType(nodeName)) {
287-
const updatedData = handleCamelizeKeys(data);
288-
289-
if (!isEmpty(updatedData)) {
290-
// Create nodes from the data
291-
if (isArrayType(updatedData)) {
292-
updatedData?.map(async (datum) => {
293-
await handleCreateNodeFromData(datum, nodeName, helpers, datum?.contentLink?.url || site_url + endpoint);
294-
});
295-
} else {
296-
await handleCreateNodeFromData(updatedData, nodeName, helpers, updatedData?.contentLink?.url || site_url + endpoint);
297-
}
298-
} else {
299-
// Send log message to console if an error occurred
300-
console.error(`[ERROR] No data was retrieved from the Optimizely/Episerver API. Please check your credentials and try again.`);
301-
}
302-
}
284+
if (!isEmpty(cachedData)) {
285+
// Send log message to console if the cached data is available
286+
console.warn(`[CACHE] Current cache is available. Proceeding to node creation...`);
287+
288+
// Create nodes from the cached data
289+
await handleNodeCreation(cachedData);
290+
291+
// Resolve the promise
292+
return cachedData;
293+
} else {
294+
// Send log message to console if the cached data is not available
295+
console.warn(`[CACHE] Current cache is not available. Proceeding to source data...`);
296+
297+
await Promise.allSettled(
298+
endpoints?.map(async ({ nodeName = null, endpoint = null }) => {
299+
const url = site_url + endpoint;
300+
301+
const results = await optimizely.get({
302+
url,
303+
headers: {
304+
...headers,
305+
"Authorization": `Bearer ${auth?.access_token}`,
306+
"Access-Control-Allow-Credentials": ACCESS_CONTROL_ALLOW_CREDENTIALS
307+
},
308+
endpoint: nodeName
303309
});
304310

305-
// Resolve the promise
306-
return cachedData;
307-
})
308-
.catch((err) => {
309-
// Send log message to console if an error occurred
310-
console.error(`[GET] ${err?.message || convertObjectToString(err) || "An error occurred. Please try again later."}`);
311+
// Resolve the promise
312+
return {
313+
nodeName,
314+
data: results || null,
315+
endpoint
316+
};
317+
})
318+
)
319+
.then(async (res) => {
320+
// Store the data in the cache
321+
if (!isEmpty(res)) {
322+
sourceData = res;
323+
}
324+
325+
// Create nodes from the cached data
326+
await handleNodeCreation(sourceData);
327+
328+
// Resolve the promise
329+
return sourceData;
330+
})
331+
.catch((err) => {
332+
// Send log message to console if an error occurred
333+
console.error(`[GET] ${err?.message || convertObjectToString(err) || "An error occurred. Please try again later."}`);
311334

312-
// Reject the promise
313-
return err;
314-
})
315-
.finally(async () => {
316-
console.info("@epicdesignlabs/gatsby-source-optimizely task processing complete!");
335+
// Reject the promise
336+
return err;
337+
});
338+
}
317339

318-
return;
319-
});
340+
return;
320341
} else {
321342
// Send error message to console if an error occurred
322343
throw new Error(`[AUTH] API authentication failed. Please check your credentials and try again.`);
@@ -331,10 +352,7 @@ exports.sourceNodes = async ({ actions: { createNode }, cache, createNodeId, cre
331352
exports.createSchemaCustomization = ({ actions: { createTypes } }, pluginOptions) => {
332353
let typeDefs = ``;
333354

334-
const {
335-
globals: { schema = null },
336-
endpoints = []
337-
} = pluginOptions;
355+
const { globals: { schema = null } = null, endpoints = [] } = pluginOptions;
338356

339357
if (!isEmpty(endpoints)) {
340358
endpoints?.map(({ nodeName = null, schema = null }) => {

0 commit comments

Comments
 (0)