diff --git a/scripts/delayed.js b/scripts/delayed.js index 8b05ca50..1f16c99d 100644 --- a/scripts/delayed.js +++ b/scripts/delayed.js @@ -1,7 +1,9 @@ // eslint-disable-next-line import/no-cycle import { sampleRUM, isInternalPage } from './lib-franklin.js'; // eslint-disable-next-line import/no-cycle -import { getEnvType, loadConsentManager, loadScript } from './scripts.js'; +import { + getEnvType, loadConsentManager, loadScript, fetchIndex, queryIndex, +} from './scripts.js'; // Core Web Vitals RUM collection sampleRUM('cwv'); @@ -25,4 +27,8 @@ window.addEventListener('consentmanager', () => { if (!isInternalPage()) { await loadConsentManager(); await loadAdobeLaunch(); + // TODO Remove. Just for testing. + const json = await fetchIndex('query-index'); + const results = queryIndex(json, ['title', 'description'], ['category', '=', 'Newsroom'], ['newsdate', 'desc'], 3); + console.log(JSON.stringify(results, null, 2)); } diff --git a/scripts/json-query.js b/scripts/json-query.js new file mode 100644 index 00000000..cdfd324b --- /dev/null +++ b/scripts/json-query.js @@ -0,0 +1,55 @@ +/* eslint-disable max-len */ +export default function query(select, from, where, orderBy, rowCount) { + // Validate input parameters + if (!Array.isArray(select) || !Array.isArray(from) || !Array.isArray(where) || where.length !== 3) { + throw new Error('Invalid input parameters'); + } + + // Extract the filter condition components + const [field, operator, value] = where; + + // Sort the 'from' array based on the orderBy parameter + if (orderBy) { + const [orderByField, sortOrder] = orderBy; + from.sort((a, b) => { + const aValue = a[orderByField]; + const bValue = b[orderByField]; + if (sortOrder === 'asc') { + // eslint-disable-next-line no-nested-ternary + return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; + } if (sortOrder === 'desc') { + // eslint-disable-next-line no-nested-ternary + return bValue < aValue ? -1 : bValue > aValue ? 1 : 0; + } + throw new Error('Invalid sortOrder'); + }); + } + + // Filter the 'from' array based on the condition + const filteredData = from.filter((item) => { + switch (operator) { + case '<': + return item[field] < parseFloat(value); + case '>': + return item[field] > parseFloat(value); + case '=': + return item[field] === value; + default: + return false; // Unsupported operator + } + }); + + // Limit the number of rows based on the rowCount parameter + const selectedData = filteredData.slice(0, rowCount); + + // Select the specified fields from the filtered data + const result = selectedData.map((item) => { + const selectedFields = {}; + select.forEach((fieldName) => { + selectedFields[fieldName] = item[fieldName]; + }); + return selectedFields; + }); + + return result; +} diff --git a/scripts/scripts.js b/scripts/scripts.js index ca531139..bf41061a 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -15,6 +15,8 @@ import { isInternalPage, } from './lib-franklin.js'; +import query from './json-query.js'; + const LCP_BLOCKS = [ 'hero', 'hero-banner', @@ -332,6 +334,10 @@ export async function fetchIndex(indexFile, sheet, pageSize = 500) { return newIndex; } +export function queryIndex(index, select, where, orderBy, rowCount) { + const result = query(select, index.data, where, orderBy, rowCount); + return result; +} /** * Loads everything that happens a lot later, * without impacting the user experience.