Files
vue-journal-layer/app/utils/types.ts
Jakub Zych 6f6792f51c feat: scaffold Journal layer with configurable post route and git-install check
- journal module registers the Journal pages at journal.routes paths
- typed anonymous-GET client, html gate, SSR x-forwarded-for forwarding
- fixture API, built-server SSR smoke and git-tag install check
2026-10-09 17:31:45 +02:00

144 lines
3.5 KiB
TypeScript

// Wire types of the anonymous Journal API (/_journal/api/v1). Field names
// mirror the Go serializers exactly (snake_case); a field is nullable where
// Go can emit null. Types only, so `node --test` can import any util.
/** The author object embedded in a post row. `null` when the post has none. */
export interface JournalAuthorRef {
id: number
first_name: string
last_name: string
login: string
}
/** A category or tag reference embedded in a post row. */
export interface JournalTermRef {
id: number
name: string
slug: string
}
export interface JournalFeaturedImage {
id: number
url: string
file_name: string
file_size: number
}
/** One post row, as GET /posts and GET /authors/{author}/posts list it. */
export interface JournalPost {
id: number
title: string
slug: string
excerpt: string | null
content: string | null
content_html: string | null
reading_time: number
published: boolean
/** UTC, "2006-01-02T15:04:05+00:00". */
published_at: string | null
is_pinned: boolean
metadata: unknown
sources: unknown
author: JournalAuthorRef | null
categories: JournalTermRef[]
tags: JournalTermRef[]
featured_images: JournalFeaturedImage[]
featured_image_url: string | null
translations: unknown
created_at: string | null
updated_at: string | null
}
/** previous_post / next_post on GET /posts/{slug}. */
export interface JournalPostSibling {
id: number
title: string
slug: string
}
/** GET /posts/{slug} data: the post plus its neighbours and related posts. */
export interface JournalPostDetail extends JournalPost {
previous_post: JournalPostSibling | null
next_post: JournalPostSibling | null
/** Latest 3 in the same categories; empty when the post has no category. */
related_posts: JournalPost[]
}
/** One node of the GET /categories tree. */
export interface JournalCategory {
id: number
name: string
slug: string
description: string | null
/** Rich HTML body of the category page, stored as is; null when unset. */
content: string | null
parent_id: number | null
nest_depth: number | null
post_count: number
children?: JournalCategory[]
}
export interface JournalTag {
id: number
name: string
slug: string
post_count: number
}
/**
* GET /authors/{author} data. `slug` is the canonical identifier: the author
* slug when set, otherwise the login. Missing names are "".
*/
export interface JournalAuthor {
id: number
slug: string
first_name: string
last_name: string
}
export interface JournalPageMeta {
current_page: number
last_page: number
per_page: number
total: number
}
/** The paginated envelope of GET /posts and GET /authors/{author}/posts. */
export interface JournalPage<T> {
data: T[]
meta: JournalPageMeta
}
/** The single-object envelope ({ data }) of show and list endpoints. */
export interface JournalItem<T> {
data: T
}
/** Route paths per Journal view; `false` disables the view. */
export interface JournalRoutes {
index: string | false
post: string | false
category: string | false
tag: string | false
author: string | false
}
export interface JournalPerPage {
index: number
category: number
tag: number
author: number
}
/** Options of the `journal` config key in nuxt.config. */
export interface JournalModuleOptions {
routes: JournalRoutes
perPage: JournalPerPage
/** "<column> <asc|desc>", column one of published_at, created_at, updated_at, title, id. */
sort: string
/** How many related posts a post page shows. */
relatedCount: number
/** Whether /rss.xml is served and linked. */
rss: boolean
}