From 6cbf096deecbb0f8b2bd4998d37dfbac7aae1461 Mon Sep 17 00:00:00 2001 From: Hunter Achieng Date: Thu, 4 Sep 2025 00:24:08 +0300 Subject: [PATCH 1/3] feat: implement adaptor labels Signed-off-by: Hunter Achieng --- adaptors/intro.mdx | 87 +++++++++++++++++++++++++++++++++++++- generate-adaptors/index.js | 78 +++++++++++++++++++++++++++++++--- 2 files changed, 158 insertions(+), 7 deletions(-) diff --git a/adaptors/intro.mdx b/adaptors/intro.mdx index 4dfe9bfdc9ac..9f2ac26b4114 100644 --- a/adaptors/intro.mdx +++ b/adaptors/intro.mdx @@ -44,11 +44,96 @@ adaptors is as follows: In short, _most_ adaptors follow the naming convention `@openfn/language-xyz`. +## Adaptor Badges + +OpenFn uses badges to label adaptors based on how they are built and maintained. +The scale being used is: + +- + + Actively maintained adaptor : Core + + + + +- + + Newly created adaptor by an external contributor: Community + + + + + + +- + Adaptors not actively maintained: Legacy + + + + + + ## Learn More About Adaptors Explore this YouTube playlist to gain a deeper understanding of OpenFn adaptors. - + ## Adaptors vs. Workflows diff --git a/generate-adaptors/index.js b/generate-adaptors/index.js index 88b4d2b66c85..dba2d903abd3 100644 --- a/generate-adaptors/index.js +++ b/generate-adaptors/index.js @@ -5,6 +5,70 @@ const chokidar = require('chokidar'); const versions = []; +const badges = [ + { + name: 'core', + icon: ` `, + emoji:'⛨', + }, + { + name: 'community', + icon: ` + + `, + emoji:'👥' + }, + { + name: 'legacy', + icon: ` + + +`, +emoji:'⚙️' + }, +]; async function listVersions(next) { const url = next || `https://api.github.com/repos/OpenFn/adaptors/tags`; @@ -90,22 +154,25 @@ function pushToPaths(name) { function generateJsDoc(a) { // Add line break before tags and escape curly braces outside of code blocks let docsContent = JSON.parse(a.docs).replace(/<\/dt>/g, '\n'); - + // Split content by code blocks (both inline ` and multi-line ```) const codeBlockRegex = /(```[\s\S]*?```|`[^`]*`)/g; const parts = docsContent.split(codeBlockRegex); - + // Escape curly braces only in non-code parts (odd indices are code blocks) for (let i = 0; i < parts.length; i++) { - if (i % 2 === 0) { // Non-code parts + if (i % 2 === 0) { + // Non-code parts parts[i] = parts[i].replace(/{/g, '\\{').replace(/}/g, '\\}'); } } - + docsContent = parts.join(''); + const icon = badges.find(b => b.name === a.badge?.toLowerCase())?.emoji || ''; + return `--- -title: ${a.name}@${a.version} +title: ${a.name}@${a.version}-${icon} id: ${a.name}-docs keywords: - adaptor @@ -227,7 +294,6 @@ async function buildAdaptors(monorepoPath) { if (!a.name) { return; } - const docsBody = generateJsDoc(a); const readmeBody = generateReadme(a); const changelogBody = generateChangelog(a); From 8c4c5386575c46d9a17bd312d71b90cae8f09fa6 Mon Sep 17 00:00:00 2001 From: Hunter Achieng Date: Thu, 4 Sep 2025 14:12:58 +0300 Subject: [PATCH 2/3] feat: use md images for icons Signed-off-by: Hunter Achieng --- adaptors/intro.mdx | 117 +++++++++++-------------- generate-adaptors/index.js | 76 ++++------------ static/img/heroicons--cog.svg | 1 + static/img/heroicons--shield-check.svg | 1 + static/img/heroicons--users.svg | 1 + 5 files changed, 71 insertions(+), 125 deletions(-) create mode 100644 static/img/heroicons--cog.svg create mode 100644 static/img/heroicons--shield-check.svg create mode 100644 static/img/heroicons--users.svg diff --git a/adaptors/intro.mdx b/adaptors/intro.mdx index 9f2ac26b4114..d19c89c0f85d 100644 --- a/adaptors/intro.mdx +++ b/adaptors/intro.mdx @@ -49,77 +49,60 @@ In short, _most_ adaptors follow the naming convention `@openfn/language-xyz`. OpenFn uses badges to label adaptors based on how they are built and maintained. The scale being used is: -- - - Actively maintained adaptor : Core - -
+ Actively maintained adaptor : Core + Core badge - - - -- - - Newly created adaptor by an external contributor: Community - - - + +

+ Core adaptors are actively maintained by the OpenFn team and/or trusted partners. + They receive regular updates, security fixes, and documentation improvements. +

+
+ + +-
+
+ Newly created adaptor by an external contributor: Community + Community badge - - - -- - Adaptors not actively maintained: Legacy - - + +

+ Community adaptors are contributed by external developers and may not follow a regular + maintenance cadence. Contributions and PRs are welcome. +

+
+ + +-
+
+ Adaptors not actively maintained: Legacy + Legacy badge - +
+

+ Legacy adaptors are not actively maintained and may not receive updates. +

+
- ## Learn More About Adaptors diff --git a/generate-adaptors/index.js b/generate-adaptors/index.js index dba2d903abd3..6dc79fb0ef78 100644 --- a/generate-adaptors/index.js +++ b/generate-adaptors/index.js @@ -7,66 +7,19 @@ const versions = []; const badges = [ { - name: 'core', - icon: ` `, - emoji:'⛨', + name: 'Core', + icon: `/img/heroicons--shield-check.svg`, + link: '/adaptors#adaptor-badges', }, { - name: 'community', - icon: ` - - `, - emoji:'👥' + name: 'Community', + icon: ` /img/heroicons--users.svg`, + link: '/adaptors#adaptor-badges', }, { - name: 'legacy', - icon: ` - - -`, -emoji:'⚙️' + name: 'Legacy', + icon: ` /img/heroicons--cog.svg`, + link: '/adaptors#adaptor-badges', }, ]; async function listVersions(next) { @@ -169,10 +122,12 @@ function generateJsDoc(a) { docsContent = parts.join(''); - const icon = badges.find(b => b.name === a.badge?.toLowerCase())?.emoji || ''; + const icon = badges.find( + b => b.name?.toLowerCase() === a.badge?.toLowerCase() + ); return `--- -title: ${a.name}@${a.version}-${icon} +title: ${a.name}@${a.version} id: ${a.name}-docs keywords: - adaptor @@ -180,6 +135,11 @@ keywords: ${a.functions.length > 0 ? '- ' : ''}${a.functions.join('\r\n - ')} --- + +#### Badge: [${icon?.name || ''} ${ + icon?.icon ? `![badge](${icon.icon})` : '' + }](${icon?.link || '#'}) + ${docsContent}`; } diff --git a/static/img/heroicons--cog.svg b/static/img/heroicons--cog.svg new file mode 100644 index 000000000000..45ac78a88b4e --- /dev/null +++ b/static/img/heroicons--cog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/heroicons--shield-check.svg b/static/img/heroicons--shield-check.svg new file mode 100644 index 000000000000..c6bb0c7e1e12 --- /dev/null +++ b/static/img/heroicons--shield-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/heroicons--users.svg b/static/img/heroicons--users.svg new file mode 100644 index 000000000000..2f4fd3278179 --- /dev/null +++ b/static/img/heroicons--users.svg @@ -0,0 +1 @@ + \ No newline at end of file From 0ab5f854055e792288f9a082222441b4348a4957 Mon Sep 17 00:00:00 2001 From: Hunter Achieng Date: Thu, 4 Sep 2025 20:34:26 +0300 Subject: [PATCH 3/3] fix: create pill styles Signed-off-by: Hunter Achieng --- generate-adaptors/index.js | 17 +++++++++++------ src/css/custom.css | 20 +++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/generate-adaptors/index.js b/generate-adaptors/index.js index 6dc79fb0ef78..e7a6dd734c1c 100644 --- a/generate-adaptors/index.js +++ b/generate-adaptors/index.js @@ -9,17 +9,17 @@ const badges = [ { name: 'Core', icon: `/img/heroicons--shield-check.svg`, - link: '/adaptors#adaptor-badges', + link: '/adaptors/#adaptor-badges', }, { name: 'Community', icon: ` /img/heroicons--users.svg`, - link: '/adaptors#adaptor-badges', + link: '/adaptors/#adaptor-badges', }, { name: 'Legacy', icon: ` /img/heroicons--cog.svg`, - link: '/adaptors#adaptor-badges', + link: '/adaptors/#adaptor-badges', }, ]; async function listVersions(next) { @@ -135,10 +135,15 @@ keywords: ${a.functions.length > 0 ? '- ' : ''}${a.functions.join('\r\n - ')} --- + + ${icon?.name || ''} + ${icon?.icon ? `` : ''} + -#### Badge: [${icon?.name || ''} ${ - icon?.icon ? `![badge](${icon.icon})` : '' - }](${icon?.link || '#'}) ${docsContent}`; } diff --git a/src/css/custom.css b/src/css/custom.css index 731ebccb56da..b3f92480f724 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -71,9 +71,27 @@ html[data-theme='dark'] .header-github-link:before { margin-bottom: 20px; padding-top: 12px; - text-align: center; + text-align: center; border: solid 1px #c0c0c0; border-radius: 8px; min-width: 300px; max-width: 400px; } + +.badge-pill { + display: inline-flex; + align-items: center; + gap: 0.35rem; + padding: 5px 10px; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 9999px; + background: rgb(225, 225, 230); + color: inherit; + text-decoration: none; + line-height: 1.1; +} +.badge-pill img { + width: 1.2em; + height: 1.2em; + transform: translateY(0.05em); +}