Testing implementation for private data in ATProto with ATPKeyserver and ATCute tools

we can actually reduce even more because the atcute package is this great

Changed files
+32 -149
packages
client
lexicon
types
app
wafrn
server
src
lib
xrpc
types
app
wafrn
+13
bun.lock
··· 22 22 "@react-router/fs-routes": "^7.9.4", 23 23 "@react-router/node": "^7.9.2", 24 24 "@react-router/serve": "^7.9.2", 25 + "@watproto/lexicon": "workspace:*", 25 26 "clsx": "^2.1.1", 26 27 "daisyui": "^5.3.10", 27 28 "isbot": "^5.1.31", ··· 50 51 "vite-tsconfig-paths": "^5.1.4", 51 52 }, 52 53 }, 54 + "packages/lexicon": { 55 + "name": "@watproto/lexicon", 56 + "version": "0.0.1", 57 + "dependencies": { 58 + "@atcute/atproto": "^3.1.8", 59 + "@atcute/bluesky": "^3.2.9", 60 + "@atcute/lexicons": "^1.2.2", 61 + }, 62 + }, 53 63 "packages/server": { 54 64 "name": "@watproto/server", 55 65 "version": "0.0.1", ··· 57 67 "@atcute/xrpc-server": "^0.1.3", 58 68 "@elysiajs/cors": "1.4.0", 59 69 "@elysiajs/openapi": "1.4.11", 70 + "@watproto/lexicon": "workspace:*", 60 71 "elysia": "1.4.13", 61 72 "kysely": "^0.28.8", 62 73 "kysely-bun-worker": "^1.2.1", ··· 454 465 "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="], 455 466 456 467 "@watproto/client": ["@watproto/client@workspace:packages/client"], 468 + 469 + "@watproto/lexicon": ["@watproto/lexicon@workspace:packages/lexicon"], 457 470 458 471 "@watproto/server": ["@watproto/server@workspace:packages/server"], 459 472
+1 -6
lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli' 2 2 3 - const LEX_ENV = process.env.LEX_ENV 4 - 5 3 export default defineLexiconConfig({ 6 4 files: ['lexicons/**/*.json'], 7 - outdir: 8 - LEX_ENV === 'server' 9 - ? 'packages/server/src/xrpc/' 10 - : 'packages/client/app/xrpc/', 5 + outdir: 'packages/lexicon', 11 6 imports: ['@atcute/atproto', '@atcute/bluesky'] 12 7 })
+1 -3
package.json
··· 14 14 "typecheck": "bun run --workspaces typecheck", 15 15 "typecheck:server": "bun run --filter @watproto/server typecheck", 16 16 "typecheck:client": "bun run --filter @watproto/client typecheck", 17 - "lex": "bun run lex:client && bun run lex:server", 18 - "lex:client": "LEX_ENV=client bunx --bun lex-cli generate -c lex.config.js", 19 - "lex:server": "LEX_ENV=server bunx --bun lex-cli generate -c lex.config.js" 17 + "lex": "bunx --bun lex-cli generate -c lex.config.js" 20 18 }, 21 19 "devDependencies": { 22 20 "@atcute/atproto": "^3.1.8",
+1 -1
packages/client/app/lib/user.ts
··· 1 1 import { idResolver } from './idResolver.server' 2 2 import { StatusError } from './https' 3 - import { getSessionAgent, type XRPCLient } from '@www/lib/xprcClient' 3 + import { getSessionAgent, type XRPCLient } from '@www/lib/xrpcClient' 4 4 import type { Did } from '@atcute/lexicons' 5 5 6 6 export async function getCurrentUser(request: Request) {
+1
packages/client/app/lib/xprcClient.ts packages/client/app/lib/xrpcClient.ts
··· 4 4 5 5 // magic import: this loads bluesky calls into the current atcute client 6 6 import type {} from '@atcute/bluesky' 7 + import type {} from '@watproto/lexicon' 7 8 8 9 export type XRPCLient = Awaited<ReturnType<typeof getSessionAgent>>['client'] 9 10
packages/client/app/xrpc/index.ts packages/lexicon/index.ts
packages/client/app/xrpc/types/app/wafrn/content/createPost.ts packages/lexicon/types/app/wafrn/content/createPost.ts
packages/client/app/xrpc/types/app/wafrn/content/post.ts packages/lexicon/types/app/wafrn/content/post.ts
+1
packages/client/package.json
··· 10 10 "typecheck": "bunx --bun react-router typegen && tsc" 11 11 }, 12 12 "dependencies": { 13 + "@watproto/lexicon": "workspace:*", 13 14 "@atcute/client": "^4.0.5", 14 15 "@atproto/identity": "^0.4.9", 15 16 "@atproto/oauth-client-node": "^0.3.10",
+12
packages/lexicon/package.json
··· 1 + { 2 + "name": "@watproto/lexicon", 3 + "version": "0.0.1", 4 + "license": "MIT", 5 + "main": "./index.ts", 6 + "types": "./index.ts", 7 + "dependencies": { 8 + "@atcute/atproto": "^3.1.8", 9 + "@atcute/bluesky": "^3.2.9", 10 + "@atcute/lexicons": "^1.2.2" 11 + } 12 + }
+1
packages/server/package.json
··· 12 12 "typecheck": "bunx --bun tsc --noEmit" 13 13 }, 14 14 "dependencies": { 15 + "@watproto/lexicon": "workspace:*", 15 16 "@atcute/xrpc-server": "^0.1.3", 16 17 "@elysiajs/cors": "1.4.0", 17 18 "@elysiajs/openapi": "1.4.11",
+1 -1
packages/server/src/lib/xrpcServer.ts
··· 1 1 import { XRPCRouter, json } from '@atcute/xrpc-server' 2 2 import { cors } from '@atcute/xrpc-server/middlewares/cors' 3 - import { AppWafrnContentCreatePost } from '../xrpc/index.js' 3 + import { AppWafrnContentCreatePost } from '@watproto/lexicon' 4 4 5 5 const xrpcServer = new XRPCRouter({ middlewares: [cors()] }) 6 6
-2
packages/server/src/xrpc/index.ts
··· 1 - export * as AppWafrnContentCreatePost from "./types/app/wafrn/content/createPost.js"; 2 - export * as AppWafrnContentPost from "./types/app/wafrn/content/post.js";
-57
packages/server/src/xrpc/types/app/wafrn/content/createPost.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as AppWafrnContentPost from "./post.js"; 5 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 6 - 7 - const _mainSchema = /*#__PURE__*/ v.procedure("app.wafrn.content.createPost", { 8 - params: null, 9 - input: { 10 - type: "lex", 11 - schema: /*#__PURE__*/ v.object({ 12 - contentMarkdown: /*#__PURE__*/ v.string(), 13 - contentWarning: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 14 - get labels() { 15 - return /*#__PURE__*/ v.optional( 16 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 17 - ); 18 - }, 19 - tags: /*#__PURE__*/ v.optional( 20 - /*#__PURE__*/ v.array(/*#__PURE__*/ v.string()), 21 - ), 22 - /** 23 - * @default "public" 24 - */ 25 - visibility: /*#__PURE__*/ v.optional( 26 - /*#__PURE__*/ v.string< 27 - "followers" | "mentioned" | "public" | (string & {}) 28 - >(), 29 - "public", 30 - ), 31 - }), 32 - }, 33 - output: { 34 - type: "lex", 35 - schema: /*#__PURE__*/ v.object({ 36 - get post() { 37 - return AppWafrnContentPost.mainSchema; 38 - }, 39 - }), 40 - }, 41 - }); 42 - 43 - type main$schematype = typeof _mainSchema; 44 - 45 - export interface mainSchema extends main$schematype {} 46 - 47 - export const mainSchema = _mainSchema as mainSchema; 48 - 49 - export interface $params {} 50 - export interface $input extends v.InferXRPCBodyInput<mainSchema["input"]> {} 51 - export interface $output extends v.InferXRPCBodyInput<mainSchema["output"]> {} 52 - 53 - declare module "@atcute/lexicons/ambient" { 54 - interface XRPCProcedures { 55 - "app.wafrn.content.createPost": mainSchema; 56 - } 57 - }
-79
packages/server/src/xrpc/types/app/wafrn/content/post.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - import * as ComAtprotoLabelDefs from "@atcute/atproto/types/label/defs"; 5 - 6 - const _mainSchema = /*#__PURE__*/ v.record( 7 - /*#__PURE__*/ v.tidString(), 8 - /*#__PURE__*/ v.object({ 9 - $type: /*#__PURE__*/ v.literal("app.wafrn.content.post"), 10 - get content() { 11 - return /*#__PURE__*/ v.variant([ 12 - postContentSchema, 13 - postEncryptedContentSchema, 14 - ]); 15 - }, 16 - /** 17 - * @default "public" 18 - */ 19 - visibility: /*#__PURE__*/ v.optional( 20 - /*#__PURE__*/ v.string< 21 - "followers" | "mentioned" | "public" | (string & {}) 22 - >(), 23 - "public", 24 - ), 25 - }), 26 - ); 27 - const _postContentSchema = /*#__PURE__*/ v.object({ 28 - $type: /*#__PURE__*/ v.optional( 29 - /*#__PURE__*/ v.literal("app.wafrn.content.post#postContent"), 30 - ), 31 - contentHTML: /*#__PURE__*/ v.string(), 32 - contentMarkdown: /*#__PURE__*/ v.string(), 33 - contentWarning: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 34 - createdAt: /*#__PURE__*/ v.datetimeString(), 35 - get labels() { 36 - return /*#__PURE__*/ v.optional( 37 - /*#__PURE__*/ v.variant([ComAtprotoLabelDefs.selfLabelsSchema]), 38 - ); 39 - }, 40 - tags: /*#__PURE__*/ v.optional( 41 - /*#__PURE__*/ v.array(/*#__PURE__*/ v.string()), 42 - ), 43 - updatedAt: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), 44 - }); 45 - const _postEncryptedContentSchema = /*#__PURE__*/ v.object({ 46 - $type: /*#__PURE__*/ v.optional( 47 - /*#__PURE__*/ v.literal("app.wafrn.content.post#postEncryptedContent"), 48 - ), 49 - encryptedContent: /*#__PURE__*/ v.string(), 50 - /** 51 - * @minimum 0 52 - */ 53 - keyVersion: /*#__PURE__*/ v.integer(), 54 - }); 55 - 56 - type main$schematype = typeof _mainSchema; 57 - type postContent$schematype = typeof _postContentSchema; 58 - type postEncryptedContent$schematype = typeof _postEncryptedContentSchema; 59 - 60 - export interface mainSchema extends main$schematype {} 61 - export interface postContentSchema extends postContent$schematype {} 62 - export interface postEncryptedContentSchema 63 - extends postEncryptedContent$schematype {} 64 - 65 - export const mainSchema = _mainSchema as mainSchema; 66 - export const postContentSchema = _postContentSchema as postContentSchema; 67 - export const postEncryptedContentSchema = 68 - _postEncryptedContentSchema as postEncryptedContentSchema; 69 - 70 - export interface Main extends v.InferInput<typeof mainSchema> {} 71 - export interface PostContent extends v.InferInput<typeof postContentSchema> {} 72 - export interface PostEncryptedContent 73 - extends v.InferInput<typeof postEncryptedContentSchema> {} 74 - 75 - declare module "@atcute/lexicons/ambient" { 76 - interface Records { 77 - "app.wafrn.content.post": mainSchema; 78 - } 79 - }