AT Protocol OAuth template in Deno, Hono, HTMX

Revert "define qa lexicons, init utils"

This reverts commit 1282b02f765f2b79379e82b71dd0b665468e54de.

+48 -158
-1
.env.example
··· 1 - BASE_URL=<`http://127.0.0.1:8000` or `https://pedro.vote`> 2 1 COOKIE_SECRET=<`openssl rand -base64 64`>
+4 -12
README.md
··· 1 - # Pedro 2 - ### Ask questions, share opinions, vote together 3 - 4 - ## Feature Roadmap (WIP) 5 - - [ ] Question and Answers (~stackoverflow.com) 6 - - [ ] Upvote answers 7 - - [ ] Asker can highlight helpful answers 8 - - [ ] Poll 9 - - [ ] Single vs multiple choice 10 - - [ ] Live updates 11 - - [ ] Consensus (~pol.is) 12 - - [ ] Third-parties can add opinions 1 + # AT Protocol OAuth Template 2 + ### for Deno, Hono, and HTMX 13 3 14 4 ## Getting Started 15 5 1. Set up `.env` file with a `COOKIE_SECRET` variable ··· 27 17 - [`Hono`](https://hono.dev) - Web application framework 28 18 - [`HTMX`](https://htmx.org) - AJAX library 29 19 - [`@tijs/atproto-oauth`](https://jsr.io/@tijs/atproto-oauth) - AT Protocol OAuth library 20 + 21 + _Source hosted on [Tangled](https://tangled.org/zeu.dev/atproto-oauth-deno), mirrored on [GitHub](https://github.com/zeucapua/atproto-oauth-deno-demo)_
-41
lexicons/vote/pedro/qa/answer.json
··· 1 - { 2 - "lexicon": 1, 3 - "$type": "com.atproto.lexicon.schema", 4 - "id": "vote.pedro.qa.answer", 5 - "defs": { 6 - "main": { 7 - "description": "A user generated answer to a referenced question", 8 - "key": "tid", 9 - "type": "record", 10 - "record": { 11 - "type": "object", 12 - "required": [ 13 - "description", 14 - "question", 15 - "createdAt" 16 - ], 17 - "properties": { 18 - "description": { 19 - "type": "string" 20 - }, 21 - "facets": { 22 - "type": "array", 23 - "items": { 24 - "type": "ref", 25 - "ref": "app.bsky.richtext.facet" 26 - }, 27 - "description": "Annotations of text (mentions, URLs, etc.) for the description" 28 - }, 29 - "question": { 30 - "type": "ref", 31 - "ref": "com.atproto.repo.strongRef" 32 - }, 33 - "createdAt": { 34 - "type": "string", 35 - "format": "datetime" 36 - } 37 - } 38 - } 39 - } 40 - } 41 - }
-54
lexicons/vote/pedro/qa/question.json
··· 1 - { 2 - "lexicon": 1, 3 - "$type": "com.atproto.lexicon.schema", 4 - "id": "vote.pedro.qa.question", 5 - "defs": { 6 - "main": { 7 - "description": "A user generated question that others can answer to", 8 - "key": "tid", 9 - "type": "record", 10 - "record": { 11 - "type": "object", 12 - "required": [ 13 - "title", 14 - "createdAt" 15 - ], 16 - "properties": { 17 - "title": { 18 - "type": "string", 19 - "minLength": 1, 20 - "maxLength": 150 21 - }, 22 - "description": { 23 - "type": "string" 24 - }, 25 - "facets": { 26 - "type": "array", 27 - "items": { 28 - "type": "ref", 29 - "ref": "app.bsky.richtext.facet" 30 - }, 31 - "description": "Annotations of text (mentions, URLs, etc.) for the description" 32 - }, 33 - "tags": { 34 - "type": "array", 35 - "items": { 36 - "type": "string" 37 - } 38 - }, 39 - "createdAt": { 40 - "type": "string", 41 - "format": "datetime" 42 - }, 43 - "highlightedAnswers": { 44 - "type": "array", 45 - "items": { 46 - "type": "ref", 47 - "ref": "com.atproto.repo.strongRef" 48 - } 49 - } 50 - } 51 - } 52 - } 53 - } 54 - }
-29
lexicons/vote/pedro/qa/upvote.json
··· 1 - { 2 - "lexicon": 1, 3 - "$type": "com.atproto.lexicon.schema", 4 - "id": "vote.pedro.qa.upvote", 5 - "defs": { 6 - "main": { 7 - "description": "An upvote to a question or answer", 8 - "key": "tid", 9 - "type": "record", 10 - "record": { 11 - "type": "object", 12 - "required": [ 13 - "reference", 14 - "createdAt" 15 - ], 16 - "properties": { 17 - "reference": { 18 - "type": "ref", 19 - "ref": "com.atproto.repo.strongRef" 20 - }, 21 - "createdAt": { 22 - "type": "string", 23 - "format": "datetime" 24 - } 25 - } 26 - } 27 - } 28 - } 29 - }
+44 -4
main.tsx
··· 6 6 const app = new Hono(); 7 7 8 8 export const oauth = createATProtoOAuth({ 9 - baseUrl: Deno.env.get("BASE_URL")!, 10 - appName: "Pedro", 9 + baseUrl: "https://atproto-oauth-deno-demo.zeu.deno.net", // or for local dev: "http://127.0.0.1:8000/", 10 + appName: "AT Protocol OAuth Example App", 11 11 cookieSecret: Deno.env.get("COOKIE_SECRET")!, 12 12 storage: new MemoryStorage(), 13 13 sessionTtl: 60 * 60 * 24 * 14, // 14 days ··· 32 32 app.get("/", (c) => { 33 33 return c.html( 34 34 <SiteLayout context={c}> 35 - <h1>Pedro</h1> 36 - <p>Ask questions, share opinions, vote together</p> 35 + <h1>AT Protocol OAuth Template</h1> 36 + <h3>for Deno, Hono, and HTMX</h3> 37 + 38 + <hr /> 39 + 40 + <h2>Getting Started</h2> 41 + <ol> 42 + <li> 43 + <div style={{ display: "flex", "flex-direction": "column", gap: "0.25em" }}> 44 + <p>Set up <code>.env</code> file with a <code>COOKIE_SECRET</code> variable</p> 45 + <code style={{ background: "lightgray", padding: "1em", width: "fit-content" }}> 46 + COOKIE_SECRET=[run `openssl rand -base64 64` in the terminal] 47 + </code> 48 + </div> 49 + </li> 50 + 51 + <li> 52 + <div style={{ display: "flex", "flex-direction": "column", gap: "0.25em" }}> 53 + <p>Run the web application</p> 54 + <code style={{ background: "lightgray", padding: "1em", width: "fit-content" }}> 55 + deno task start 56 + </code> 57 + </div> 58 + </li> 59 + </ol> 60 + 61 + <hr /> 62 + 63 + <h2>Packages</h2> 64 + <ul> 65 + <li><a href="https://deno.com">Deno</a> - Runtime and package manager</li> 66 + <li><a href="https://hono.dev">Hono</a> - Web application framework</li> 67 + <li><a href="https://htmx.org">HTMX</a> - AJAX library</li> 68 + <li> 69 + <a href="https://jsr.io/@tijs/atproto-oauth">@tijs/atproto-oauth</a> - AT Protocol OAuth library 70 + </li> 71 + </ul> 72 + 73 + <p style={{ "font-style": "italic" }}> 74 + Source hosted on <a href="https://tangled.org/zeu.dev/atproto-oauth-deno">Tangled</a> 75 + , mirrored on <a href="https://github.com/zeucapua/atproto-oauth-deno-demo">GitHub</a> 76 + </p> 37 77 </SiteLayout> 38 78 ) 39 79 });
-17
utils.ts
··· 1 - import { SessionInterface } from "@tijs/atproto-oauth"; 2 - 3 - type Record<T> = { 4 - uri: string; 5 - cid: string; 6 - value: T 7 - } 8 - 9 - export async function listRecords<T>(session: SessionInterface, nsid: string) { 10 - const response = await session.makeRequest( 11 - "GET", 12 - `${session.pdsUrl}/xrpc/com.atproto.repo.listRecords?repo=${session.did}&collection=${encodeURIComponent(nsid)}` 13 - ); 14 - 15 - const { records } = await response.json(); 16 - return records as Record<T>[]; 17 - }