Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/santiagonieto09/portafolio/llms.txt

Use this file to discover all available pages before exploring further.

src/domain/portfolio/repository-query.ts contains all filtering, sorting, and collection logic for the repository explorer. These are pure functions with no side effects — they take plain data in and return plain data out, with zero dependency on React state, browser APIs, or network calls. That means they can be unit-tested in isolation, reused in server-side loaders, and reasoned about without any UI context.

RepositoryQuery Interface

RepositoryQuery is the single object that encodes a user’s current explorer state: what they have searched for, which filters are active, and how results should be ordered. It is kept in URL search params so that the filtered view is shareable and bookmarkable.
interface RepositoryQuery {
  search: string;
  language: string | null;
  technology: string | null;
  onlyWithRelease: boolean;
  onlyWithSite: boolean;
  onlyWithDocs: boolean;
  onlyArchived: boolean;
  onlyActive: boolean;
  sort: 'updated' | 'created' | 'stars' | 'name';
  direction: 'desc' | 'asc';
}
Free-text search term matched case-insensitively against five fields of each repository: name, description, each key in languages, each entry in technologies, and each entry in topics. An empty string disables the search filter and all repositories pass through.
language
string | null
required
When non-null, restricts results to repositories that contain this language name as a key in their languages map (i.e. at least one byte of that language was detected). Pass null to remove the language filter. The available values are produced by collectLanguages.
technology
string | null
required
When non-null, restricts results to repositories whose technologies array includes this exact string. Technologies are framework/tool labels such as "React" or "Docker" — they are distinct from raw language names (see collectTechnologies). Pass null to remove the technology filter.
onlyWithRelease
boolean
required
When true, only repositories where release !== null are returned — i.e. repositories that have at least one published GitHub release.
onlyWithSite
boolean
required
When true, only repositories where homepage !== null are returned — i.e. repositories that have a live demo or project website URL set in their GitHub settings.
onlyWithDocs
boolean
required
When true, only repositories for which docsUrlFor(htmlUrl) returns a non-null URL are returned. This flag lets visitors browse only the projects that have dedicated documentation sites. See the note below for details on how docsUrlFor works.
onlyArchived
boolean
required
When true, only repositories where archived === true are returned. Cannot be true at the same time as onlyActive (the UI enforces mutual exclusivity).
onlyActive
boolean
required
When true, only repositories where archived === false are returned. Cannot be true at the same time as onlyArchived.
sort
'updated' | 'created' | 'stars' | 'name'
required
Determines which property is used as the sort key:
  • 'updated' — sorts by pushedAt (last code push timestamp).
  • 'created' — sorts by createdAt (repository creation timestamp).
  • 'stars' — sorts by stars (stargazer count).
  • 'name' — sorts alphabetically by name using localeCompare.
direction
'desc' | 'asc'
required
Sort direction applied on top of the sort key. 'desc' means most-recent / highest-value first (the default); 'asc' reverses the comparator.

defaultQuery

defaultQuery is the exported constant that serves as the baseline state for the repository explorer. When no URL search params are present, the UI initialises from this object, giving visitors an unfiltered, recently-updated view of all repositories.
const defaultQuery: RepositoryQuery = {
  search: '',
  language: null,
  technology: null,
  onlyWithRelease: false,
  onlyWithSite: false,
  onlyWithDocs: false,
  onlyArchived: false,
  onlyActive: false,
  sort: 'updated',
  direction: 'desc',
};
Import it wherever you need a safe, fully-typed starting point for building a partial query override:
import { defaultQuery } from '@/domain/portfolio/repository-query';

const myQuery = { ...defaultQuery, language: 'TypeScript', sort: 'stars' };

applyQuery(repos, query)

function applyQuery(repos: Repository[], query: RepositoryQuery): Repository[]
applyQuery is the core transformation function of the repository explorer. It applies all active filters in order and then sorts the surviving repositories, returning a new array without mutating the input.

Filtering

Filters run in the following order. A repository is excluded as soon as any single filter rejects it:
  1. searchmatchesSearch(repo, query.search) checks name, description, all languages keys, all technologies entries, and all topics entries for a case-insensitive substring match.
  2. language — checks that query.language is present as a key in repo.languages.
  3. technology — checks that query.technology is present in repo.technologies.
  4. onlyWithRelease — checks that repo.release !== null.
  5. onlyWithSite — checks that repo.homepage !== null.
  6. onlyWithDocs — checks that docsUrlFor(repo.htmlUrl) returns a non-null value.
  7. onlyArchived — checks that repo.archived === true.
  8. onlyActive — checks that repo.archived === false.

Sorting

After filtering, the result is sorted using one of four built-in comparators, each expressed in descending order. The direction field then flips the sign of the comparator when set to 'asc':
sort valueComparatorField used
'updated'+new Date(b.pushedAt) - +new Date(a.pushedAt)pushedAt — last Git push
'created'+new Date(b.createdAt) - +new Date(a.createdAt)createdAt — repository creation date
'stars'b.stars - a.starsstars — stargazer count
'name'b.name.localeCompare(a.name)name — alphabetical (Z→A when desc)
Setting direction: 'asc' multiplies the comparator result by -1, effectively reversing the order for all four sort keys. For example, sort: 'name', direction: 'asc' sorts A→Z.

Example

import { applyQuery, defaultQuery } from '@/domain/portfolio/repository-query';
import type { Repository } from '@/domain/github/types';

const filtered = applyQuery(snapshot.repositories, {
  ...defaultQuery,
  search: 'api',
  language: 'TypeScript',
  sort: 'stars',
  direction: 'desc',
});

collectLanguages(repos)

function collectLanguages(repos: Repository[]): string[]
Scans every repository in repos, collects all language names that appear as keys in each repo’s languages map, deduplicates them, and returns the result sorted alphabetically using the default locale comparator. The returned array is intended to populate the language filter <select> element in the repository explorer. Every string in the array is a valid value for RepositoryQuery.language.
import { collectLanguages } from '@/domain/portfolio/repository-query';

const languages = collectLanguages(snapshot.repositories);
// e.g. ['CSS', 'Dockerfile', 'HTML', 'Java', 'TypeScript', ...]

collectTechnologies(repos)

function collectTechnologies(repos: Repository[]): string[]
Scans every repository in repos, collects all entries from each repo’s technologies array, deduplicates them, and then excludes any technology name that is also a raw language name (as determined by collectLanguages). The filtered, unique set is returned sorted alphabetically. This distinction matters because technologies intentionally includes raw language names (e.g. "TypeScript", "Java") in addition to framework labels. collectTechnologies strips those raw language names so the technology dropdown contains only framework/tool labels like "React", "Spring Boot", or "Docker" — values that complement rather than duplicate the separate language dropdown.
import { collectTechnologies } from '@/domain/portfolio/repository-query';

const techs = collectTechnologies(snapshot.repositories);
// e.g. ['Angular', 'Docker', 'FastAPI', 'JPA / Hibernate', 'React', 'Spring Boot', ...]
onlyWithDocs uses docsUrlFor(htmlUrl) from src/lib/docs-url.ts to check whether a documentation site exists for a given repository. The utility converts a GitHub repository URL to its corresponding DeepWiki URL — for example https://github.com/owner/repo becomes https://deepwiki.com/owner/repo. It returns null for any URL that is not a valid GitHub repository URL (non-GitHub host, too few path segments, or a falsy input). Repositories for which docsUrlFor returns null are excluded when onlyWithDocs is true.

Build docs developers (and LLMs) love