/** * Pireon Admin API — the public payloads. * * Generated from openapi.yaml by `php artisan api:types`. Do not edit: * change the specification instead, and the contract test will hold the * API to it. */ /** * The same record's path in each language that has a translation. Feed * these straight into ``. Languages with * no translation are absent, so no advertised URL ever 404s. */ export type Alternates = Record; /** * Everything needed to render an image well server-side. A path alone * was never enough: without `width`/`height` the page reflows as images * arrive, without `srcset` every visitor downloads the original, and * without `alt` the page is not accessible. * * Degrades on purpose — an upload whose derived versions are not ready * yet still carries a `url`, with the rest null, so the frontend renders * a plain `` rather than a gap. */ export interface Image { /** * Absolute, because the frontend is on another host. */ url: string; /** * Empty string when the image is decorative — that is what `alt=""` * means — never absent. Follows the requested language. */ alt: string; width?: number; height?: number; aspect_ratio?: number; mime?: string; /** * Tiny blurred data URI to paint while the real image loads. */ placeholder?: string; /** * Keyed by format, ready to use verbatim — build a `` with * AVIF first and WebP behind it. Only widths that actually exist are * listed, and an image is never scaled up. */ srcset?: Record; } /** * A call for contributors. The commitment fields are the point: time is * the scarce resource in a volunteer collective, and stating it plainly * is what lets someone decide. */ export interface PublicCall { id: number; locale: string; title: string; slug: string; description?: string; /** * The explicit exchange offered for unpaid work. */ what_you_get?: string; status: 'open' | 'filled' | 'closed'; hours_per_week?: number; duration_weeks?: number; total_hours?: number; seniority?: 'any' | 'junior' | 'mid' | 'senior'; closes_at?: string; project: PublicProject; technologies: PublicTechnology[]; alternates: Alternates; path?: string; } export interface PublicCategory { id: number; name?: string; slug?: string; description?: string; color?: string; position: number; pages_count: number; } export interface PublicClient { id: number; /** * A proper noun, so it is the same in every language. */ name: string; slug: string; sector?: string; url?: string; /** * Its alt text is the organisation's name. */ logo?: Image; projects_count: number; } export interface PublicIssue { number: number; title: string; url: string; labels: string[]; is_good_first_issue: boolean; is_help_wanted: boolean; /** * Nobody has claimed it. A claimed issue is not an invitation. */ is_available: boolean; comments: number; created_at?: string; repository: { full_name: string; url?: string; primary_language?: string; project?: { title: string; slug: string } }; } export interface PublicMember { id: number; name: string; slug: string; headline?: string; bio?: string; avatar?: Image; github_username?: string; links: Record; is_founder: boolean; /** * False for people who have left; their work is kept. */ is_current: boolean; joined_at?: string; left_at?: string; /** * Their role on a project, when nested under one. */ role?: string; technologies: PublicTechnology[]; projects: PublicProject[]; alternates: Alternates; path: string; } export interface PublicPage { id: number; locale: string; title?: string; slug?: string; excerpt?: string; body?: string; meta_title?: string; meta_description?: string; status: string; is_featured: boolean; featured_image?: Image; published_at?: string; /** * When the record leaves the site. Enforced by the query itself, so * it holds whether or not anything is running. Use it to expire a * cache downstream at the same moment. */ unpublish_at?: string; updated_at: string; category: PublicCategory; /** * The ones named in this language, to link to the blog filtered by each. */ tags: ({ name: string; slug: string })[]; /** * The member who signs it, when they have a public profile. */ byline?: { name: string; slug: string; headline?: string; avatar?: Image; path: string }; alternates: Alternates; path?: string; } export interface PublicProject { id: number; locale: string; title: string; slug: string; tagline?: string; /** * Detail endpoint only. */ description?: string; /** * Why the technical choices were made. Detail endpoint only. */ decisions?: string; /** * What went wrong and what was learned. Detail endpoint only. */ postmortem?: string; /** * What a search engine or a chat preview should show instead of the * title. Detail endpoint only. */ meta_title?: string; /** * Detail endpoint only. */ meta_description?: string; status: 'idea' | 'active' | 'paused' | 'completed' | 'archived'; is_featured: boolean; /** * Flagged directly, or carrying at least one open call. */ needs_help: boolean; cover_image?: Image; /** * Screenshots and before-and-after, in the order they were arranged * in the panel. **Detail endpoint only** — a listing of twenty * projects has no use for every screenshot of each one. */ gallery: (Image & { caption?: string })[]; demo_url?: string; /** * The NGO or association the work serves. Used to be two free-text * fields, which made the same organisation two different things. */ client?: PublicClient; services: PublicService[]; testimonials: PublicTestimonial[]; talks: PublicTalk[]; started_at?: string; ended_at?: string; published_at?: string; /** * When the record leaves the site. Enforced by the query itself, so * it holds whether or not anything is running. Use it to expire a * cache downstream at the same moment. */ unpublish_at?: string; updated_at: string; technologies: PublicTechnology[]; members: PublicMember[]; lead: PublicMember; calls: PublicCall[]; repositories: PublicRepository[]; alternates: Alternates; path?: string; } /** * Mirrored from the git provider and refreshed hourly. */ export interface PublicRepository { id: number; provider: 'github' | 'gitlab' | 'gitea'; full_name: string; url?: string; description?: string; primary_language?: string; /** * Bytes of code per language. */ languages: Record; topics: string[]; license?: string; stars: number; forks: number; contributors_count: number; open_issues_count: number; is_archived: boolean; /** * Nothing pushed for six months. Lets the frontend avoid presenting * dead work as live. */ is_dormant: boolean; pushed_at?: string; synced_at?: string; good_first_issues: PublicIssue[]; } export interface PublicSearchResult { type: 'page' | 'project' | 'service' | 'call' | 'member' | 'technology'; id: number; title: string; /** * Plain text around the first match. */ excerpt: string; path?: string; /** * Higher is a better match. Only comparable within one response. */ score: number; } export interface PublicService { id: number; locale: string; title: string; slug: string; tagline?: string; /** * Detail endpoint only. */ description?: string; /** * What a search engine or a chat preview should show instead of the * title. Detail endpoint only. */ meta_title?: string; /** * Detail endpoint only. */ meta_description?: string; /** * A Heroicons name, e.g. `heroicon-o-code-bracket`. */ icon?: string; is_featured: boolean; position: number; /** * So a cache downstream can tell whether its copy is still the * current one. */ updated_at?: string; /** * The published work that backs the offer. Detail endpoint only. */ projects: PublicProject[]; technologies: PublicTechnology[]; testimonials: PublicTestimonial[]; alternates: Alternates; path?: string; } export interface PublicTalk { id: number; /** * Not translated: the name of a talk given once, in one language. */ title: string; language: string; summary?: string; event: string; city?: string; held_at?: string; video_url?: string; slides_url?: string; speaker?: PublicMember; } export interface PublicTechnology { id: number; /** * Not translated — technology names are proper nouns. */ name: string; slug: string; category: 'language' | 'framework' | 'datastore' | 'infrastructure' | 'tool' | 'practice'; color?: string; icon?: string; /** * The technology's own logo. Its `alt` is the technology's name — * there is nothing to write and nothing to get wrong. */ logo?: Image; website?: string; /** * Radar placement. Null for technologies used but not placed. */ ring?: 'adopt' | 'trial' | 'assess' | 'hold'; description?: string; /** * Why it sits in that ring. */ radar_note?: string; projects_count: number; members_count: number; } export interface PublicTestimonial { id: number; quote: string; /** * The language it was actually said in. */ original_locale: string; /** * False when the quote you are reading was translated by us. Say so — * "translated from Spanish" — rather than implying they phrased it * that way. */ is_original: boolean; author: { name: string; role?: string; avatar?: Image }; given_at?: string; client?: PublicClient; } /** * Either a plain string (applies to the active language) or an object * keyed by locale. */ export type TranslatedField = Record; /** What each public endpoint answers with, under `data`. */ export interface PublicApiPayloads { '/public/v1/site': { locales: ({ code: string; name: string; flag: string; is_default: boolean })[]; default_locale: string; content_version: number; submissions_enabled: boolean; stats: { projects: number; active_projects: number; members: number; open_calls: number; good_first_issues: number; stars: number } }; '/public/v1/slugs': Record })[]>; '/public/v1/redirects': ({ from: string; to: string; status: 301 | 302; locale?: string })[]; '/public/v1/search': PublicSearchResult[]; '/public/v1/tags': ({ name: string; slug: string; count: number })[]; '/public/v1/projects': PublicProject[]; '/public/v1/projects/{slug}': PublicProject; '/public/v1/members': PublicMember[]; '/public/v1/members/{slug}': PublicMember; '/public/v1/calls': PublicCall[]; '/public/v1/calls/{slug}': PublicCall; '/public/v1/services': PublicService[]; '/public/v1/services/{slug}': PublicService; '/public/v1/clients': PublicClient[]; '/public/v1/testimonials': PublicTestimonial[]; '/public/v1/talks': PublicTalk[]; '/public/v1/pages': PublicPage[]; '/public/v1/pages/{slug}': PublicPage; '/public/v1/technologies': PublicTechnology[]; '/public/v1/radar': PublicTechnology[]; '/public/v1/good-first-issues': PublicIssue[]; }