Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"fetch": "run-p fetch:*",
"fetch:readmes": "node src/utilities/fetch-package-readmes.mjs",
"fetch:supporters": "node src/utilities/fetch-supporters.mjs",
"fetch:footer": "node src/utilities/fetch-footer.mjs",
"fetch:governance": "node src/utilities/fetch-governance.mjs",
"fetch-all": "run-s fetch-repos fetch",
"prebuild": "npm run clean",
Expand Down
19 changes: 9 additions & 10 deletions src/components/Footer/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Icon from "../../assets/icon-square-small.svg";
import OpenJSLogo from "../../assets/openjs-logo.png";
import Container from "../Container/Container.jsx";
import Link from "../Link/Link.jsx";
import footerLegal from './_footer-legal.json';

const footerLinkClasses =
"text-[11px] uppercase text-[#777676] dark:text-[#cccccc] hover:text-[#333333] dark:hover:text-[#ffffff]";
Expand Down Expand Up @@ -36,16 +37,14 @@ const Footer = () => (
holders. Use of them does not imply any affiliation with or endorsement
by them.
</p>
<p className="mx-auto mt-[18px] text-[15px] leading-[1.6] text-[#333333] dark:text-[#e0e0e0]">
<a href="https://openjsf.org">The OpenJS Foundation</a> |{" "}
<a href="https://terms-of-use.openjsf.org">Terms of Use</a> |{" "}
<a href="https://privacy-policy.openjsf.org">Privacy Policy</a> |{" "}
<a href="https://bylaws.openjsf.org">Bylaws</a> |{" "}
<a href="https://code-of-conduct.openjsf.org">Code of Conduct</a> |{" "}
<a href="https://trademark-policy.openjsf.org">Trademark Policy</a> |{" "}
<a href="https://trademark-list.openjsf.org">Trademark List</a> |{" "}
<a href="https://www.linuxfoundation.org/cookies">Cookie Policy</a>
</p>
<p className="mx-auto mt-[18px] text-[15px] leading-[1.6] text-[#333333] dark:text-[#e0e0e0]">
{footerLegal.links.map((link, i) => (
<span key={link.url}>
{i > 0 && ' | '}
<a href={link.url}>{link.label}</a>a>
</span>
))}
</p>
</Container>
<Container className="flex flex-wrap justify-center gap-y-4 content-center border-t border-[#f2f2f2] px-0 py-[0.4em] md:flex-row md:justify-between">
<section
Expand Down
56 changes: 56 additions & 0 deletions src/utilities/fetch-footer.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { writeFile, mkdir } from 'fs/promises';

Check failure on line 1 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

Strings must use doublequote

Check failure on line 1 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

Prefer `node:fs/promises` over `fs/promises`

Check failure on line 1 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

Replace `'fs/promises'` with `"fs/promises"`

Check failure on line 1 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

`mkdir` import should occur before import of `writeFile`
import path from 'path';

Check failure on line 2 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

Prefer `node:path` over `path`

Check failure on line 2 in src/utilities/fetch-footer.mjs

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest, lts/*)

Replace `'path'` with `"path"`

const ARTWORK_README_URL =
'https://raw.githubusercontent.com/openjs-foundation/artwork/main/README.md';
const OUTPUT_PATH = path.resolve(
'src/components/Footer/_footer-legal.json'
);

async function fetchFooter() {
console.log('Fetching OpenJS Foundation footer template...');

const response = await fetch(ARTWORK_README_URL);
if (!response.ok) {
throw new Error(`Failed to fetch artwork README: ${response.status}`);
}
const readme = await response.text();

// Extract the HTML block under "### HTML"
const htmlSectionMatch = readme.match(
/### HTML\s*\n+```html\s*\n([\s\S]*?)\n```/
);

if (!htmlSectionMatch) {
throw new Error(
'Could not find HTML footer template in artwork README'
);
}

const html = htmlSectionMatch[1].trim();

// Parse links from the footer HTML
const linkRegex = /<a\s+href="([^"]+)">([^<]+)<\/a>/g;
const paragraphs = html.split('</p>');

// Second paragraph contains the links bar
const linksSection = paragraphs.length > 1 ? paragraphs[1] : '';
const links = [];
let match;
while ((match = linkRegex.exec(linksSection)) !== null) {
links.push({ url: match[1], label: match[2] });
}

const data = { links };

await mkdir(path.dirname(OUTPUT_PATH), { recursive: true });
await writeFile(OUTPUT_PATH, JSON.stringify(data, null, 2));

console.log(`Footer data written to ${OUTPUT_PATH}`);
console.log(`Found ${links.length} footer links`);
}

fetchFooter().catch((err) => {
console.error('Error fetching footer:', err);
process.exit(1);
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this AI generated code?

Loading