feat: init public notes

This commit is contained in:
Julien Calixte
2026-02-10 19:17:30 +01:00
parent eb88bfa8e4
commit 674bf84fe0
8 changed files with 216 additions and 16 deletions

View File

@@ -19,10 +19,14 @@
"@octokit/core": "^7.0.6",
"@octokit/rest": "^22.0.1",
"@tailwindcss/postcss": "^4.1.16",
"@tanstack/vue-query": "^5.92.9",
"@toycode/markdown-it-class": "^1.2.4",
"@ts-rest/core": "^3.52.1",
"@ts-rest/vue-query": "^3.52.1",
"@vscode/markdown-it-katex": "^1.1.2",
"@vueuse/core": "^13.6.0",
"@vueuse/router": "^13.6.0",
"arktype": "^2.1.29",
"date-fns": "^4.1.0",
"events": "^3.3.0",
"font-color-contrast": "^11.1.0",

105
pnpm-lock.yaml generated
View File

@@ -20,9 +20,18 @@ importers:
'@tailwindcss/postcss':
specifier: ^4.1.16
version: 4.1.16
'@tanstack/vue-query':
specifier: ^5.92.9
version: 5.92.9(vue@3.5.18(typescript@5.9.3))
'@toycode/markdown-it-class':
specifier: ^1.2.4
version: 1.2.4
'@ts-rest/core':
specifier: ^3.52.1
version: 3.52.1(@types/node@22.15.24)
'@ts-rest/vue-query':
specifier: ^3.52.1
version: 3.52.1(@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3)))(@ts-rest/core@3.52.1(@types/node@22.15.24))
'@vscode/markdown-it-katex':
specifier: ^1.1.2
version: 1.1.2
@@ -32,6 +41,9 @@ importers:
'@vueuse/router':
specifier: ^13.6.0
version: 13.6.0(vue-router@4.5.1(vue@3.5.18(typescript@5.9.3)))(vue@3.5.18(typescript@5.9.3))
arktype:
specifier: ^2.1.29
version: 2.1.29
date-fns:
specifier: ^4.1.0
version: 4.1.0
@@ -227,6 +239,12 @@ packages:
peerDependencies:
ajv: '>=8'
'@ark/schema@0.56.0':
resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==}
'@ark/util@0.56.0':
resolution: {integrity: sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==}
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
@@ -1491,9 +1509,46 @@ packages:
peerDependencies:
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
'@tanstack/match-sorter-utils@8.19.4':
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
engines: {node: '>=12'}
'@tanstack/query-core@5.90.20':
resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==}
'@tanstack/vue-query@5.92.9':
resolution: {integrity: sha512-jjAZcqKveyX0C4w/6zUqbnqk/XzuxNWaFsWjGTJWULVFizUNeLGME2gf9vVSDclIyiBhR13oZJPPs6fJgfpIJQ==}
peerDependencies:
'@vue/composition-api': ^1.1.2
vue: ^2.6.0 || ^3.3.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
'@toycode/markdown-it-class@1.2.4':
resolution: {integrity: sha512-hA4gHBK8moObkOYdWTjhy1wYcYy0MJeM3JjSKbsXHRpRMvIKhk6Jm+t3bXsSScTdz/byWqQbs8YIwVYjHp+SlQ==}
'@ts-rest/core@3.52.1':
resolution: {integrity: sha512-tAjz7Kxq/grJodcTA1Anop4AVRDlD40fkksEV5Mmal88VoZeRKAG8oMHsDwdwPZz+B/zgnz0q2sF+cm5M7Bc7g==}
peerDependencies:
'@types/node': ^18.18.7 || >=20.8.4
zod: ^3.22.3
peerDependenciesMeta:
'@types/node':
optional: true
zod:
optional: true
'@ts-rest/vue-query@3.52.1':
resolution: {integrity: sha512-89u7aS9LGDC7uNUC5CagWX1EB7vTwyXohYcizLi1D9v7MD/Cnu5OTQNf8SY3PuAK62RcFJXB2XZGsMAPC0svNw==}
peerDependencies:
'@tanstack/vue-query': ^4.0.0
'@ts-rest/core': ~3.52.0
zod: ^3.22.3
peerDependenciesMeta:
zod:
optional: true
'@types/chai@5.2.2':
resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
@@ -1955,6 +2010,12 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
arkregex@0.0.5:
resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==}
arktype@2.1.29:
resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==}
array-buffer-byte-length@1.0.2:
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
engines: {node: '>= 0.4'}
@@ -3675,6 +3736,9 @@ packages:
resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==}
hasBin: true
remove-accents@0.5.0:
resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==}
require-from-string@2.0.2:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
@@ -4415,6 +4479,12 @@ snapshots:
jsonpointer: 5.0.1
leven: 3.1.0
'@ark/schema@0.56.0':
dependencies:
'@ark/util': 0.56.0
'@ark/util@0.56.0': {}
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.27.1
@@ -5762,8 +5832,31 @@ snapshots:
postcss-selector-parser: 6.0.10
tailwindcss: 4.1.16
'@tanstack/match-sorter-utils@8.19.4':
dependencies:
remove-accents: 0.5.0
'@tanstack/query-core@5.90.20': {}
'@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3))':
dependencies:
'@tanstack/match-sorter-utils': 8.19.4
'@tanstack/query-core': 5.90.20
'@vue/devtools-api': 6.6.4
vue: 3.5.18(typescript@5.9.3)
vue-demi: 0.14.10(vue@3.5.18(typescript@5.9.3))
'@toycode/markdown-it-class@1.2.4': {}
'@ts-rest/core@3.52.1(@types/node@22.15.24)':
optionalDependencies:
'@types/node': 22.15.24
'@ts-rest/vue-query@3.52.1(@tanstack/vue-query@5.92.9(vue@3.5.18(typescript@5.9.3)))(@ts-rest/core@3.52.1(@types/node@22.15.24))':
dependencies:
'@tanstack/vue-query': 5.92.9(vue@3.5.18(typescript@5.9.3))
'@ts-rest/core': 3.52.1(@types/node@22.15.24)
'@types/chai@5.2.2':
dependencies:
'@types/deep-eql': 4.0.2
@@ -6389,6 +6482,16 @@ snapshots:
argparse@2.0.1: {}
arkregex@0.0.5:
dependencies:
'@ark/util': 0.56.0
arktype@2.1.29:
dependencies:
'@ark/schema': 0.56.0
'@ark/util': 0.56.0
arkregex: 0.0.5
array-buffer-byte-length@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -8205,6 +8308,8 @@ snapshots:
dependencies:
jsesc: 3.1.0
remove-accents@0.5.0: {}
require-from-string@2.0.2: {}
resolve-from@4.0.0: {}

View File

@@ -1,5 +0,0 @@
onlyBuiltDependencies:
- '@parcel/watcher'
- '@tailwindcss/oxide'
- esbuild
- vue-demi

View File

@@ -19,6 +19,9 @@
<router-link v-if="isLogged" :to="{ name: 'RepoList' }" class="btn"
>Manage your repos</router-link
>
<router-link :to="{ name: 'PublicNoteList' }" class="btn"
>Public notes</router-link
>
</div>
<form class="github-form" @submit.prevent>

View File

@@ -1,18 +1,24 @@
import 'notyf/notyf.min.css'
import './styles/app.css'
import "notyf/notyf.min.css"
import "./styles/app.css"
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import { createPinia } from "pinia"
import { createApp } from "vue"
import { createI18n } from "vue-i18n"
import { messages } from '@/locales/message'
import { router } from '@/router/router'
import { messages } from "@/locales/message"
import { router } from "@/router/router"
import { VueQueryPlugin } from "@tanstack/vue-query"
import App from './App.vue'
import App from "./App.vue"
const i18n = createI18n({
locale: 'en',
messages
locale: "en",
messages,
})
createApp(App).use(router).use(i18n).use(createPinia()).mount('#app')
createApp(App)
.use(router)
.use(VueQueryPlugin)
.use(i18n)
.use(createPinia())
.mount("#app")

View File

@@ -0,0 +1,64 @@
import { initContract } from "@ts-rest/core"
import { type } from "arktype"
import { initQueryClient } from "@ts-rest/vue-query"
const PublicNoteListItem = type({
did: "string",
rkey: "string",
title: "string",
publishedAt: "string",
createdAt: "string",
})
export type PublicNoteListItem = typeof PublicNoteListItem.infer
const PublicNote = type({
did: "string",
rkey: "string",
title: "string",
content: "string",
publishedAt: "string",
createdAt: "string",
})
export type PublicNote = typeof PublicNote.infer
const contract = initContract()
export const noteRouter = contract.router({
noteLists: {
method: "GET",
path: "/notes",
query: type({
cursor: "string | undefined",
limit: "number | undefined",
}),
responses: {
200: type({
notes: PublicNoteListItem.array(),
}),
},
summary: "List all notes",
},
noteListsByDid: {
method: "GET",
path: "/:did/notes",
pathParams: type({
did: "string",
}),
query: type({
cursor: "string | undefined",
limit: "number | undefined",
}),
responses: {
200: type({
notes: PublicNoteListItem.array(),
}),
},
summary: "List all notes",
},
})
export const client = initQueryClient(noteRouter, {
baseUrl: "https://api.litenote.li212.fr",
})

View File

@@ -8,6 +8,11 @@ const routes: Array<RouteRecordRaw> = [
name: "RepoList",
component: () => import("@/views/RepoList.vue"),
},
{
path: "/notes",
name: "PublicNoteList",
component: () => import("@/views/PublicNoteList.vue"),
},
{
path: "/:user/:repo",
name: "FluxNoteView",

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import { noteRouter } from "@/modules/post/data/client"
const { data: notes, isLoading } = noteRouter.noteLists.get.useQuery(["notes"])
</script>
<template>
<div class="public-note-view" v-if="isLoading">
<ul>
<li v-for="note in notes">{{ note.did }} / {{ note.rkey }}</li>
</ul>
</div>
</template>
<style scoped lang="scss">
.public-note-view {
}
</style>