feat: add support for .all-contributors#78
Conversation
|
✅ Deploy Preview for astro-contributors ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds all-contributors support: new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
1 similar comment
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/astro-contributors/components/AllContributors.astro`:
- Around line 120-122: The grid CSS in AllContributors.astro currently uses a
responsive auto-fill layout and ignores the .all-contributorsrc
contributorsPerLine setting; update the component to read the
contributorsPerLine value (either passed as a prop or imported from the
.all-contributorsrc parsing logic used elsewhere) and use it to build the
grid-template-columns rule (e.g. use repeat(contributorsPerLine, minmax(140px,
1fr)) with a sensible fallback to the existing auto-fill behavior) so the layout
respects the contributorsPerLine configuration.
- Around line 76-81: AllContributors: the template uses contributor.profile
directly as the anchor href, which may allow unsafe schemes; update the code
that renders the <a> with contributor.profile to validate the URL first (e.g.,
in the component script or a helper) by constructing a URL in try/catch and only
allowing protocols 'http:' or 'https:'; if validation fails, render a safe
fallback (omit href or use '#' and/or add aria-disabled) or skip rendering the
anchor, ensuring any logic lives next to the contributor rendering (reference:
contributor.profile and the contributor-card anchor) so only validated HTTP(S)
links are output.
In `@packages/astro-contributors/libs/getAllContributorsRc.ts`:
- Around line 17-25: The function findAllContributorsRc currently JSON.parse()s
.all-contributorsrc and returns it cast to AllContributorsRc without runtime
checks; update findAllContributorsRc to validate the parsed object before
returning by verifying required top-level properties (e.g., contributors is an
array) and each contributor has expected fields (name, github username,
contributions array, etc.), returning null or throwing a clear error on
validation failure; you can implement this with a lightweight manual type guard
inside findAllContributorsRc or use an existing runtime validator (zod/io-ts)
and apply the same validation for the other similar parse site (lines 36-38) so
only safe, well-typed AllContributorsRc objects are returned.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e552b3bb-2bce-412a-a746-45452ce137b9
📒 Files selected for processing (7)
.all-contributorsrcdocs/astro.config.tsdocs/src/content/docs/all-contributors.mdxdocs/src/content/docs/parameters.mdxpackages/astro-contributors/components/AllContributors.astropackages/astro-contributors/index.tspackages/astro-contributors/libs/getAllContributorsRc.ts
There was a problem hiding this comment.
♻️ Duplicate comments (3)
packages/astro-contributors/components/AllContributors.astro (2)
75-81:⚠️ Potential issue | 🟠 MajorValidate profile URLs before rendering anchor
href.Line 77 trusts config input directly. Non-HTTP(S) schemes should be rejected before outputting links.
Proposed fix
const contributors = getAllContributorsFromRc(); +const toSafeHttpUrl = (value: string): string | null => { + try { + const url = new URL(value); + return url.protocol === "http:" || url.protocol === "https:" + ? url.toString() + : null; + } catch { + return null; + } +}; @@ - {contributors.map((contributor) => ( - <a - href={contributor.profile} + {contributors.map((contributor) => { + const safeProfile = toSafeHttpUrl(contributor.profile); + if (!safeProfile) return null; + return ( + <a + href={safeProfile} class="contributor-card" target="_blank" rel="noopener noreferrer" > @@ - </a> - ))} + </a> + )})}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/astro-contributors/components/AllContributors.astro` around lines 75 - 81, The template in AllContributors.astro uses contributor.profile directly in the anchor href inside contributors.map, which can emit non-HTTP(S) schemes; add a URL validation/sanitization step (e.g., an isValidHttpUrl or sanitizeProfileUrl helper) that accepts only http and https schemes and returns either the validated URL or null/empty, then use that sanitized value in the anchor (or render a non-link fallback) to avoid outputting unsafe schemes; update the contributors.map anchor logic to reference the sanitized variable instead of contributor.profile.
120-122: 🧹 Nitpick | 🔵 TrivialConsider honoring
.all-contributorsrccontributorsPerLinefor output parity.Line 121 hardcodes responsive auto-fill and ignores the explicit per-line layout config.
Proposed refactor
-import { getAllContributorsFromRc } from "../libs/getAllContributorsRc"; +import { findAllContributorsRc, getAllContributorsFromRc } from "../libs/getAllContributorsRc"; @@ const contributors = getAllContributorsFromRc(); +const rc = findAllContributorsRc(); +const contributorsPerLine = + Number.isInteger(rc?.contributorsPerLine) && (rc?.contributorsPerLine ?? 0) > 0 + ? rc!.contributorsPerLine + : undefined; @@ const styleOverride = { ...(focusColor && { "--ac-focus-color": focusColor }), ...(bgColor && { "--ac-bg-color": bgColor }), ...(borderColor && { "--ac-border-color": borderColor }), ...(textColor && { "--ac-text-color": textColor }), ...(badgeBgColor && { "--ac-badge-bg-color": badgeBgColor }), ...(badgeTextColor && { "--ac-badge-text-color": badgeTextColor }), + ...(contributorsPerLine && { + "--ac-grid-template-columns": `repeat(${contributorsPerLine}, minmax(140px, 1fr))`, + }), }; @@ - grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + grid-template-columns: var( + --ac-grid-template-columns, + repeat(auto-fill, minmax(140px, 1fr)) + );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/astro-contributors/components/AllContributors.astro` around lines 120 - 122, The grid currently hardcodes "grid-template-columns: repeat(auto-fill, minmax(140px, 1fr))" which ignores the .all-contributorsrc contributorsPerLine setting; update the AllContributors.astro component to read the contributorsPerLine value (either from the passed prop or the parsed .all-contributorsrc config used by this component) and use it to compute the CSS rule, e.g. set "grid-template-columns: repeat({contributorsPerLine}, minmax(140px, 1fr))" with a safe fallback to auto-fill when contributorsPerLine is absent or invalid; adjust the code that renders the style block in AllContributors.astro (where grid-template-columns is defined) to reference that variable.packages/astro-contributors/libs/getAllContributorsRc.ts (1)
23-25:⚠️ Potential issue | 🟠 MajorHarden
.all-contributorsrcparsing with runtime validation and parse guards.Lines 25 and 38 currently trust unvalidated JSON; malformed content can throw or propagate invalid contributor objects to rendering.
Proposed fix
export interface AllContributorsRc { contributors: RcContributor[]; [key: string]: any; } +function isRcContributor(value: unknown): value is RcContributor { + if (!value || typeof value !== "object") return false; + const v = value as Record<string, unknown>; + return ( + typeof v.login === "string" && + typeof v.name === "string" && + typeof v.avatar_url === "string" && + typeof v.profile === "string" && + Array.isArray(v.contributions) && + v.contributions.every((c) => typeof c === "string") + ); +} + +function isAllContributorsRc(value: unknown): value is AllContributorsRc { + if (!value || typeof value !== "object") return false; + const v = value as Record<string, unknown>; + return Array.isArray(v.contributors) && v.contributors.every(isRcContributor); +} + export function findAllContributorsRc(): AllContributorsRc | null { @@ if (fs.existsSync(filePath)) { - const content = fs.readFileSync(filePath, "utf-8"); - return JSON.parse(content) as AllContributorsRc; + try { + const content = fs.readFileSync(filePath, "utf-8"); + const parsed = JSON.parse(content) as unknown; + return isAllContributorsRc(parsed) ? parsed : null; + } catch { + return null; + } } @@ export function getAllContributorsFromRc(): RcContributor[] { const data = findAllContributorsRc(); - return data?.contributors || []; + return Array.isArray(data?.contributors) ? data.contributors : []; }Also applies to: 36-38
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/astro-contributors/libs/getAllContributorsRc.ts` around lines 23 - 25, The code currently calls JSON.parse on the .all-contributorsrc content (via fs.existsSync, fs.readFileSync and JSON.parse returning AllContributorsRc) without runtime validation; wrap the parse in a try/catch and add a runtime shape check (or use a small schema validator like zod) inside getAllContributorsRc to ensure the parsed object matches the AllContributorsRc shape (e.g., has a contributors array and expected fields) before returning it, and if validation fails return a safe default or throw a clear error; apply the same guarded parse/validation to the alternate parse path that also uses JSON.parse so malformed JSON or wrong shapes won’t leak into rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/astro-contributors/components/AllContributors.astro`:
- Around line 75-81: The template in AllContributors.astro uses
contributor.profile directly in the anchor href inside contributors.map, which
can emit non-HTTP(S) schemes; add a URL validation/sanitization step (e.g., an
isValidHttpUrl or sanitizeProfileUrl helper) that accepts only http and https
schemes and returns either the validated URL or null/empty, then use that
sanitized value in the anchor (or render a non-link fallback) to avoid
outputting unsafe schemes; update the contributors.map anchor logic to reference
the sanitized variable instead of contributor.profile.
- Around line 120-122: The grid currently hardcodes "grid-template-columns:
repeat(auto-fill, minmax(140px, 1fr))" which ignores the .all-contributorsrc
contributorsPerLine setting; update the AllContributors.astro component to read
the contributorsPerLine value (either from the passed prop or the parsed
.all-contributorsrc config used by this component) and use it to compute the CSS
rule, e.g. set "grid-template-columns: repeat({contributorsPerLine},
minmax(140px, 1fr))" with a safe fallback to auto-fill when contributorsPerLine
is absent or invalid; adjust the code that renders the style block in
AllContributors.astro (where grid-template-columns is defined) to reference that
variable.
In `@packages/astro-contributors/libs/getAllContributorsRc.ts`:
- Around line 23-25: The code currently calls JSON.parse on the
.all-contributorsrc content (via fs.existsSync, fs.readFileSync and JSON.parse
returning AllContributorsRc) without runtime validation; wrap the parse in a
try/catch and add a runtime shape check (or use a small schema validator like
zod) inside getAllContributorsRc to ensure the parsed object matches the
AllContributorsRc shape (e.g., has a contributors array and expected fields)
before returning it, and if validation fails return a safe default or throw a
clear error; apply the same guarded parse/validation to the alternate parse path
that also uses JSON.parse so malformed JSON or wrong shapes won’t leak into
rendering.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8fef0df5-660c-4959-8254-e2ee72d94988
📒 Files selected for processing (7)
.all-contributorsrcdocs/astro.config.tsdocs/src/content/docs/all-contributors.mdxdocs/src/content/docs/parameters.mdxpackages/astro-contributors/components/AllContributors.astropackages/astro-contributors/index.tspackages/astro-contributors/libs/getAllContributorsRc.ts
Description
Implement new
AllContributors.astrocomponent for the All Contributors project.all-contributorsrcfile to render contributors #6Summary by CodeRabbit
New Features
Documentation