Skip to content

Commit

Permalink
JSDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
xjensen committed Oct 23, 2023
1 parent ce3cd8a commit b44543b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 22 deletions.
3 changes: 1 addition & 2 deletions src/http/get-benefits/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { getDefinitions } = require("@architect/shared/s3");

// Definitions will be loaded from benefits-recs-defs.json in S3.
// We keep it outside the handler to cache it between Lambda runs.
/** @type {import('./node_modules/@architect/shared/s3.js').Definitions} */
let definitions = {};

/** Core function for get-benefits. */
Expand All @@ -19,9 +20,7 @@ exports.handler = arc.http.async(async (req) => {
const language = req.query.language || "en";

const allLinks = assembleLinks(definitions, language, host);
console.log("All:" + allLinks.length);
const links = await applyRules(definitions, allLinks, host);
console.log("Filtered:" + links.length);
const data = {
header: "Apply for more benefits!",
tagline: "You might be able to get:",
Expand Down
21 changes: 13 additions & 8 deletions src/shared/links.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,23 @@ const addAnalytics = (linkUrl, analytics, hostDef) => {
}
};

/**
* @typedef TargetLink
* @type {object}
* @property {string} id
* @property {string} language
* @property {string} lead
* @property {string} catalyst
* @property {string} url
* @property {string} graphic
*/

/**
* Construct link objects for the given language and host.
* @param {object} definitions
* @param {import('./s3.js').Definitions} definitions
* @param {string} language
* @param {string} host
* @returns
* @returns {TargetLink[]}
*/
exports.assembleLinks = (definitions, language, host) => {
const { targets, hosts: hostDefs } = definitions;
Expand All @@ -76,9 +87,6 @@ exports.assembleLinks = (definitions, language, host) => {
const catalyst =
translations[langKey]?.catalyst || translations.en.catalyst || "";

const description =
translations[langKey]?.description || translations.en.description || "";

const linkUrl = translations[langKey]?.url || translations.en.url || "";

const analytics =
Expand All @@ -87,11 +95,8 @@ exports.assembleLinks = (definitions, language, host) => {
const urlWithAnalytics = addAnalytics(linkUrl, analytics, hostDef);

return {
linktext: lead, // linktext depreciated
program: catalyst, // program depreciated
lead,
catalyst,
description, // description possibly depreciated
url: urlWithAnalytics,
graphic,
language: langKey,
Expand Down
46 changes: 38 additions & 8 deletions src/shared/rules.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const url = require("./url");
const { getThrottles } = require("./throttles");

/**
* rules.js
* Welcome to rules.
Expand All @@ -8,10 +11,19 @@
* Rules are processed in a specific order.
*/

const url = require("./url");
const { getThrottles } = require("./throttles");
/**
* @callback Rule
* @param {import('./links.js').TargetLink[]} links
* @param {object} params
* @param {string} [params.host]
* @param {import('./s3.js').Throttle[]} [params.throttles]
* @returns {import('./links.js').TargetLink[]}
*/

/** Remove links that have exceeded daily throttles. */
/**
* Remove links that have exceeded daily throttles.
* @type {Rule}
*/
const removeThrottledLinks = (links, { throttles }) =>
links.filter((link) => {
const blockingThrottles = throttles.filter(
Expand All @@ -22,29 +34,47 @@ const removeThrottledLinks = (links, { throttles }) =>
return blockingThrottles.length < 1;
});

/** Remove links that point back to the same host site as the widget. */
/**
* Remove links that point back to the same host site as the widget.
* @type {Rule}
*/
const removeLinkBacks = (links, { host }) =>
links.filter((link) => !url.matchHosts(host, link.url));

/** Randomize the order of the links. */
/**
* Randomize the order of the links.
* @type {Rule}
*/
const randomizeOrder = (links) =>
links
.map((link) => ({ link, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map(({ link }) => link);

/** Reduce the list of links to just the top three. */
/**
* Reduce the list of links to just the top three.
* @type {Rule}
*/
const pickTopThree = (links) => links.slice(0, 3);

/** Active rules, in order. */
/**
* Active rules, in order.
* @type {Rule[]}
*/
const rules = [
removeThrottledLinks,
removeLinkBacks,
randomizeOrder,
pickTopThree,
];

/** Apply the rules to the list of links. */
/**
* Apply the rules to the list of links.
* @param {import('./s3.js').Definitions} definitions
* @param {import('./links.js').TargetLink[]} allLinks
* @param {string} host
* @returns {Promise<import('./links.js').TargetLink[]>}
*/
const applyRules = async (definitions, allLinks, host) => {
const throttles = await getThrottles(definitions);

Expand Down
52 changes: 51 additions & 1 deletion src/shared/s3.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,57 @@ const { GetObjectCommand, S3Client } = require("@aws-sdk/client-s3");

const s3 = new S3Client({});

/** Grab the definitions file from S3. */
/**
* @typedef Definitions
* @type {object}
* @property {string} name
* @property {string} description
* @property {string} updated
* @property {Target[]} targets
* @property {Throttle[]} throttles
* @property {Host[]} hosts
*/

/**
* @typedef Target
* @type {object}
* @property {string} id
* @property {object.<string, Translation>} translations
* @property {string[]} throttle_ids
*/

/**
* @typedef Translation
* @type {object}
* @property {string} id
* @property {string} url
* @property {string} icon
* @property {string} analytics
* @property {string} lead
* @property {string} catalyst
*/

/**
* @typedef Throttle
* @type {object}
* @property {string} id
* @property {number} [limit]
* @property {string} [start]
* @property {string} [end]
* @property {string[]} urls
* @property {boolean} [exceeded]
*/

/**
* @typedef Host
* @type {object}
* @property {string} id
* @property {string[]} urls
*/

/** Grab the definitions file from S3.
* @returns {Promise<Definitions>}
*/
exports.getDefinitions = async () => {
const command = new GetObjectCommand({
Bucket: "cdn.innovation.ca.gov",
Expand Down
6 changes: 5 additions & 1 deletion src/shared/throttles.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const arc = require("@architect/functions");

/** Retrieve throttles. */
/**
* Retrieve throttles.
* @param {import('./s3.js').Definitions} definitions
* @returns {Promise<import('./s3.js').Throttle[]>}
*/
exports.getThrottles = async (definitions) => {
const { throttles: throttleDefs } = definitions;

Expand Down
10 changes: 8 additions & 2 deletions src/shared/url.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const { URL } = require("url");

/**
* url.js
* A collection of functions for comparing URLs.
* We'll be doing a lot of that when targetting links to send to the widget.
*/

const { URL } = require("url");

/**
* Get a URL object from a string, if possible.
* @param {string} input A string representation of the URL.
Expand Down Expand Up @@ -60,6 +60,12 @@ const comparePaths = (pUrl1, pUrl2) => {
return normalizePath(pUrl1) === normalizePath(pUrl2);
};

/**
* See if two URLs have matching hostnames and pathnames.
* @param {URL} pUrl1 A URL object for the first URL.
* @param {URL} pUrl2 A URL object for the second URL.
* @returns {boolean}
*/
const compare = (pUrl1, pUrl2) => {
return compareHosts(pUrl1, pUrl2) && comparePaths(pUrl1, pUrl2);
};
Expand Down

0 comments on commit b44543b

Please sign in to comment.