├── .DS_Store ├── scripts ├── bluej.png ├── blue-j-icon.png ├── bluej.code-workspace ├── createIndexes.ts ├── get-did.ts └── import-authors.ts ├── app ├── public │ ├── blue-jay.webp │ └── index.html └── package.json ├── visualization ├── live │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── src │ │ ├── assets │ │ │ └── images │ │ │ │ ├── bluesky.png │ │ │ │ └── memgraph.png │ │ ├── index.css │ │ └── index.js │ ├── .env.example │ ├── .gitignore │ ├── package.json │ └── README.md ├── query_module │ ├── CMakeLists.txt │ └── README.md └── backend_service │ ├── .gitignore │ ├── package.json │ ├── .env.example │ └── src │ ├── routes │ ├── create.js │ ├── delete.js │ ├── merge.js │ ├── detach.js │ └── enrich.js │ └── util │ └── enrich_util.js ├── query_module ├── CMakeLists.txt ├── README.md └── bluej.cpp ├── src ├── db │ ├── schema.ts │ ├── index.ts │ └── migrations.ts ├── lexicon │ ├── util.ts │ └── types │ │ ├── app │ │ └── bsky │ │ │ ├── graph │ │ │ ├── block.ts │ │ │ ├── follow.ts │ │ │ ├── listblock.ts │ │ │ ├── listitem.ts │ │ │ ├── muteActor.ts │ │ │ ├── unmuteActor.ts │ │ │ ├── muteActorList.ts │ │ │ ├── unmuteActorList.ts │ │ │ ├── list.ts │ │ │ ├── getSuggestedFollowsByActor.ts │ │ │ ├── getListMutes.ts │ │ │ ├── getListBlocks.ts │ │ │ ├── getBlocks.ts │ │ │ ├── getMutes.ts │ │ │ ├── getLists.ts │ │ │ ├── getList.ts │ │ │ ├── getFollowers.ts │ │ │ └── getFollows.ts │ │ │ ├── feed │ │ │ ├── like.ts │ │ │ ├── repost.ts │ │ │ ├── generator.ts │ │ │ ├── getPosts.ts │ │ │ ├── getFeedGenerators.ts │ │ │ ├── getFeedGenerator.ts │ │ │ ├── getSuggestedFeeds.ts │ │ │ ├── getActorFeeds.ts │ │ │ ├── getTimeline.ts │ │ │ ├── getFeed.ts │ │ │ ├── getListFeed.ts │ │ │ ├── getFeedSkeleton.ts │ │ │ ├── getActorLikes.ts │ │ │ ├── getRepostedBy.ts │ │ │ ├── getPostThread.ts │ │ │ ├── getAuthorFeed.ts │ │ │ ├── searchPosts.ts │ │ │ ├── getLikes.ts │ │ │ ├── describeFeedGenerator.ts │ │ │ └── threadgate.ts │ │ │ ├── actor │ │ │ ├── profile.ts │ │ │ ├── putPreferences.ts │ │ │ ├── getProfile.ts │ │ │ ├── getPreferences.ts │ │ │ ├── getProfiles.ts │ │ │ ├── getSuggestions.ts │ │ │ ├── searchActorsTypeahead.ts │ │ │ └── searchActors.ts │ │ │ ├── notification │ │ │ ├── updateSeen.ts │ │ │ ├── registerPush.ts │ │ │ ├── getUnreadCount.ts │ │ │ └── listNotifications.ts │ │ │ ├── unspecced │ │ │ ├── defs.ts │ │ │ ├── getPopular.ts │ │ │ ├── getPopularFeedGenerators.ts │ │ │ ├── getTimelineSkeleton.ts │ │ │ ├── searchPostsSkeleton.ts │ │ │ └── searchActorsSkeleton.ts │ │ │ └── embed │ │ │ ├── recordWithMedia.ts │ │ │ └── external.ts │ │ └── com │ │ └── atproto │ │ ├── repo │ │ ├── strongRef.ts │ │ ├── uploadBlob.ts │ │ ├── describeRepo.ts │ │ ├── deleteRecord.ts │ │ ├── getRecord.ts │ │ ├── createRecord.ts │ │ ├── putRecord.ts │ │ └── listRecords.ts │ │ ├── server │ │ ├── deleteSession.ts │ │ ├── requestAccountDelete.ts │ │ ├── revokeAppPassword.ts │ │ ├── requestPasswordReset.ts │ │ ├── resetPassword.ts │ │ ├── deleteAccount.ts │ │ ├── getSession.ts │ │ ├── refreshSession.ts │ │ ├── defs.ts │ │ ├── createInviteCode.ts │ │ ├── getAccountInviteCodes.ts │ │ ├── createSession.ts │ │ ├── createAccount.ts │ │ ├── listAppPasswords.ts │ │ ├── describeServer.ts │ │ ├── createAppPassword.ts │ │ └── createInviteCodes.ts │ │ ├── identity │ │ ├── updateHandle.ts │ │ └── resolveHandle.ts │ │ ├── admin │ │ ├── updateAccountHandle.ts │ │ ├── disableInviteCodes.ts │ │ ├── updateAccountEmail.ts │ │ ├── disableAccountInvites.ts │ │ ├── enableAccountInvites.ts │ │ ├── getModerationAction.ts │ │ ├── getModerationReport.ts │ │ ├── getRepo.ts │ │ ├── getRecord.ts │ │ ├── sendEmail.ts │ │ ├── getModerationActions.ts │ │ ├── reverseModerationAction.ts │ │ ├── resolveModerationReports.ts │ │ ├── getInviteCodes.ts │ │ ├── searchRepos.ts │ │ ├── getModerationReports.ts │ │ └── takeModerationAction.ts │ │ ├── sync │ │ ├── notifyOfUpdate.ts │ │ ├── requestCrawl.ts │ │ ├── getCheckout.ts │ │ ├── getBlocks.ts │ │ ├── getBlob.ts │ │ ├── getHead.ts │ │ ├── getRepo.ts │ │ ├── getLatestCommit.ts │ │ ├── getRecord.ts │ │ ├── listBlobs.ts │ │ └── listRepos.ts │ │ ├── moderation │ │ ├── defs.ts │ │ └── createReport.ts │ │ └── label │ │ ├── queryLabels.ts │ │ ├── subscribeLabels.ts │ │ └── defs.ts ├── config.ts ├── algos │ ├── index.ts │ └── weighted-round-robin.ts ├── auth.ts ├── methods │ ├── describe-generator.ts │ └── feed-generation.ts ├── well-known.ts ├── index.ts └── server.ts ├── tsconfig.json ├── .env.example └── package.json /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/.DS_Store -------------------------------------------------------------------------------- /scripts/bluej.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/scripts/bluej.png -------------------------------------------------------------------------------- /app/public/blue-jay.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/app/public/blue-jay.webp -------------------------------------------------------------------------------- /scripts/blue-j-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/scripts/blue-j-icon.png -------------------------------------------------------------------------------- /scripts/bluej.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /visualization/live/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/visualization/live/public/favicon.ico -------------------------------------------------------------------------------- /visualization/live/src/assets/images/bluesky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/visualization/live/src/assets/images/bluesky.png -------------------------------------------------------------------------------- /visualization/live/src/assets/images/memgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memgraph/bluej/HEAD/visualization/live/src/assets/images/memgraph.png -------------------------------------------------------------------------------- /visualization/live/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: 'Roboto', sans-serif; 4 | width: 100%; 5 | height: 100%; 6 | } -------------------------------------------------------------------------------- /query_module/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add all module files related to graph util module 2 | set(bluej_src bluej.cpp) 3 | add_query_module(bluej 1 "${bluej_src}") 4 | 5 | -------------------------------------------------------------------------------- /visualization/live/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './components/App'; 4 | import "./index.css" 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | 8 | root.render( 9 | 10 | ); -------------------------------------------------------------------------------- /visualization/live/.env.example: -------------------------------------------------------------------------------- 1 | # Set this to the domain of the backend app (for local testing use http://localhost:3002) 2 | REACT_APP_BACKEND_DOMAIN=https://bluej.memgraph.com 3 | 4 | # Set this to the path of the backend app (for local testing use /socket.io) 5 | REACT_APP_BACKEND_PATH=/viz/socket -------------------------------------------------------------------------------- /scripts/createIndexes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | if (createIndexes) { 3 | async () => { 4 | await session.run("CREATE INDEX ON :Person(did)", {}) 5 | await session.run("CREATE INDEX ON :Post(uri)", {}) 6 | await session.run("CREATE INDEX ON :Person", {}) 7 | await session.run("CREATE INDEX ON :Post", {}) 8 | } 9 | } 10 | */ -------------------------------------------------------------------------------- /src/db/schema.ts: -------------------------------------------------------------------------------- 1 | export type DatabaseSchema = { 2 | post: Post 3 | sub_state: SubState 4 | } 5 | 6 | export type Post = { 7 | uri: string 8 | cid: string 9 | replyParent: string | null 10 | replyRoot: string | null 11 | indexedAt: string 12 | } 13 | 14 | export type SubState = { 15 | service: string 16 | cursor: number 17 | } 18 | -------------------------------------------------------------------------------- /src/lexicon/util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | export function isObj(v: unknown): v is Record { 5 | return typeof v === 'object' && v !== null 6 | } 7 | 8 | export function hasProp( 9 | data: object, 10 | prop: K, 11 | ): data is Record { 12 | return prop in data 13 | } 14 | -------------------------------------------------------------------------------- /visualization/query_module/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add all module files related to graph util module 2 | set(visualization_src visualization.cpp) 3 | add_query_module(visualization 1 "${visualization_src}") 4 | 5 | # Link external libraries 6 | target_link_libraries(visualization PRIVATE ${CURL_LIBRARIES}) 7 | target_include_directories(visualization PRIVATE ${CURL_INCLUDE_DIRS}) -------------------------------------------------------------------------------- /visualization/live/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import { Database } from './db' 2 | import { DidResolver } from '@atproto/identity' 3 | 4 | export type AppContext = { 5 | db: Database 6 | didResolver: DidResolver 7 | cfg: Config 8 | } 9 | 10 | export type Config = { 11 | port: number 12 | listenhost: string 13 | hostname: string 14 | sqliteLocation: string 15 | subscriptionEndpoint: string 16 | serviceDid: string 17 | publisherDid: string 18 | subscriptionReconnectDelay: number 19 | } 20 | -------------------------------------------------------------------------------- /visualization/backend_service/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # config file 26 | .env -------------------------------------------------------------------------------- /visualization/live/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Live visualization 7 | 11 | 12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bluej-app", 3 | "version": "1.0.0", 4 | "description": "A simple servers for running Memgraph queries.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.20.2", 13 | "express": "^4.18.2", 14 | "helmet": "^7.0.0", 15 | "neo4j-driver": "^4.4.6", 16 | "pm2": "^5.3.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "lib": [ 5 | "ESNext", 6 | "DOM" 7 | ], 8 | "outDir": "dist", 9 | "module": "CommonJS", 10 | "target": "ES6", 11 | "esModuleInterop": true, 12 | "moduleResolution": "node", 13 | "alwaysStrict": true, 14 | "allowUnreachableCode": false, 15 | "strictNullChecks": true, 16 | "skipLibCheck": true 17 | }, 18 | "include": ["./src/**/*.ts"], 19 | "exclude": [ 20 | "node_modules" 21 | ] 22 | } -------------------------------------------------------------------------------- /visualization/backend_service/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend_service", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node ./src/index.js", 9 | "start-dev": "nodemon ./src/index.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@atproto/api": "^0.6.3", 15 | "dotenv": "^16.3.1", 16 | "express": "^4.18.2", 17 | "neo4j-driver": "^5.11.0", 18 | "socket.io": "^4.7.1" 19 | }, 20 | "devDependencies": { 21 | "nodemon": "^3.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/algos/index.ts: -------------------------------------------------------------------------------- 1 | import { AppContext } from '../config' 2 | import { 3 | QueryParams, 4 | OutputSchema as AlgoOutput, 5 | } from '../lexicon/types/app/bsky/feed/getFeedSkeleton' 6 | import * as FriendsAndCommunity from './friends-and-community' 7 | import * as HomePlus from './home-plus' 8 | import * as Authors from './authors' 9 | 10 | type AlgoHandler = (ctx: AppContext, params: QueryParams, requesterDid: string) => Promise 11 | 12 | const algos: Record = { 13 | [FriendsAndCommunity.shortname]: FriendsAndCommunity.handler, 14 | [HomePlus.shortname]: HomePlus.handler, 15 | [Authors.shortname]: Authors.handler, 16 | } 17 | 18 | export default algos 19 | -------------------------------------------------------------------------------- /src/auth.ts: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import { verifyJwt, AuthRequiredError } from '@atproto/xrpc-server' 3 | import { DidResolver } from '@atproto/identity' 4 | 5 | export const validateAuth = async ( 6 | req: express.Request, 7 | serviceDid: string, 8 | didResolver: DidResolver, 9 | ): Promise => { 10 | const { authorization = '' } = req.headers 11 | if (!authorization.startsWith('Bearer ')) { 12 | return 'did:plc:ewgejell4547pukut5255ibm' 13 | // throw new AuthRequiredError() 14 | } 15 | const jwt = authorization.replace('Bearer ', '').trim() 16 | return verifyJwt(jwt, serviceDid, async (did: string) => { 17 | return didResolver.resolveAtprotoKey(did) 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /visualization/backend_service/.env.example: -------------------------------------------------------------------------------- 1 | # Set this to the port where you want to run the backend server 2 | PORT=3002 3 | 4 | # Set this to the URL of the client-side app (for local testing use http://localhost:3001) 5 | CLIENT=https://bluej.memgraph.com/viz 6 | 7 | # Set this to the handle and password you want to run with 8 | HANDLE=example.bsky.social 9 | PASSWORD=password-goes-here 10 | 11 | # Set this to the number of nodes you want to send to the client-side app on interest subscribe 12 | NODE_COUNT=50 13 | 14 | # Set this to true if you want the backend service to run the enrichment process 15 | ENRICHMENT=true 16 | 17 | # Set this to true if you want verbose descriptions of activity 18 | VERBOSE=false -------------------------------------------------------------------------------- /src/db/index.ts: -------------------------------------------------------------------------------- 1 | import SqliteDb from 'better-sqlite3' 2 | import { Kysely, Migrator, SqliteDialect } from 'kysely' 3 | import { DatabaseSchema } from './schema' 4 | import { migrationProvider } from './migrations' 5 | 6 | export const createDb = (location: string): Database => { 7 | return new Kysely({ 8 | dialect: new SqliteDialect({ 9 | database: new SqliteDb(location), 10 | }), 11 | }) 12 | } 13 | 14 | export const migrateToLatest = async (db: Database) => { 15 | const migrator = new Migrator({ db, provider: migrationProvider }) 16 | const { error } = await migrator.migrateToLatest() 17 | if (error) throw error 18 | } 19 | 20 | export type Database = Kysely 21 | -------------------------------------------------------------------------------- /src/methods/describe-generator.ts: -------------------------------------------------------------------------------- 1 | import { Server } from '../lexicon' 2 | import { AppContext } from '../config' 3 | import algos from '../algos' 4 | import { AtUri } from '@atproto/syntax' 5 | 6 | export default function (server: Server, ctx: AppContext) { 7 | server.app.bsky.feed.describeFeedGenerator(async () => { 8 | const feeds = Object.keys(algos).map((shortname) => ({ 9 | uri: AtUri.make( 10 | ctx.cfg.publisherDid, 11 | 'app.bsky.feed.generator', 12 | shortname, 13 | ).toString(), 14 | })) 15 | return { 16 | encoding: 'application/json', 17 | body: { 18 | did: ctx.cfg.serviceDid, 19 | feeds, 20 | }, 21 | } 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /visualization/backend_service/src/routes/create.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { sockets, clientInterests } = require('../index'); 3 | 4 | const router = express.Router(); 5 | 6 | router.post('/', (req, res) => { 7 | const author = req.body?.did || req.body?.author; 8 | 9 | Object.entries(sockets).forEach(([socketID, socket]) => { 10 | const interests = clientInterests[socketID]; 11 | 12 | if (!interests || interests.includes(author)) { 13 | socket.emit('create', req.body); 14 | } 15 | }); 16 | 17 | if (process.env.VERBOSE === 'true') { 18 | process.stdout.write('C'); 19 | } 20 | 21 | res.sendStatus(200); 22 | }) 23 | 24 | module.exports = router; -------------------------------------------------------------------------------- /src/well-known.ts: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import { AppContext } from './config' 3 | 4 | const makeRouter = (ctx: AppContext) => { 5 | const router = express.Router() 6 | 7 | router.get('/.well-known/did.json', (_req, res) => { 8 | if (!ctx.cfg.serviceDid.endsWith(ctx.cfg.hostname)) { 9 | return res.sendStatus(404) 10 | } 11 | res.json({ 12 | '@context': ['https://www.w3.org/ns/did/v1'], 13 | id: ctx.cfg.serviceDid, 14 | service: [ 15 | { 16 | id: '#bsky_fg', 17 | type: 'BskyFeedGenerator', 18 | serviceEndpoint: `https://${ctx.cfg.hostname}`, 19 | }, 20 | ], 21 | }) 22 | }) 23 | 24 | return router 25 | } 26 | export default makeRouter 27 | -------------------------------------------------------------------------------- /visualization/backend_service/src/routes/delete.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { sockets, clientInterests } = require('../index'); 3 | 4 | const router = express.Router(); 5 | 6 | router.post('/', (req, res) => { 7 | const author = req.body?.did || req.body?.author; 8 | 9 | Object.entries(sockets).forEach(([socketID, socket]) => { 10 | const interests = clientInterests[socketID]; 11 | 12 | if (!interests || interests.includes(author) || !author) { 13 | socket.emit('delete', req.body); 14 | } 15 | }); 16 | 17 | if (process.env.VERBOSE === 'true') { 18 | process.stdout.write('D'); 19 | } 20 | 21 | res.sendStatus(200); 22 | }) 23 | 24 | module.exports = router; -------------------------------------------------------------------------------- /visualization/backend_service/src/routes/merge.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { sockets, clientInterests } = require('../index'); 3 | 4 | const router = express.Router(); 5 | 6 | router.post('/', (req, res) => { 7 | const author = req.body.source.startsWith('did') ? req.body.source : req.body?.author; 8 | 9 | Object.entries(sockets).forEach(([socketID, socket]) => { 10 | const interests = clientInterests[socketID]; 11 | 12 | if (!interests || interests.includes(author)) { 13 | socket.emit('merge', req.body); 14 | } 15 | }); 16 | 17 | if (process.env.VERBOSE === 'true') { 18 | process.stdout.write('M'); 19 | } 20 | 21 | res.sendStatus(200); 22 | }) 23 | 24 | module.exports = router; -------------------------------------------------------------------------------- /visualization/backend_service/src/routes/detach.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { sockets, clientInterests } = require('../index'); 3 | 4 | const router = express.Router(); 5 | 6 | router.post('/', (req, res) => { 7 | const author = req.body.source.startsWith('did') ? req.body.source : req.body?.author; 8 | 9 | Object.entries(sockets).forEach(([socketID, socket]) => { 10 | const interests = clientInterests[socketID]; 11 | 12 | if (!interests || interests.includes(author) || !author) { 13 | socket.emit('detach', req.body); 14 | } 15 | }); 16 | 17 | if (process.env.VERBOSE === 'true') { 18 | process.stdout.write('T'); 19 | } 20 | 21 | res.sendStatus(200); 22 | }) 23 | 24 | module.exports = router; -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/block.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Record { 10 | subject: string 11 | createdAt: string 12 | [k: string]: unknown 13 | } 14 | 15 | export function isRecord(v: unknown): v is Record { 16 | return ( 17 | isObj(v) && 18 | hasProp(v, '$type') && 19 | (v.$type === 'app.bsky.graph.block#main' || 20 | v.$type === 'app.bsky.graph.block') 21 | ) 22 | } 23 | 24 | export function validateRecord(v: unknown): ValidationResult { 25 | return lexicons.validate('app.bsky.graph.block#main', v) 26 | } 27 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/follow.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Record { 10 | subject: string 11 | createdAt: string 12 | [k: string]: unknown 13 | } 14 | 15 | export function isRecord(v: unknown): v is Record { 16 | return ( 17 | isObj(v) && 18 | hasProp(v, '$type') && 19 | (v.$type === 'app.bsky.graph.follow#main' || 20 | v.$type === 'app.bsky.graph.follow') 21 | ) 22 | } 23 | 24 | export function validateRecord(v: unknown): ValidationResult { 25 | return lexicons.validate('app.bsky.graph.follow#main', v) 26 | } 27 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/strongRef.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Main { 10 | uri: string 11 | cid: string 12 | [k: string]: unknown 13 | } 14 | 15 | export function isMain(v: unknown): v is Main { 16 | return ( 17 | isObj(v) && 18 | hasProp(v, '$type') && 19 | (v.$type === 'com.atproto.repo.strongRef#main' || 20 | v.$type === 'com.atproto.repo.strongRef') 21 | ) 22 | } 23 | 24 | export function validateMain(v: unknown): ValidationResult { 25 | return lexicons.validate('com.atproto.repo.strongRef#main', v) 26 | } 27 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/listblock.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Record { 10 | subject: string 11 | createdAt: string 12 | [k: string]: unknown 13 | } 14 | 15 | export function isRecord(v: unknown): v is Record { 16 | return ( 17 | isObj(v) && 18 | hasProp(v, '$type') && 19 | (v.$type === 'app.bsky.graph.listblock#main' || 20 | v.$type === 'app.bsky.graph.listblock') 21 | ) 22 | } 23 | 24 | export function validateRecord(v: unknown): ValidationResult { 25 | return lexicons.validate('app.bsky.graph.listblock#main', v) 26 | } 27 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/listitem.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Record { 10 | subject: string 11 | list: string 12 | createdAt: string 13 | [k: string]: unknown 14 | } 15 | 16 | export function isRecord(v: unknown): v is Record { 17 | return ( 18 | isObj(v) && 19 | hasProp(v, '$type') && 20 | (v.$type === 'app.bsky.graph.listitem#main' || 21 | v.$type === 'app.bsky.graph.listitem') 22 | ) 23 | } 24 | 25 | export function validateRecord(v: unknown): ValidationResult { 26 | return lexicons.validate('app.bsky.graph.listitem#main', v) 27 | } 28 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/like.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef' 9 | 10 | export interface Record { 11 | subject: ComAtprotoRepoStrongRef.Main 12 | createdAt: string 13 | [k: string]: unknown 14 | } 15 | 16 | export function isRecord(v: unknown): v is Record { 17 | return ( 18 | isObj(v) && 19 | hasProp(v, '$type') && 20 | (v.$type === 'app.bsky.feed.like#main' || v.$type === 'app.bsky.feed.like') 21 | ) 22 | } 23 | 24 | export function validateRecord(v: unknown): ValidationResult { 25 | return lexicons.validate('app.bsky.feed.like#main', v) 26 | } 27 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/repost.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef' 9 | 10 | export interface Record { 11 | subject: ComAtprotoRepoStrongRef.Main 12 | createdAt: string 13 | [k: string]: unknown 14 | } 15 | 16 | export function isRecord(v: unknown): v is Record { 17 | return ( 18 | isObj(v) && 19 | hasProp(v, '$type') && 20 | (v.$type === 'app.bsky.feed.repost#main' || 21 | v.$type === 'app.bsky.feed.repost') 22 | ) 23 | } 24 | 25 | export function validateRecord(v: unknown): ValidationResult { 26 | return lexicons.validate('app.bsky.feed.repost#main', v) 27 | } 28 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Whichever port you want to run this on 2 | FEEDGEN_PORT=8000 3 | 4 | # Set to something like db.sqlite to store persistently 5 | FEEDGEN_SQLITE_LOCATION=":memory:" 6 | 7 | # Don't change unless you're working in a different environment than the primary Bluesky network 8 | FEEDGEN_SUBSCRIPTION_ENDPOINT="wss://bsky.social" 9 | 10 | # Set this to the hostname that you intend to run the service at 11 | FEEDGEN_HOSTNAME="example.com" 12 | FEEDGEN_HANDLE="example.bsky.social" 13 | FEEDGEN_PASSWORD="password-goes-here" 14 | 15 | # Set this to the DID of the account you'll use to publish the feed 16 | # You can find your accounts DID by going to 17 | # https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=${YOUR_HANDLE} 18 | FEEDGEN_PUBLISHER_DID="did:plc:2wqomm3tjqbgktbrfwgvrw34" 19 | 20 | # Delay between reconnect attempts to the firehose subscription endpoint (in milliseconds) 21 | FEEDGEN_SUBSCRIPTION_RECONNECT_DELAY=3000 -------------------------------------------------------------------------------- /scripts/get-did.ts: -------------------------------------------------------------------------------- 1 | import { BskyAgent, AtpSessionEvent, AtpSessionData } from '@atproto/api' 2 | import * as dotenv from 'dotenv' 3 | dotenv.config() 4 | const util = require('util') 5 | 6 | const agent = new BskyAgent({ 7 | service: 'https://bsky.social/', 8 | }) 9 | 10 | async function fetchProfile(handle: string) { 11 | try { 12 | let profile = await agent.getProfile({actor: handle}) 13 | console.log(util.inspect(profile, false, null, true)) 14 | } catch (err) { 15 | console.error('[fetchProfile]:', err) 16 | } 17 | } 18 | 19 | async function run(handle: string) { 20 | console.log(" Querying...", handle) 21 | await agent.login({ identifier: process.env.FEEDGEN_HANDLE, password: process.env.FEEDGEN_PASSWORD }) 22 | fetchProfile(handle) 23 | } 24 | 25 | let handle = process.argv[2]?.trim() 26 | if (handle === undefined) { 27 | console.log("Usage: ts-node get-did.ts ") 28 | process.exit(1) 29 | } 30 | 31 | run(handle) 32 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/deleteSession.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | export type HandlerInput = undefined 15 | 16 | export interface HandlerError { 17 | status: number 18 | message?: string 19 | } 20 | 21 | export type HandlerOutput = HandlerError | void 22 | export type HandlerReqCtx = { 23 | auth: HA 24 | params: QueryParams 25 | input: HandlerInput 26 | req: express.Request 27 | res: express.Response 28 | } 29 | export type Handler = ( 30 | ctx: HandlerReqCtx, 31 | ) => Promise | HandlerOutput 32 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/requestAccountDelete.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | export type HandlerInput = undefined 15 | 16 | export interface HandlerError { 17 | status: number 18 | message?: string 19 | } 20 | 21 | export type HandlerOutput = HandlerError | void 22 | export type HandlerReqCtx = { 23 | auth: HA 24 | params: QueryParams 25 | input: HandlerInput 26 | req: express.Request 27 | res: express.Response 28 | } 29 | export type Handler = ( 30 | ctx: HandlerReqCtx, 31 | ) => Promise | HandlerOutput 32 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/profile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs' 9 | 10 | export interface Record { 11 | displayName?: string 12 | description?: string 13 | avatar?: BlobRef 14 | banner?: BlobRef 15 | labels?: 16 | | ComAtprotoLabelDefs.SelfLabels 17 | | { $type: string; [k: string]: unknown } 18 | [k: string]: unknown 19 | } 20 | 21 | export function isRecord(v: unknown): v is Record { 22 | return ( 23 | isObj(v) && 24 | hasProp(v, '$type') && 25 | (v.$type === 'app.bsky.actor.profile#main' || 26 | v.$type === 'app.bsky.actor.profile') 27 | ) 28 | } 29 | 30 | export function validateRecord(v: unknown): ValidationResult { 31 | return lexicons.validate('app.bsky.actor.profile#main', v) 32 | } 33 | -------------------------------------------------------------------------------- /src/db/migrations.ts: -------------------------------------------------------------------------------- 1 | import { Kysely, Migration, MigrationProvider } from 'kysely' 2 | 3 | const migrations: Record = {} 4 | 5 | export const migrationProvider: MigrationProvider = { 6 | async getMigrations() { 7 | return migrations 8 | }, 9 | } 10 | 11 | migrations['001'] = { 12 | async up(db: Kysely) { 13 | await db.schema 14 | .createTable('post') 15 | .addColumn('uri', 'varchar', (col) => col.primaryKey()) 16 | .addColumn('cid', 'varchar', (col) => col.notNull()) 17 | .addColumn('replyParent', 'varchar') 18 | .addColumn('replyRoot', 'varchar') 19 | .addColumn('indexedAt', 'varchar', (col) => col.notNull()) 20 | .execute() 21 | await db.schema 22 | .createTable('sub_state') 23 | .addColumn('service', 'varchar', (col) => col.primaryKey()) 24 | .addColumn('cursor', 'integer', (col) => col.notNull()) 25 | .execute() 26 | }, 27 | async down(db: Kysely) { 28 | await db.schema.dropTable('post').execute() 29 | await db.schema.dropTable('sub_state').execute() 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/muteActor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | actor: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/unmuteActor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | actor: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/muteActorList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | list: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/unmuteActorList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | list: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/notification/updateSeen.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | seenAt: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/identity/updateHandle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | handle: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/revokeAppPassword.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | name: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/requestPasswordReset.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | email: string 15 | [k: string]: unknown 16 | } 17 | 18 | export interface HandlerInput { 19 | encoding: 'application/json' 20 | body: InputSchema 21 | } 22 | 23 | export interface HandlerError { 24 | status: number 25 | message?: string 26 | } 27 | 28 | export type HandlerOutput = HandlerError | void 29 | export type HandlerReqCtx = { 30 | auth: HA 31 | params: QueryParams 32 | input: HandlerInput 33 | req: express.Request 34 | res: express.Response 35 | } 36 | export type Handler = ( 37 | ctx: HandlerReqCtx, 38 | ) => Promise | HandlerOutput 39 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/updateAccountHandle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | did: string 15 | handle: string 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | } 28 | 29 | export type HandlerOutput = HandlerError | void 30 | export type HandlerReqCtx = { 31 | auth: HA 32 | params: QueryParams 33 | input: HandlerInput 34 | req: express.Request 35 | res: express.Response 36 | } 37 | export type Handler = ( 38 | ctx: HandlerReqCtx, 39 | ) => Promise | HandlerOutput 40 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/disableInviteCodes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | codes?: string[] 15 | accounts?: string[] 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | } 28 | 29 | export type HandlerOutput = HandlerError | void 30 | export type HandlerReqCtx = { 31 | auth: HA 32 | params: QueryParams 33 | input: HandlerInput 34 | req: express.Request 35 | res: express.Response 36 | } 37 | export type Handler = ( 38 | ctx: HandlerReqCtx, 39 | ) => Promise | HandlerOutput 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "memgraph-bluej", 3 | "version": "1.0.0", 4 | "description": "memgraph graph database atproto feed generator starter kit", 5 | "main": "index.js", 6 | "repository": "git@github.com:memgraph/bluej.git", 7 | "author": "Memgraph ", 8 | "license": "MIT", 9 | "scripts": { 10 | "start": "ts-node src/index.ts", 11 | "build": "tsc", 12 | "publishFeed": "ts-node scripts/publishFeedGen.ts" 13 | }, 14 | "dependencies": { 15 | "@atproto/api": "^0.6.20", 16 | "@atproto/did-resolver": "^0.1.0", 17 | "@atproto/identity": "^0.2.1", 18 | "@atproto/lexicon": "^0.2.2", 19 | "@atproto/repo": "^0.3.2", 20 | "@atproto/syntax": "^0.1.2", 21 | "@atproto/xrpc-server": "^0.3.2", 22 | "better-sqlite3": "^8.3.0", 23 | "dotenv": "^16.0.3", 24 | "express": "^4.18.2", 25 | "kysely": "^0.22.0", 26 | "multiformats": "^9.9.0", 27 | "neo4j-driver": "^5.10.0" 28 | }, 29 | "devDependencies": { 30 | "@types/better-sqlite3": "^7.6.4", 31 | "@types/express": "^4.17.17", 32 | "@types/node": "^20.1.2", 33 | "ts-node": "^10.9.1", 34 | "typescript": "^5.0.4" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/generator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as AppBskyRichtextFacet from '../richtext/facet' 9 | import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs' 10 | 11 | export interface Record { 12 | did: string 13 | displayName: string 14 | description?: string 15 | descriptionFacets?: AppBskyRichtextFacet.Main[] 16 | avatar?: BlobRef 17 | labels?: 18 | | ComAtprotoLabelDefs.SelfLabels 19 | | { $type: string; [k: string]: unknown } 20 | createdAt: string 21 | [k: string]: unknown 22 | } 23 | 24 | export function isRecord(v: unknown): v is Record { 25 | return ( 26 | isObj(v) && 27 | hasProp(v, '$type') && 28 | (v.$type === 'app.bsky.feed.generator#main' || 29 | v.$type === 'app.bsky.feed.generator') 30 | ) 31 | } 32 | 33 | export function validateRecord(v: unknown): ValidationResult { 34 | return lexicons.validate('app.bsky.feed.generator#main', v) 35 | } 36 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/notifyOfUpdate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** Hostname of the service that is notifying of update. */ 15 | hostname: string 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | } 28 | 29 | export type HandlerOutput = HandlerError | void 30 | export type HandlerReqCtx = { 31 | auth: HA 32 | params: QueryParams 33 | input: HandlerInput 34 | req: express.Request 35 | res: express.Response 36 | } 37 | export type Handler = ( 38 | ctx: HandlerReqCtx, 39 | ) => Promise | HandlerOutput 40 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/putPreferences.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams {} 13 | 14 | export interface InputSchema { 15 | preferences: AppBskyActorDefs.Preferences 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | } 28 | 29 | export type HandlerOutput = HandlerError | void 30 | export type HandlerReqCtx = { 31 | auth: HA 32 | params: QueryParams 33 | input: HandlerInput 34 | req: express.Request 35 | res: express.Response 36 | } 37 | export type Handler = ( 38 | ctx: HandlerReqCtx, 39 | ) => Promise | HandlerOutput 40 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/updateAccountEmail.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** The handle or DID of the repo. */ 15 | account: string 16 | email: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface HandlerInput { 21 | encoding: 'application/json' 22 | body: InputSchema 23 | } 24 | 25 | export interface HandlerError { 26 | status: number 27 | message?: string 28 | } 29 | 30 | export type HandlerOutput = HandlerError | void 31 | export type HandlerReqCtx = { 32 | auth: HA 33 | params: QueryParams 34 | input: HandlerInput 35 | req: express.Request 36 | res: express.Response 37 | } 38 | export type Handler = ( 39 | ctx: HandlerReqCtx, 40 | ) => Promise | HandlerOutput 41 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/resetPassword.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | token: string 15 | password: string 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | error?: 'ExpiredToken' | 'InvalidToken' 28 | } 29 | 30 | export type HandlerOutput = HandlerError | void 31 | export type HandlerReqCtx = { 32 | auth: HA 33 | params: QueryParams 34 | input: HandlerInput 35 | req: express.Request 36 | res: express.Response 37 | } 38 | export type Handler = ( 39 | ctx: HandlerReqCtx, 40 | ) => Promise | HandlerOutput 41 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/requestCrawl.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** Hostname of the service that is requesting to be crawled. */ 15 | hostname: string 16 | [k: string]: unknown 17 | } 18 | 19 | export interface HandlerInput { 20 | encoding: 'application/json' 21 | body: InputSchema 22 | } 23 | 24 | export interface HandlerError { 25 | status: number 26 | message?: string 27 | } 28 | 29 | export type HandlerOutput = HandlerError | void 30 | export type HandlerReqCtx = { 31 | auth: HA 32 | params: QueryParams 33 | input: HandlerInput 34 | req: express.Request 35 | res: express.Response 36 | } 37 | export type Handler = ( 38 | ctx: HandlerReqCtx, 39 | ) => Promise | HandlerOutput 40 | -------------------------------------------------------------------------------- /src/methods/feed-generation.ts: -------------------------------------------------------------------------------- 1 | import { InvalidRequestError } from '@atproto/xrpc-server' 2 | import { Server } from '../lexicon' 3 | import { AppContext } from '../config' 4 | import algos from '../algos' 5 | import { validateAuth } from '../auth' 6 | import { AtUri } from '@atproto/syntax' 7 | 8 | export default function (server: Server, ctx: AppContext) { 9 | server.app.bsky.feed.getFeedSkeleton(async ({ params, req }) => { 10 | const feedUri = new AtUri(params.feed) 11 | const algo = algos[feedUri.rkey] 12 | if ( 13 | feedUri.hostname !== ctx.cfg.publisherDid || 14 | feedUri.collection !== 'app.bsky.feed.generator' || 15 | !algo 16 | ) { 17 | throw new InvalidRequestError( 18 | 'Unsupported algorithm', 19 | 'UnsupportedAlgorithm', 20 | ) 21 | } 22 | let requesterDid = '' 23 | try { 24 | requesterDid = await validateAuth( 25 | req, 26 | ctx.cfg.serviceDid, 27 | ctx.didResolver, 28 | ) 29 | } catch (e) { 30 | console.error(e) 31 | } 32 | const body = await algo(ctx, params, requesterDid) 33 | return { 34 | encoding: 'application/json', 35 | body: body, 36 | } 37 | }) 38 | } -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/deleteAccount.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | did: string 15 | password: string 16 | token: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface HandlerInput { 21 | encoding: 'application/json' 22 | body: InputSchema 23 | } 24 | 25 | export interface HandlerError { 26 | status: number 27 | message?: string 28 | error?: 'ExpiredToken' | 'InvalidToken' 29 | } 30 | 31 | export type HandlerOutput = HandlerError | void 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /visualization/backend_service/src/routes/enrich.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const enrichPerson = require('../util/enrich_util'); 3 | const { agent } = require('../index'); 4 | 5 | const router = express.Router(); 6 | 7 | router.post('/person', async (req, res) => { 8 | if (req.socket.remoteAddress !== '::1' && req.socket.remoteAddress.replace(/^.*:/, '') !== '127.0.0.1') { 9 | res.sendStatus(403); 10 | return; 11 | } 12 | 13 | if (!agent.hasSession) { 14 | res.sendStatus(401); 15 | return; 16 | } 17 | 18 | if (process.env.ENRICHMENT !== 'true') { 19 | res.sendStatus(200); 20 | return; 21 | } 22 | 23 | const did = req.body.did; 24 | 25 | const result = await enrichPerson(did); 26 | 27 | if (result) { 28 | if (process.env.VERBOSE === 'true') { 29 | process.stdout.write('Ep'); 30 | } 31 | 32 | res.sendStatus(200); 33 | } else { 34 | if (process.env.VERBOSE === 'true') { 35 | process.stdout.write(`\nAn error occured while trying to enrich person with DID: ${did}.\n`); 36 | } 37 | 38 | res.sendStatus(500); 39 | } 40 | }) 41 | 42 | module.exports = router; -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as AppBskyGraphDefs from './defs' 9 | import * as AppBskyRichtextFacet from '../richtext/facet' 10 | import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs' 11 | 12 | export interface Record { 13 | purpose: AppBskyGraphDefs.ListPurpose 14 | name: string 15 | description?: string 16 | descriptionFacets?: AppBskyRichtextFacet.Main[] 17 | avatar?: BlobRef 18 | labels?: 19 | | ComAtprotoLabelDefs.SelfLabels 20 | | { $type: string; [k: string]: unknown } 21 | createdAt: string 22 | [k: string]: unknown 23 | } 24 | 25 | export function isRecord(v: unknown): v is Record { 26 | return ( 27 | isObj(v) && 28 | hasProp(v, '$type') && 29 | (v.$type === 'app.bsky.graph.list#main' || 30 | v.$type === 'app.bsky.graph.list') 31 | ) 32 | } 33 | 34 | export function validateRecord(v: unknown): ValidationResult { 35 | return lexicons.validate('app.bsky.graph.list#main', v) 36 | } 37 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/notification/registerPush.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | serviceDid: string 15 | token: string 16 | platform: 'ios' | 'android' | 'web' | (string & {}) 17 | appId: string 18 | [k: string]: unknown 19 | } 20 | 21 | export interface HandlerInput { 22 | encoding: 'application/json' 23 | body: InputSchema 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | } 30 | 31 | export type HandlerOutput = HandlerError | void 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/disableAccountInvites.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | account: string 15 | /** Additionally add a note describing why the invites were disabled */ 16 | note?: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface HandlerInput { 21 | encoding: 'application/json' 22 | body: InputSchema 23 | } 24 | 25 | export interface HandlerError { 26 | status: number 27 | message?: string 28 | } 29 | 30 | export type HandlerOutput = HandlerError | void 31 | export type HandlerReqCtx = { 32 | auth: HA 33 | params: QueryParams 34 | input: HandlerInput 35 | req: express.Request 36 | res: express.Response 37 | } 38 | export type Handler = ( 39 | ctx: HandlerReqCtx, 40 | ) => Promise | HandlerOutput 41 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/enableAccountInvites.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | account: string 15 | /** Additionally add a note describing why the invites were enabled */ 16 | note?: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface HandlerInput { 21 | encoding: 'application/json' 22 | body: InputSchema 23 | } 24 | 25 | export interface HandlerError { 26 | status: number 27 | message?: string 28 | } 29 | 30 | export type HandlerOutput = HandlerError | void 31 | export type HandlerReqCtx = { 32 | auth: HA 33 | params: QueryParams 34 | input: HandlerInput 35 | req: express.Request 36 | res: express.Response 37 | } 38 | export type Handler = ( 39 | ctx: HandlerReqCtx, 40 | ) => Promise | HandlerOutput 41 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getCheckout.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams { 13 | /** The DID of the repo. */ 14 | did: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | export type HandlerInput = undefined 19 | 20 | export interface HandlerSuccess { 21 | encoding: 'application/vnd.ipld.car' 22 | body: Uint8Array | stream.Readable 23 | headers?: { [key: string]: string } 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | } 30 | 31 | export type HandlerOutput = HandlerError | HandlerSuccess 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/getProfile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | export type OutputSchema = AppBskyActorDefs.ProfileViewDetailed 18 | export type HandlerInput = undefined 19 | 20 | export interface HandlerSuccess { 21 | encoding: 'application/json' 22 | body: OutputSchema 23 | headers?: { [key: string]: string } 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | } 30 | 31 | export type HandlerOutput = HandlerError | HandlerSuccess 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getBlocks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams { 13 | /** The DID of the repo. */ 14 | did: string 15 | cids: string[] 16 | } 17 | 18 | export type InputSchema = undefined 19 | export type HandlerInput = undefined 20 | 21 | export interface HandlerSuccess { 22 | encoding: 'application/vnd.ipld.car' 23 | body: Uint8Array | stream.Readable 24 | headers?: { [key: string]: string } 25 | } 26 | 27 | export interface HandlerError { 28 | status: number 29 | message?: string 30 | } 31 | 32 | export type HandlerOutput = HandlerError | HandlerSuccess 33 | export type HandlerReqCtx = { 34 | auth: HA 35 | params: QueryParams 36 | input: HandlerInput 37 | req: express.Request 38 | res: express.Response 39 | } 40 | export type Handler = ( 41 | ctx: HandlerReqCtx, 42 | ) => Promise | HandlerOutput 43 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/notification/getUnreadCount.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | seenAt?: string 13 | } 14 | 15 | export type InputSchema = undefined 16 | 17 | export interface OutputSchema { 18 | count: number 19 | [k: string]: unknown 20 | } 21 | 22 | export type HandlerInput = undefined 23 | 24 | export interface HandlerSuccess { 25 | encoding: 'application/json' 26 | body: OutputSchema 27 | headers?: { [key: string]: string } 28 | } 29 | 30 | export interface HandlerError { 31 | status: number 32 | message?: string 33 | } 34 | 35 | export type HandlerOutput = HandlerError | HandlerSuccess 36 | export type HandlerReqCtx = { 37 | auth: HA 38 | params: QueryParams 39 | input: HandlerInput 40 | req: express.Request 41 | res: express.Response 42 | } 43 | export type Handler = ( 44 | ctx: HandlerReqCtx, 45 | ) => Promise | HandlerOutput 46 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/defs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface SkeletonSearchPost { 10 | uri: string 11 | [k: string]: unknown 12 | } 13 | 14 | export function isSkeletonSearchPost(v: unknown): v is SkeletonSearchPost { 15 | return ( 16 | isObj(v) && 17 | hasProp(v, '$type') && 18 | v.$type === 'app.bsky.unspecced.defs#skeletonSearchPost' 19 | ) 20 | } 21 | 22 | export function validateSkeletonSearchPost(v: unknown): ValidationResult { 23 | return lexicons.validate('app.bsky.unspecced.defs#skeletonSearchPost', v) 24 | } 25 | 26 | export interface SkeletonSearchActor { 27 | did: string 28 | [k: string]: unknown 29 | } 30 | 31 | export function isSkeletonSearchActor(v: unknown): v is SkeletonSearchActor { 32 | return ( 33 | isObj(v) && 34 | hasProp(v, '$type') && 35 | v.$type === 'app.bsky.unspecced.defs#skeletonSearchActor' 36 | ) 37 | } 38 | 39 | export function validateSkeletonSearchActor(v: unknown): ValidationResult { 40 | return lexicons.validate('app.bsky.unspecced.defs#skeletonSearchActor', v) 41 | } 42 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/getSession.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | 15 | export interface OutputSchema { 16 | handle: string 17 | did: string 18 | email?: string 19 | [k: string]: unknown 20 | } 21 | 22 | export type HandlerInput = undefined 23 | 24 | export interface HandlerSuccess { 25 | encoding: 'application/json' 26 | body: OutputSchema 27 | headers?: { [key: string]: string } 28 | } 29 | 30 | export interface HandlerError { 31 | status: number 32 | message?: string 33 | } 34 | 35 | export type HandlerOutput = HandlerError | HandlerSuccess 36 | export type HandlerReqCtx = { 37 | auth: HA 38 | params: QueryParams 39 | input: HandlerInput 40 | req: express.Request 41 | res: express.Response 42 | } 43 | export type Handler = ( 44 | ctx: HandlerReqCtx, 45 | ) => Promise | HandlerOutput 46 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getModerationAction.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | id: number 14 | } 15 | 16 | export type InputSchema = undefined 17 | export type OutputSchema = ComAtprotoAdminDefs.ActionViewDetail 18 | export type HandlerInput = undefined 19 | 20 | export interface HandlerSuccess { 21 | encoding: 'application/json' 22 | body: OutputSchema 23 | headers?: { [key: string]: string } 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | } 30 | 31 | export type HandlerOutput = HandlerError | HandlerSuccess 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getModerationReport.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | id: number 14 | } 15 | 16 | export type InputSchema = undefined 17 | export type OutputSchema = ComAtprotoAdminDefs.ReportViewDetail 18 | export type HandlerInput = undefined 19 | 20 | export interface HandlerSuccess { 21 | encoding: 'application/json' 22 | body: OutputSchema 23 | headers?: { [key: string]: string } 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | } 30 | 31 | export type HandlerOutput = HandlerError | HandlerSuccess 32 | export type HandlerReqCtx = { 33 | auth: HA 34 | params: QueryParams 35 | input: HandlerInput 36 | req: express.Request 37 | res: express.Response 38 | } 39 | export type Handler = ( 40 | ctx: HandlerReqCtx, 41 | ) => Promise | HandlerOutput 42 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getBlob.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams { 13 | /** The DID of the repo. */ 14 | did: string 15 | /** The CID of the blob to fetch */ 16 | cid: string 17 | } 18 | 19 | export type InputSchema = undefined 20 | export type HandlerInput = undefined 21 | 22 | export interface HandlerSuccess { 23 | encoding: '*/*' 24 | body: Uint8Array | stream.Readable 25 | headers?: { [key: string]: string } 26 | } 27 | 28 | export interface HandlerError { 29 | status: number 30 | message?: string 31 | } 32 | 33 | export type HandlerOutput = HandlerError | HandlerSuccess 34 | export type HandlerReqCtx = { 35 | auth: HA 36 | params: QueryParams 37 | input: HandlerInput 38 | req: express.Request 39 | res: express.Response 40 | } 41 | export type Handler = ( 42 | ctx: HandlerReqCtx, 43 | ) => Promise | HandlerOutput 44 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getRepo.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | did: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | export type OutputSchema = ComAtprotoAdminDefs.RepoViewDetail 18 | export type HandlerInput = undefined 19 | 20 | export interface HandlerSuccess { 21 | encoding: 'application/json' 22 | body: OutputSchema 23 | headers?: { [key: string]: string } 24 | } 25 | 26 | export interface HandlerError { 27 | status: number 28 | message?: string 29 | error?: 'RepoNotFound' 30 | } 31 | 32 | export type HandlerOutput = HandlerError | HandlerSuccess 33 | export type HandlerReqCtx = { 34 | auth: HA 35 | params: QueryParams 36 | input: HandlerInput 37 | req: express.Request 38 | res: express.Response 39 | } 40 | export type Handler = ( 41 | ctx: HandlerReqCtx, 42 | ) => Promise | HandlerOutput 43 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/identity/resolveHandle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The handle to resolve. */ 13 | handle: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | did: string 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | } 35 | 36 | export type HandlerOutput = HandlerError | HandlerSuccess 37 | export type HandlerReqCtx = { 38 | auth: HA 39 | params: QueryParams 40 | input: HandlerInput 41 | req: express.Request 42 | res: express.Response 43 | } 44 | export type Handler = ( 45 | ctx: HandlerReqCtx, 46 | ) => Promise | HandlerOutput 47 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/getPreferences.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams {} 13 | 14 | export type InputSchema = undefined 15 | 16 | export interface OutputSchema { 17 | preferences: AppBskyActorDefs.Preferences 18 | [k: string]: unknown 19 | } 20 | 21 | export type HandlerInput = undefined 22 | 23 | export interface HandlerSuccess { 24 | encoding: 'application/json' 25 | body: OutputSchema 26 | headers?: { [key: string]: string } 27 | } 28 | 29 | export interface HandlerError { 30 | status: number 31 | message?: string 32 | } 33 | 34 | export type HandlerOutput = HandlerError | HandlerSuccess 35 | export type HandlerReqCtx = { 36 | auth: HA 37 | params: QueryParams 38 | input: HandlerInput 39 | req: express.Request 40 | res: express.Response 41 | } 42 | export type Handler = ( 43 | ctx: HandlerReqCtx, 44 | ) => Promise | HandlerOutput 45 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getHead.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The DID of the repo. */ 13 | did: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | root: string 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | error?: 'HeadNotFound' 35 | } 36 | 37 | export type HandlerOutput = HandlerError | HandlerSuccess 38 | export type HandlerReqCtx = { 39 | auth: HA 40 | params: QueryParams 41 | input: HandlerInput 42 | req: express.Request 43 | res: express.Response 44 | } 45 | export type Handler = ( 46 | ctx: HandlerReqCtx, 47 | ) => Promise | HandlerOutput 48 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getPosts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | uris: string[] 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | posts: AppBskyFeedDefs.PostView[] 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | } 35 | 36 | export type HandlerOutput = HandlerError | HandlerSuccess 37 | export type HandlerReqCtx = { 38 | auth: HA 39 | params: QueryParams 40 | input: HandlerInput 41 | req: express.Request 42 | res: express.Response 43 | } 44 | export type Handler = ( 45 | ctx: HandlerReqCtx, 46 | ) => Promise | HandlerOutput 47 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | uri: string 14 | cid?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | export type OutputSchema = ComAtprotoAdminDefs.RecordViewDetail 19 | export type HandlerInput = undefined 20 | 21 | export interface HandlerSuccess { 22 | encoding: 'application/json' 23 | body: OutputSchema 24 | headers?: { [key: string]: string } 25 | } 26 | 27 | export interface HandlerError { 28 | status: number 29 | message?: string 30 | error?: 'RecordNotFound' 31 | } 32 | 33 | export type HandlerOutput = HandlerError | HandlerSuccess 34 | export type HandlerReqCtx = { 35 | auth: HA 36 | params: QueryParams 37 | input: HandlerInput 38 | req: express.Request 39 | res: express.Response 40 | } 41 | export type Handler = ( 42 | ctx: HandlerReqCtx, 43 | ) => Promise | HandlerOutput 44 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getRepo.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams { 13 | /** The DID of the repo. */ 14 | did: string 15 | /** The revision of the repo to catch up from. */ 16 | since?: string 17 | } 18 | 19 | export type InputSchema = undefined 20 | export type HandlerInput = undefined 21 | 22 | export interface HandlerSuccess { 23 | encoding: 'application/vnd.ipld.car' 24 | body: Uint8Array | stream.Readable 25 | headers?: { [key: string]: string } 26 | } 27 | 28 | export interface HandlerError { 29 | status: number 30 | message?: string 31 | } 32 | 33 | export type HandlerOutput = HandlerError | HandlerSuccess 34 | export type HandlerReqCtx = { 35 | auth: HA 36 | params: QueryParams 37 | input: HandlerInput 38 | req: express.Request 39 | res: express.Response 40 | } 41 | export type Handler = ( 42 | ctx: HandlerReqCtx, 43 | ) => Promise | HandlerOutput 44 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/uploadBlob.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams {} 13 | 14 | export type InputSchema = string | Uint8Array 15 | 16 | export interface OutputSchema { 17 | blob: BlobRef 18 | [k: string]: unknown 19 | } 20 | 21 | export interface HandlerInput { 22 | encoding: '*/*' 23 | body: stream.Readable 24 | } 25 | 26 | export interface HandlerSuccess { 27 | encoding: 'application/json' 28 | body: OutputSchema 29 | headers?: { [key: string]: string } 30 | } 31 | 32 | export interface HandlerError { 33 | status: number 34 | message?: string 35 | } 36 | 37 | export type HandlerOutput = HandlerError | HandlerSuccess 38 | export type HandlerReqCtx = { 39 | auth: HA 40 | params: QueryParams 41 | input: HandlerInput 42 | req: express.Request 43 | res: express.Response 44 | } 45 | export type Handler = ( 46 | ctx: HandlerReqCtx, 47 | ) => Promise | HandlerOutput 48 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getFeedGenerators.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | feeds: string[] 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | feeds: AppBskyFeedDefs.GeneratorView[] 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | } 35 | 36 | export type HandlerOutput = HandlerError | HandlerSuccess 37 | export type HandlerReqCtx = { 38 | auth: HA 39 | params: QueryParams 40 | input: HandlerInput 41 | req: express.Request 42 | res: express.Response 43 | } 44 | export type Handler = ( 45 | ctx: HandlerReqCtx, 46 | ) => Promise | HandlerOutput 47 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/getProfiles.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actors: string[] 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | profiles: AppBskyActorDefs.ProfileViewDetailed[] 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | } 35 | 36 | export type HandlerOutput = HandlerError | HandlerSuccess 37 | export type HandlerReqCtx = { 38 | auth: HA 39 | params: QueryParams 40 | input: HandlerInput 41 | req: express.Request 42 | res: express.Response 43 | } 44 | export type Handler = ( 45 | ctx: HandlerReqCtx, 46 | ) => Promise | HandlerOutput 47 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/refreshSession.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | 15 | export interface OutputSchema { 16 | accessJwt: string 17 | refreshJwt: string 18 | handle: string 19 | did: string 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | error?: 'AccountTakedown' 35 | } 36 | 37 | export type HandlerOutput = HandlerError | HandlerSuccess 38 | export type HandlerReqCtx = { 39 | auth: HA 40 | params: QueryParams 41 | input: HandlerInput 42 | req: express.Request 43 | res: express.Response 44 | } 45 | export type Handler = ( 46 | ctx: HandlerReqCtx, 47 | ) => Promise | HandlerOutput 48 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getLatestCommit.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The DID of the repo. */ 13 | did: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | cid: string 20 | rev: string 21 | [k: string]: unknown 22 | } 23 | 24 | export type HandlerInput = undefined 25 | 26 | export interface HandlerSuccess { 27 | encoding: 'application/json' 28 | body: OutputSchema 29 | headers?: { [key: string]: string } 30 | } 31 | 32 | export interface HandlerError { 33 | status: number 34 | message?: string 35 | error?: 'RepoNotFound' 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | suggestions: AppBskyActorDefs.ProfileView[] 20 | [k: string]: unknown 21 | } 22 | 23 | export type HandlerInput = undefined 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | } 35 | 36 | export type HandlerOutput = HandlerError | HandlerSuccess 37 | export type HandlerReqCtx = { 38 | auth: HA 39 | params: QueryParams 40 | input: HandlerInput 41 | req: express.Request 42 | res: express.Response 43 | } 44 | export type Handler = ( 45 | ctx: HandlerReqCtx, 46 | ) => Promise | HandlerOutput 47 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/getRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import stream from 'stream' 6 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 7 | import { lexicons } from '../../../../lexicons' 8 | import { isObj, hasProp } from '../../../../util' 9 | import { CID } from 'multiformats/cid' 10 | import { HandlerAuth } from '@atproto/xrpc-server' 11 | 12 | export interface QueryParams { 13 | /** The DID of the repo. */ 14 | did: string 15 | collection: string 16 | rkey: string 17 | /** An optional past commit CID. */ 18 | commit?: string 19 | } 20 | 21 | export type InputSchema = undefined 22 | export type HandlerInput = undefined 23 | 24 | export interface HandlerSuccess { 25 | encoding: 'application/vnd.ipld.car' 26 | body: Uint8Array | stream.Readable 27 | headers?: { [key: string]: string } 28 | } 29 | 30 | export interface HandlerError { 31 | status: number 32 | message?: string 33 | } 34 | 35 | export type HandlerOutput = HandlerError | HandlerSuccess 36 | export type HandlerReqCtx = { 37 | auth: HA 38 | params: QueryParams 39 | input: HandlerInput 40 | req: express.Request 41 | res: express.Response 42 | } 43 | export type Handler = ( 44 | ctx: HandlerReqCtx, 45 | ) => Promise | HandlerOutput 46 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/defs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface InviteCode { 10 | code: string 11 | available: number 12 | disabled: boolean 13 | forAccount: string 14 | createdBy: string 15 | createdAt: string 16 | uses: InviteCodeUse[] 17 | [k: string]: unknown 18 | } 19 | 20 | export function isInviteCode(v: unknown): v is InviteCode { 21 | return ( 22 | isObj(v) && 23 | hasProp(v, '$type') && 24 | v.$type === 'com.atproto.server.defs#inviteCode' 25 | ) 26 | } 27 | 28 | export function validateInviteCode(v: unknown): ValidationResult { 29 | return lexicons.validate('com.atproto.server.defs#inviteCode', v) 30 | } 31 | 32 | export interface InviteCodeUse { 33 | usedBy: string 34 | usedAt: string 35 | [k: string]: unknown 36 | } 37 | 38 | export function isInviteCodeUse(v: unknown): v is InviteCodeUse { 39 | return ( 40 | isObj(v) && 41 | hasProp(v, '$type') && 42 | v.$type === 'com.atproto.server.defs#inviteCodeUse' 43 | ) 44 | } 45 | 46 | export function validateInviteCodeUse(v: unknown): ValidationResult { 47 | return lexicons.validate('com.atproto.server.defs#inviteCodeUse', v) 48 | } 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getListMutes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyGraphDefs from './defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | lists: AppBskyGraphDefs.ListView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv' 2 | import FeedGenerator from './server' 3 | 4 | const run = async () => { 5 | dotenv.config() 6 | const hostname = maybeStr(process.env.FEEDGEN_HOSTNAME) ?? 'example.com' 7 | const serviceDid = 8 | maybeStr(process.env.FEEDGEN_SERVICE_DID) ?? `did:web:${hostname}` 9 | const server = FeedGenerator.create({ 10 | port: maybeInt(process.env.FEEDGEN_PORT) ?? 3000, 11 | listenhost: maybeStr(process.env.FEEDGEN_LISTENHOST) ?? 'localhost', 12 | sqliteLocation: maybeStr(process.env.FEEDGEN_SQLITE_LOCATION) ?? ':memory:', 13 | subscriptionEndpoint: 14 | maybeStr(process.env.FEEDGEN_SUBSCRIPTION_ENDPOINT) ?? 15 | 'wss://bsky.social', 16 | publisherDid: 17 | maybeStr(process.env.FEEDGEN_PUBLISHER_DID) ?? 'did:example:alice', 18 | subscriptionReconnectDelay: 19 | maybeInt(process.env.FEEDGEN_SUBSCRIPTION_RECONNECT_DELAY) ?? 3000, 20 | hostname, 21 | serviceDid, 22 | }) 23 | await server.start() 24 | console.log( 25 | `🤖 running feed generator at http://${server.cfg.listenhost}:${server.cfg.port}`, 26 | ) 27 | } 28 | 29 | const maybeStr = (val?: string) => { 30 | if (!val) return undefined 31 | return val 32 | } 33 | 34 | const maybeInt = (val?: string) => { 35 | if (!val) return undefined 36 | const int = parseInt(val, 10) 37 | if (isNaN(int)) return undefined 38 | return int 39 | } 40 | 41 | run() 42 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getFeedGenerator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | feed: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | view: AppBskyFeedDefs.GeneratorView 20 | isOnline: boolean 21 | isValid: boolean 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getListBlocks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyGraphDefs from './defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | lists: AppBskyGraphDefs.ListView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/getSuggestions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | actors: AppBskyActorDefs.ProfileView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getSuggestedFeeds.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | feeds: AppBskyFeedDefs.GeneratorView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getBlocks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | blocks: AppBskyActorDefs.ProfileView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getMutes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | mutes: AppBskyActorDefs.ProfileView[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/createInviteCode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | useCount: number 15 | forAccount?: string 16 | [k: string]: unknown 17 | } 18 | 19 | export interface OutputSchema { 20 | code: string 21 | [k: string]: unknown 22 | } 23 | 24 | export interface HandlerInput { 25 | encoding: 'application/json' 26 | body: InputSchema 27 | } 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getLists.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyGraphDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | lists: AppBskyGraphDefs.ListView[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getActorFeeds.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feeds: AppBskyFeedDefs.GeneratorView[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getTimeline.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | algorithm?: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.FeedViewPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/sendEmail.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | recipientDid: string 15 | content: string 16 | subject?: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface OutputSchema { 21 | sent: boolean 22 | [k: string]: unknown 23 | } 24 | 25 | export interface HandlerInput { 26 | encoding: 'application/json' 27 | body: InputSchema 28 | } 29 | 30 | export interface HandlerSuccess { 31 | encoding: 'application/json' 32 | body: OutputSchema 33 | headers?: { [key: string]: string } 34 | } 35 | 36 | export interface HandlerError { 37 | status: number 38 | message?: string 39 | } 40 | 41 | export type HandlerOutput = HandlerError | HandlerSuccess 42 | export type HandlerReqCtx = { 43 | auth: HA 44 | params: QueryParams 45 | input: HandlerInput 46 | req: express.Request 47 | res: express.Response 48 | } 49 | export type Handler = ( 50 | ctx: HandlerReqCtx, 51 | ) => Promise | HandlerOutput 52 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/describeRepo.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The handle or DID of the repo. */ 13 | repo: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | handle: string 20 | did: string 21 | didDoc: {} 22 | collections: string[] 23 | handleIsCorrect: boolean 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/getPopular.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from '../feed/defs' 11 | 12 | export interface QueryParams { 13 | includeNsfw: boolean 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.FeedViewPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getFeed.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | feed: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.FeedViewPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | error?: 'UnknownFeed' 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getModerationActions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | subject?: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | actions: ComAtprotoAdminDefs.ActionView[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getListFeed.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | list: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.FeedViewPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | error?: 'UnknownList' 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from '../feed/defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | query?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feeds: AppBskyFeedDefs.GeneratorView[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/getAccountInviteCodes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoServerDefs from './defs' 11 | 12 | export interface QueryParams { 13 | includeUsed: boolean 14 | createAvailable: boolean 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | codes: ComAtprotoServerDefs.InviteCode[] 21 | [k: string]: unknown 22 | } 23 | 24 | export type HandlerInput = undefined 25 | 26 | export interface HandlerSuccess { 27 | encoding: 'application/json' 28 | body: OutputSchema 29 | headers?: { [key: string]: string } 30 | } 31 | 32 | export interface HandlerError { 33 | status: number 34 | message?: string 35 | error?: 'DuplicateCreate' 36 | } 37 | 38 | export type HandlerOutput = HandlerError | HandlerSuccess 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from '../feed/defs' 11 | 12 | export interface QueryParams { 13 | limit: number 14 | cursor?: string 15 | } 16 | 17 | export type InputSchema = undefined 18 | 19 | export interface OutputSchema { 20 | cursor?: string 21 | feed: AppBskyFeedDefs.SkeletonFeedPost[] 22 | [k: string]: unknown 23 | } 24 | 25 | export type HandlerInput = undefined 26 | 27 | export interface HandlerSuccess { 28 | encoding: 'application/json' 29 | body: OutputSchema 30 | headers?: { [key: string]: string } 31 | } 32 | 33 | export interface HandlerError { 34 | status: number 35 | message?: string 36 | error?: 'UnknownFeed' 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/reverseModerationAction.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams {} 13 | 14 | export interface InputSchema { 15 | id: number 16 | reason: string 17 | createdBy: string 18 | [k: string]: unknown 19 | } 20 | 21 | export type OutputSchema = ComAtprotoAdminDefs.ActionView 22 | 23 | export interface HandlerInput { 24 | encoding: 'application/json' 25 | body: InputSchema 26 | } 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/algos/weighted-round-robin.ts: -------------------------------------------------------------------------------- 1 | import { ParallelQueriesOutput } from "./parralel-queries" 2 | 3 | export type WeightedItem = { items: any[], weight: number }; 4 | 5 | type Element = ParallelQueriesOutput; 6 | 7 | export function sortByHourAge(entries: ParallelQueriesOutput[]): ParallelQueriesOutput[] { 8 | const zeroHourAgeEntries = entries.filter((entry) => entry.hour_age === 0); 9 | const nonZeroHourAgeEntries = entries.filter((entry) => entry.hour_age !== 0); 10 | return [...zeroHourAgeEntries, ...nonZeroHourAgeEntries]; 11 | } 12 | 13 | export function deduplicateArray(arr: ParallelQueriesOutput[]): ParallelQueriesOutput[] { 14 | const idSet = new Set(); 15 | return arr.filter((obj) => { 16 | if (idSet.has(obj.id)) { 17 | return false; 18 | } 19 | idSet.add(obj.id); 20 | return true; 21 | }); 22 | } 23 | 24 | export function weightedRoundRobin(...arrays: Element[][]): Element[] { 25 | const result: Element[] = []; 26 | const arraysLengths = arrays.map(arr => arr.length); 27 | const maxCount = Math.max(...arraysLengths); 28 | 29 | for (let i = 0; i < maxCount; i++) { 30 | for (let arrIndex = 0; arrIndex < arrays.length; arrIndex++) { 31 | const arr = arrays[arrIndex]; 32 | const weight = arr.length; 33 | if (i < weight) { 34 | result.push(arr[i]); 35 | } 36 | } 37 | } 38 | return result; 39 | } -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getFeedSkeleton.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | feed: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.SkeletonFeedPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | error?: 'UnknownFeed' 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyGraphDefs from './defs' 11 | 12 | export interface QueryParams { 13 | list: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | list: AppBskyGraphDefs.ListView 23 | items: AppBskyGraphDefs.ListItemView[] 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/resolveModerationReports.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams {} 13 | 14 | export interface InputSchema { 15 | actionId: number 16 | reportIds: number[] 17 | createdBy: string 18 | [k: string]: unknown 19 | } 20 | 21 | export type OutputSchema = ComAtprotoAdminDefs.ActionView 22 | 23 | export interface HandlerInput { 24 | encoding: 'application/json' 25 | body: InputSchema 26 | } 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getActorLikes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | feed: AppBskyFeedDefs.FeedViewPost[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | error?: 'BlockedActor' | 'BlockedByActor' 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getInviteCodes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoServerDefs from '../server/defs' 11 | 12 | export interface QueryParams { 13 | sort: 'recent' | 'usage' | (string & {}) 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | cursor?: string 22 | codes: ComAtprotoServerDefs.InviteCode[] 23 | [k: string]: unknown 24 | } 25 | 26 | export type HandlerInput = undefined 27 | 28 | export interface HandlerSuccess { 29 | encoding: 'application/json' 30 | body: OutputSchema 31 | headers?: { [key: string]: string } 32 | } 33 | 34 | export interface HandlerError { 35 | status: number 36 | message?: string 37 | } 38 | 39 | export type HandlerOutput = HandlerError | HandlerSuccess 40 | export type HandlerReqCtx = { 41 | auth: HA 42 | params: QueryParams 43 | input: HandlerInput 44 | req: express.Request 45 | res: express.Response 46 | } 47 | export type Handler = ( 48 | ctx: HandlerReqCtx, 49 | ) => Promise | HandlerOutput 50 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/listBlobs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The DID of the repo. */ 13 | did: string 14 | /** Optional revision of the repo to list blobs since */ 15 | since?: string 16 | limit: number 17 | cursor?: string 18 | } 19 | 20 | export type InputSchema = undefined 21 | 22 | export interface OutputSchema { 23 | cursor?: string 24 | cids: string[] 25 | [k: string]: unknown 26 | } 27 | 28 | export type HandlerInput = undefined 29 | 30 | export interface HandlerSuccess { 31 | encoding: 'application/json' 32 | body: OutputSchema 33 | headers?: { [key: string]: string } 34 | } 35 | 36 | export interface HandlerError { 37 | status: number 38 | message?: string 39 | } 40 | 41 | export type HandlerOutput = HandlerError | HandlerSuccess 42 | export type HandlerReqCtx = { 43 | auth: HA 44 | params: QueryParams 45 | input: HandlerInput 46 | req: express.Request 47 | res: express.Response 48 | } 49 | export type Handler = ( 50 | ctx: HandlerReqCtx, 51 | ) => Promise | HandlerOutput 52 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getFollowers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | subject: AppBskyActorDefs.ProfileView 22 | cursor?: string 23 | followers: AppBskyActorDefs.ProfileView[] 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/graph/getFollows.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | subject: AppBskyActorDefs.ProfileView 22 | cursor?: string 23 | follows: AppBskyActorDefs.ProfileView[] 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/moderation/defs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export type ReasonType = 10 | | 'com.atproto.moderation.defs#reasonSpam' 11 | | 'com.atproto.moderation.defs#reasonViolation' 12 | | 'com.atproto.moderation.defs#reasonMisleading' 13 | | 'com.atproto.moderation.defs#reasonSexual' 14 | | 'com.atproto.moderation.defs#reasonRude' 15 | | 'com.atproto.moderation.defs#reasonOther' 16 | | (string & {}) 17 | 18 | /** Spam: frequent unwanted promotion, replies, mentions */ 19 | export const REASONSPAM = 'com.atproto.moderation.defs#reasonSpam' 20 | /** Direct violation of server rules, laws, terms of service */ 21 | export const REASONVIOLATION = 'com.atproto.moderation.defs#reasonViolation' 22 | /** Misleading identity, affiliation, or content */ 23 | export const REASONMISLEADING = 'com.atproto.moderation.defs#reasonMisleading' 24 | /** Unwanted or mislabeled sexual content */ 25 | export const REASONSEXUAL = 'com.atproto.moderation.defs#reasonSexual' 26 | /** Rude, harassing, explicit, or otherwise unwelcoming behavior */ 27 | export const REASONRUDE = 'com.atproto.moderation.defs#reasonRude' 28 | /** Other: reports not falling under another report category */ 29 | export const REASONOTHER = 'com.atproto.moderation.defs#reasonOther' 30 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getRepostedBy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | uri: string 14 | cid?: string 15 | limit: number 16 | cursor?: string 17 | } 18 | 19 | export type InputSchema = undefined 20 | 21 | export interface OutputSchema { 22 | uri: string 23 | cid?: string 24 | cursor?: string 25 | repostedBy: AppBskyActorDefs.ProfileView[] 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | } 41 | 42 | export type HandlerOutput = HandlerError | HandlerSuccess 43 | export type HandlerReqCtx = { 44 | auth: HA 45 | params: QueryParams 46 | input: HandlerInput 47 | req: express.Request 48 | res: express.Response 49 | } 50 | export type Handler = ( 51 | ctx: HandlerReqCtx, 52 | ) => Promise | HandlerOutput 53 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/deleteRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** The handle or DID of the repo. */ 15 | repo: string 16 | /** The NSID of the record collection. */ 17 | collection: string 18 | /** The key of the record. */ 19 | rkey: string 20 | /** Compare and swap with the previous record by cid. */ 21 | swapRecord?: string 22 | /** Compare and swap with the previous commit by cid. */ 23 | swapCommit?: string 24 | [k: string]: unknown 25 | } 26 | 27 | export interface HandlerInput { 28 | encoding: 'application/json' 29 | body: InputSchema 30 | } 31 | 32 | export interface HandlerError { 33 | status: number 34 | message?: string 35 | error?: 'InvalidSwap' 36 | } 37 | 38 | export type HandlerOutput = HandlerError | void 39 | export type HandlerReqCtx = { 40 | auth: HA 41 | params: QueryParams 42 | input: HandlerInput 43 | req: express.Request 44 | res: express.Response 45 | } 46 | export type Handler = ( 47 | ctx: HandlerReqCtx, 48 | ) => Promise | HandlerOutput 49 | -------------------------------------------------------------------------------- /query_module/README.md: -------------------------------------------------------------------------------- 1 | # Score algorithm c++ query module 2 | 3 | To speed up the calculation of the score per post, this module implements both the famous HN ranking as well as a 4 | more flexible exponentially decaying scoring algorithm 5 | 6 | To use this instead of the ranking in the cypher query replace: 7 | ``` 8 | (ceil(likes) / ceil(1 + (hour_age * hour_age * hour_age * hour_age))) as score, likes, hour_age, post 9 | ``` 10 | 11 | in the query with: 12 | 13 | ``` 14 | CALL bluej.hacker_news(likes, hour_age, 4.1) YIELD score 15 | ``` 16 | 17 | 18 | 19 | Instructions on how to build the memgraph query module: 20 | 21 | 22 | ``` 23 | docker run -d -p 7687:7687 -p 7444:7444 -p 3000:3000 --name bluej_module_builder memgraph/memgraph --telemetry-enabled=False 24 | 25 | docker exec -u 0 -it bluej_module_builder 26 | 27 | In the container run: 28 | 29 | apt update -y 30 | apt install -y git cmake gcc g++ vim clang-format 31 | cd / 32 | git clone https://github.com/memgraph/mage 33 | git submodule update --init --recursive 34 | mkdir -p /mage/cpp/bluej 35 | cd /mage/cpp/bluej 36 | cp CMake and bluej.cpp here 37 | 38 | /# append `add_subdirectory(bluej)` to the /mage/cpp/CMakeLists.txt 39 | 40 | mkdir -p /mage/cpp/build && cd /mage/cpp/build && cmake -DCMAKE_BUILD_TYPE=Release .. && make bluej 41 | 42 | /# here, /mage/cpp/build/bluej.so should exist and should be copied into /usr/lib/memgraph/query_modules 43 | /# Run this in mgconsole / lab to load the module: 44 | CALL mg.load_all(); 45 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** DEPRECATED: use 'q' instead */ 14 | term?: string 15 | /** search query prefix; not a full query string */ 16 | q?: string 17 | limit: number 18 | } 19 | 20 | export type InputSchema = undefined 21 | 22 | export interface OutputSchema { 23 | actors: AppBskyActorDefs.ProfileViewBasic[] 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/searchRepos.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** DEPRECATED: use 'q' instead */ 14 | term?: string 15 | q?: string 16 | invitedBy?: string 17 | limit: number 18 | cursor?: string 19 | } 20 | 21 | export type InputSchema = undefined 22 | 23 | export interface OutputSchema { 24 | cursor?: string 25 | repos: ComAtprotoAdminDefs.RepoView[] 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | } 41 | 42 | export type HandlerOutput = HandlerError | HandlerSuccess 43 | export type HandlerReqCtx = { 44 | auth: HA 45 | params: QueryParams 46 | input: HandlerInput 47 | req: express.Request 48 | res: express.Response 49 | } 50 | export type Handler = ( 51 | ctx: HandlerReqCtx, 52 | ) => Promise | HandlerOutput 53 | -------------------------------------------------------------------------------- /app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BlueJ 7 | 8 | 9 | 38 | 39 | 40 | 41 | 42 | 43 |

BlueJ

44 |
45 |

46 |
https://bluej.memgraph.com/1/:id
47 |

48 |
  • 49 | Get popularity score from people I (id) follow by number of likes and comments. 50 |
  • 51 | 52 |

    53 |
    https://bluej.memgraph.com/2/:id
    54 |

    55 |
  • 56 | Get popularity score from people who are followed by the people I (id) follow by number of likes and 57 | comments and post age. 58 |
  • 59 | 60 |

    61 |
    https://bluej.memgraph.com/3/:id
    62 |

    63 |
  • 64 | Get popularity score from people in the same community by number of likes and comments and post age. 65 |
  • 66 |
    67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getPostThread.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | uri: string 14 | depth: number 15 | parentHeight: number 16 | } 17 | 18 | export type InputSchema = undefined 19 | 20 | export interface OutputSchema { 21 | thread: 22 | | AppBskyFeedDefs.ThreadViewPost 23 | | AppBskyFeedDefs.NotFoundPost 24 | | AppBskyFeedDefs.BlockedPost 25 | | { $type: string; [k: string]: unknown } 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | error?: 'NotFound' 41 | } 42 | 43 | export type HandlerOutput = HandlerError | HandlerSuccess 44 | export type HandlerReqCtx = { 45 | auth: HA 46 | params: QueryParams 47 | input: HandlerInput 48 | req: express.Request 49 | res: express.Response 50 | } 51 | export type Handler = ( 52 | ctx: HandlerReqCtx, 53 | ) => Promise | HandlerOutput 54 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getAuthorFeed.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | actor: string 14 | limit: number 15 | cursor?: string 16 | filter: 17 | | 'posts_with_replies' 18 | | 'posts_no_replies' 19 | | 'posts_with_media' 20 | | (string & {}) 21 | } 22 | 23 | export type InputSchema = undefined 24 | 25 | export interface OutputSchema { 26 | cursor?: string 27 | feed: AppBskyFeedDefs.FeedViewPost[] 28 | [k: string]: unknown 29 | } 30 | 31 | export type HandlerInput = undefined 32 | 33 | export interface HandlerSuccess { 34 | encoding: 'application/json' 35 | body: OutputSchema 36 | headers?: { [key: string]: string } 37 | } 38 | 39 | export interface HandlerError { 40 | status: number 41 | message?: string 42 | error?: 'BlockedActor' | 'BlockedByActor' 43 | } 44 | 45 | export type HandlerOutput = HandlerError | HandlerSuccess 46 | export type HandlerReqCtx = { 47 | auth: HA 48 | params: QueryParams 49 | input: HandlerInput 50 | req: express.Request 51 | res: express.Response 52 | } 53 | export type Handler = ( 54 | ctx: HandlerReqCtx, 55 | ) => Promise | HandlerOutput 56 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/actor/searchActors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** DEPRECATED: use 'q' instead */ 14 | term?: string 15 | /** search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended */ 16 | q?: string 17 | limit: number 18 | cursor?: string 19 | } 20 | 21 | export type InputSchema = undefined 22 | 23 | export interface OutputSchema { 24 | cursor?: string 25 | actors: AppBskyActorDefs.ProfileView[] 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | } 41 | 42 | export type HandlerOutput = HandlerError | HandlerSuccess 43 | export type HandlerReqCtx = { 44 | auth: HA 45 | params: QueryParams 46 | input: HandlerInput 47 | req: express.Request 48 | res: express.Response 49 | } 50 | export type Handler = ( 51 | ctx: HandlerReqCtx, 52 | ) => Promise | HandlerOutput 53 | -------------------------------------------------------------------------------- /visualization/backend_service/src/util/enrich_util.js: -------------------------------------------------------------------------------- 1 | const { driver, agent } = require('../index'); 2 | 3 | const enrichPerson = async (did) => { 4 | try { 5 | const user = await agent.getProfile({actor: did}); 6 | 7 | if (!user) { 8 | if (process.env.VERBOSE === 'true') { 9 | console.log('Failed to fetch user profile.'); 10 | } 11 | 12 | return; 13 | } 14 | 15 | const session = driver.session(); 16 | let cypher = `MATCH (p:Person) WHERE p.did = $did SET `; 17 | 18 | const parameters = { 19 | did: user?.data.did || "", 20 | handle: user?.data.handle || "", 21 | displayName: user?.data.displayName || "", 22 | description: user?.data.description || "", 23 | avatar: user?.data.avatar || "", 24 | followsCount: user?.data.followsCount || "", 25 | followersCount: user?.data.followersCount || "" 26 | }; 27 | 28 | const setClauses = Object.entries(parameters) 29 | .filter(([key, value]) => value !== null && value !== "" && key !== "did") 30 | .map(([key, value]) => `p.${key} = $${key}`) 31 | .join(', '); 32 | 33 | cypher += setClauses; 34 | 35 | const result = await session.run(cypher, parameters); 36 | session.close(); 37 | 38 | return result; 39 | } catch (err) { 40 | if (process.env.VERBOSE === 'true') { 41 | console.log(err); 42 | } 43 | 44 | return; 45 | } 46 | } 47 | 48 | module.exports = enrichPerson; -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/getRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The handle or DID of the repo. */ 13 | repo: string 14 | /** The NSID of the record collection. */ 15 | collection: string 16 | /** The key of the record. */ 17 | rkey: string 18 | /** The CID of the version of the record. If not specified, then return the most recent version. */ 19 | cid?: string 20 | } 21 | 22 | export type InputSchema = undefined 23 | 24 | export interface OutputSchema { 25 | uri: string 26 | cid?: string 27 | value: {} 28 | [k: string]: unknown 29 | } 30 | 31 | export type HandlerInput = undefined 32 | 33 | export interface HandlerSuccess { 34 | encoding: 'application/json' 35 | body: OutputSchema 36 | headers?: { [key: string]: string } 37 | } 38 | 39 | export interface HandlerError { 40 | status: number 41 | message?: string 42 | } 43 | 44 | export type HandlerOutput = HandlerError | HandlerSuccess 45 | export type HandlerReqCtx = { 46 | auth: HA 47 | params: QueryParams 48 | input: HandlerInput 49 | req: express.Request 50 | res: express.Response 51 | } 52 | export type Handler = ( 53 | ctx: HandlerReqCtx, 54 | ) => Promise | HandlerOutput 55 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/createSession.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** Handle or other identifier supported by the server for the authenticating user. */ 15 | identifier: string 16 | password: string 17 | [k: string]: unknown 18 | } 19 | 20 | export interface OutputSchema { 21 | accessJwt: string 22 | refreshJwt: string 23 | handle: string 24 | did: string 25 | email?: string 26 | [k: string]: unknown 27 | } 28 | 29 | export interface HandlerInput { 30 | encoding: 'application/json' 31 | body: InputSchema 32 | } 33 | 34 | export interface HandlerSuccess { 35 | encoding: 'application/json' 36 | body: OutputSchema 37 | headers?: { [key: string]: string } 38 | } 39 | 40 | export interface HandlerError { 41 | status: number 42 | message?: string 43 | error?: 'AccountTakedown' 44 | } 45 | 46 | export type HandlerOutput = HandlerError | HandlerSuccess 47 | export type HandlerReqCtx = { 48 | auth: HA 49 | params: QueryParams 50 | input: HandlerInput 51 | req: express.Request 52 | res: express.Response 53 | } 54 | export type Handler = ( 55 | ctx: HandlerReqCtx, 56 | ) => Promise | HandlerOutput 57 | -------------------------------------------------------------------------------- /visualization/live/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "visualization-live", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/react": "^11.11.1", 7 | "@emotion/styled": "^11.11.0", 8 | "@fontsource/roboto": "^5.0.6", 9 | "@fortawesome/fontawesome-svg-core": "^6.4.0", 10 | "@fortawesome/free-regular-svg-icons": "^6.4.0", 11 | "@fortawesome/free-solid-svg-icons": "^6.4.0", 12 | "@fortawesome/react-fontawesome": "^0.2.0", 13 | "@mui/icons-material": "^5.14.3", 14 | "@mui/material": "^5.14.3", 15 | "@testing-library/jest-dom": "^5.17.0", 16 | "@testing-library/react": "^13.4.0", 17 | "@testing-library/user-event": "^13.5.0", 18 | "react": "^18.2.0", 19 | "react-color": "^2.19.3", 20 | "react-dom": "^18.2.0", 21 | "react-force-graph-2d": "^1.25.0", 22 | "react-force-graph-3d": "^1.23.0", 23 | "react-scripts": "5.0.1", 24 | "react-toastify": "^9.1.3", 25 | "socket.io-client": "^4.7.1", 26 | "three": "^0.154.0", 27 | "web-vitals": "^2.1.4" 28 | }, 29 | "scripts": { 30 | "start": "react-scripts start", 31 | "build": "react-scripts build", 32 | "test": "react-scripts test", 33 | "eject": "react-scripts eject" 34 | }, 35 | "eslintConfig": { 36 | "extends": [ 37 | "react-app", 38 | "react-app/jest" 39 | ] 40 | }, 41 | "browserslist": { 42 | "production": [ 43 | ">0.2%", 44 | "not dead", 45 | "not op_mini all" 46 | ], 47 | "development": [ 48 | "last 1 chrome version", 49 | "last 1 firefox version", 50 | "last 1 safari version" 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/embed/recordWithMedia.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import * as AppBskyEmbedRecord from './record' 9 | import * as AppBskyEmbedImages from './images' 10 | import * as AppBskyEmbedExternal from './external' 11 | 12 | export interface Main { 13 | record: AppBskyEmbedRecord.Main 14 | media: 15 | | AppBskyEmbedImages.Main 16 | | AppBskyEmbedExternal.Main 17 | | { $type: string; [k: string]: unknown } 18 | [k: string]: unknown 19 | } 20 | 21 | export function isMain(v: unknown): v is Main { 22 | return ( 23 | isObj(v) && 24 | hasProp(v, '$type') && 25 | (v.$type === 'app.bsky.embed.recordWithMedia#main' || 26 | v.$type === 'app.bsky.embed.recordWithMedia') 27 | ) 28 | } 29 | 30 | export function validateMain(v: unknown): ValidationResult { 31 | return lexicons.validate('app.bsky.embed.recordWithMedia#main', v) 32 | } 33 | 34 | export interface View { 35 | record: AppBskyEmbedRecord.View 36 | media: 37 | | AppBskyEmbedImages.View 38 | | AppBskyEmbedExternal.View 39 | | { $type: string; [k: string]: unknown } 40 | [k: string]: unknown 41 | } 42 | 43 | export function isView(v: unknown): v is View { 44 | return ( 45 | isObj(v) && 46 | hasProp(v, '$type') && 47 | v.$type === 'app.bsky.embed.recordWithMedia#view' 48 | ) 49 | } 50 | 51 | export function validateView(v: unknown): ValidationResult { 52 | return lexicons.validate('app.bsky.embed.recordWithMedia#view', v) 53 | } 54 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/label/queryLabels.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoLabelDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI */ 14 | uriPatterns: string[] 15 | /** Optional list of label sources (DIDs) to filter on */ 16 | sources?: string[] 17 | limit: number 18 | cursor?: string 19 | } 20 | 21 | export type InputSchema = undefined 22 | 23 | export interface OutputSchema { 24 | cursor?: string 25 | labels: ComAtprotoLabelDefs.Label[] 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | } 41 | 42 | export type HandlerOutput = HandlerError | HandlerSuccess 43 | export type HandlerReqCtx = { 44 | auth: HA 45 | params: QueryParams 46 | input: HandlerInput 47 | req: express.Request 48 | res: express.Response 49 | } 50 | export type Handler = ( 51 | ctx: HandlerReqCtx, 52 | ) => Promise | HandlerOutput 53 | -------------------------------------------------------------------------------- /visualization/live/README.md: -------------------------------------------------------------------------------- 1 | ### Query module 2 | 3 | To run the visualization locally, you have to have the custom visualization query module loaded to Memgraph. To compile it, you can consult the README.md file in the query_module folder. 4 | Note: if you plan to run Memgraph on host (so not in a Docker container), you will have to change the hostname (line 12 in visualization.cpp) to 'http://localhost:3002'. 5 | 6 | ### Triggers 7 | 8 | In order for the visualization to work, Memgraph needs to have certain triggers stored. You can create the necessary triggers using the following queries (each probably needs to be done separately): 9 | 10 | ``` 11 | DROP TRIGGER nodeCreate; 12 | DROP TRIGGER relationshipCreate; 13 | DROP TRIGGER nodeDelete; 14 | DROP TRIGGER relationshipDelete; 15 | DROP TRIGGER personEnrich; 16 | 17 | CREATE TRIGGER nodeCreate ON () CREATE AFTER COMMIT EXECUTE 18 | UNWIND createdVertices AS createdNode 19 | RETURN visualization.create_node(createdNode); 20 | 21 | CREATE TRIGGER relationshipCreate ON --> CREATE AFTER COMMIT EXECUTE 22 | UNWIND createdEdges AS createdRelationship 23 | RETURN visualization.handle_relationship(createdRelationship, "merge"); 24 | 25 | CREATE TRIGGER nodeDelete ON () DELETE BEFORE COMMIT EXECUTE 26 | UNWIND deletedVertices AS deletedNode 27 | RETURN visualization.delete_node(deletedNode); 28 | 29 | CREATE TRIGGER relationshipDelete ON --> DELETE BEFORE COMMIT EXECUTE 30 | UNWIND deletedEdges AS deletedRelationship 31 | RETURN visualization.handle_relationship(deletedRelationship, "detach"); 32 | 33 | CREATE TRIGGER personEnrich ON () CREATE AFTER COMMIT EXECUTE 34 | UNWIND createdVertices AS createdNode 35 | RETURN CASE LABELS(createdNode)[0] WHEN 'Person' THEN visualization.enrich_person(createdNode.did) END; 36 | ``` -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/sync/listRepos.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | limit: number 13 | cursor?: string 14 | } 15 | 16 | export type InputSchema = undefined 17 | 18 | export interface OutputSchema { 19 | cursor?: string 20 | repos: Repo[] 21 | [k: string]: unknown 22 | } 23 | 24 | export type HandlerInput = undefined 25 | 26 | export interface HandlerSuccess { 27 | encoding: 'application/json' 28 | body: OutputSchema 29 | headers?: { [key: string]: string } 30 | } 31 | 32 | export interface HandlerError { 33 | status: number 34 | message?: string 35 | } 36 | 37 | export type HandlerOutput = HandlerError | HandlerSuccess 38 | export type HandlerReqCtx = { 39 | auth: HA 40 | params: QueryParams 41 | input: HandlerInput 42 | req: express.Request 43 | res: express.Response 44 | } 45 | export type Handler = ( 46 | ctx: HandlerReqCtx, 47 | ) => Promise | HandlerOutput 48 | 49 | export interface Repo { 50 | did: string 51 | head: string 52 | [k: string]: unknown 53 | } 54 | 55 | export function isRepo(v: unknown): v is Repo { 56 | return ( 57 | isObj(v) && 58 | hasProp(v, '$type') && 59 | v.$type === 'com.atproto.sync.listRepos#repo' 60 | ) 61 | } 62 | 63 | export function validateRepo(v: unknown): ValidationResult { 64 | return lexicons.validate('com.atproto.sync.listRepos#repo', v) 65 | } 66 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/createAccount.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | email: string 15 | handle: string 16 | did?: string 17 | inviteCode?: string 18 | password: string 19 | recoveryKey?: string 20 | [k: string]: unknown 21 | } 22 | 23 | export interface OutputSchema { 24 | accessJwt: string 25 | refreshJwt: string 26 | handle: string 27 | did: string 28 | [k: string]: unknown 29 | } 30 | 31 | export interface HandlerInput { 32 | encoding: 'application/json' 33 | body: InputSchema 34 | } 35 | 36 | export interface HandlerSuccess { 37 | encoding: 'application/json' 38 | body: OutputSchema 39 | headers?: { [key: string]: string } 40 | } 41 | 42 | export interface HandlerError { 43 | status: number 44 | message?: string 45 | error?: 46 | | 'InvalidHandle' 47 | | 'InvalidPassword' 48 | | 'InvalidInviteCode' 49 | | 'HandleNotAvailable' 50 | | 'UnsupportedDomain' 51 | | 'UnresolvableDid' 52 | | 'IncompatibleDidDoc' 53 | } 54 | 55 | export type HandlerOutput = HandlerError | HandlerSuccess 56 | export type HandlerReqCtx = { 57 | auth: HA 58 | params: QueryParams 59 | input: HandlerInput 60 | req: express.Request 61 | res: express.Response 62 | } 63 | export type Handler = ( 64 | ctx: HandlerReqCtx, 65 | ) => Promise | HandlerOutput 66 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/createRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** The handle or DID of the repo. */ 15 | repo: string 16 | /** The NSID of the record collection. */ 17 | collection: string 18 | /** The key of the record. */ 19 | rkey?: string 20 | /** Validate the record? */ 21 | validate: boolean 22 | /** The record to create. */ 23 | record: {} 24 | /** Compare and swap with the previous commit by cid. */ 25 | swapCommit?: string 26 | [k: string]: unknown 27 | } 28 | 29 | export interface OutputSchema { 30 | uri: string 31 | cid: string 32 | [k: string]: unknown 33 | } 34 | 35 | export interface HandlerInput { 36 | encoding: 'application/json' 37 | body: InputSchema 38 | } 39 | 40 | export interface HandlerSuccess { 41 | encoding: 'application/json' 42 | body: OutputSchema 43 | headers?: { [key: string]: string } 44 | } 45 | 46 | export interface HandlerError { 47 | status: number 48 | message?: string 49 | error?: 'InvalidSwap' 50 | } 51 | 52 | export type HandlerOutput = HandlerError | HandlerSuccess 53 | export type HandlerReqCtx = { 54 | auth: HA 55 | params: QueryParams 56 | input: HandlerInput 57 | req: express.Request 58 | res: express.Response 59 | } 60 | export type Handler = ( 61 | ctx: HandlerReqCtx, 62 | ) => Promise | HandlerOutput 63 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/searchPosts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyFeedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended */ 14 | q: string 15 | limit: number 16 | /** optional pagination mechanism; may not necessarily allow scrolling through entire result set */ 17 | cursor?: string 18 | } 19 | 20 | export type InputSchema = undefined 21 | 22 | export interface OutputSchema { 23 | cursor?: string 24 | /** count of search hits. optional, may be rounded/truncated, and may not be possible to paginate through all hits */ 25 | hitsTotal?: number 26 | posts: AppBskyFeedDefs.PostView[] 27 | [k: string]: unknown 28 | } 29 | 30 | export type HandlerInput = undefined 31 | 32 | export interface HandlerSuccess { 33 | encoding: 'application/json' 34 | body: OutputSchema 35 | headers?: { [key: string]: string } 36 | } 37 | 38 | export interface HandlerError { 39 | status: number 40 | message?: string 41 | error?: 'BadQueryString' 42 | } 43 | 44 | export type HandlerOutput = HandlerError | HandlerSuccess 45 | export type HandlerReqCtx = { 46 | auth: HA 47 | params: QueryParams 48 | input: HandlerInput 49 | req: express.Request 50 | res: express.Response 51 | } 52 | export type Handler = ( 53 | ctx: HandlerReqCtx, 54 | ) => Promise | HandlerOutput 55 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/listAppPasswords.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | 15 | export interface OutputSchema { 16 | passwords: AppPassword[] 17 | [k: string]: unknown 18 | } 19 | 20 | export type HandlerInput = undefined 21 | 22 | export interface HandlerSuccess { 23 | encoding: 'application/json' 24 | body: OutputSchema 25 | headers?: { [key: string]: string } 26 | } 27 | 28 | export interface HandlerError { 29 | status: number 30 | message?: string 31 | error?: 'AccountTakedown' 32 | } 33 | 34 | export type HandlerOutput = HandlerError | HandlerSuccess 35 | export type HandlerReqCtx = { 36 | auth: HA 37 | params: QueryParams 38 | input: HandlerInput 39 | req: express.Request 40 | res: express.Response 41 | } 42 | export type Handler = ( 43 | ctx: HandlerReqCtx, 44 | ) => Promise | HandlerOutput 45 | 46 | export interface AppPassword { 47 | name: string 48 | createdAt: string 49 | [k: string]: unknown 50 | } 51 | 52 | export function isAppPassword(v: unknown): v is AppPassword { 53 | return ( 54 | isObj(v) && 55 | hasProp(v, '$type') && 56 | v.$type === 'com.atproto.server.listAppPasswords#appPassword' 57 | ) 58 | } 59 | 60 | export function validateAppPassword(v: unknown): ValidationResult { 61 | return lexicons.validate('com.atproto.server.listAppPasswords#appPassword', v) 62 | } 63 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/describeServer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | 15 | export interface OutputSchema { 16 | inviteCodeRequired?: boolean 17 | availableUserDomains: string[] 18 | links?: Links 19 | [k: string]: unknown 20 | } 21 | 22 | export type HandlerInput = undefined 23 | 24 | export interface HandlerSuccess { 25 | encoding: 'application/json' 26 | body: OutputSchema 27 | headers?: { [key: string]: string } 28 | } 29 | 30 | export interface HandlerError { 31 | status: number 32 | message?: string 33 | } 34 | 35 | export type HandlerOutput = HandlerError | HandlerSuccess 36 | export type HandlerReqCtx = { 37 | auth: HA 38 | params: QueryParams 39 | input: HandlerInput 40 | req: express.Request 41 | res: express.Response 42 | } 43 | export type Handler = ( 44 | ctx: HandlerReqCtx, 45 | ) => Promise | HandlerOutput 46 | 47 | export interface Links { 48 | privacyPolicy?: string 49 | termsOfService?: string 50 | [k: string]: unknown 51 | } 52 | 53 | export function isLinks(v: unknown): v is Links { 54 | return ( 55 | isObj(v) && 56 | hasProp(v, '$type') && 57 | v.$type === 'com.atproto.server.describeServer#links' 58 | ) 59 | } 60 | 61 | export function validateLinks(v: unknown): ValidationResult { 62 | return lexicons.validate('com.atproto.server.describeServer#links', v) 63 | } 64 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyUnspeccedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended */ 14 | q: string 15 | limit: number 16 | /** optional pagination mechanism; may not necessarily allow scrolling through entire result set */ 17 | cursor?: string 18 | } 19 | 20 | export type InputSchema = undefined 21 | 22 | export interface OutputSchema { 23 | cursor?: string 24 | /** count of search hits. optional, may be rounded/truncated, and may not be possible to paginate through all hits */ 25 | hitsTotal?: number 26 | posts: AppBskyUnspeccedDefs.SkeletonSearchPost[] 27 | [k: string]: unknown 28 | } 29 | 30 | export type HandlerInput = undefined 31 | 32 | export interface HandlerSuccess { 33 | encoding: 'application/json' 34 | body: OutputSchema 35 | headers?: { [key: string]: string } 36 | } 37 | 38 | export interface HandlerError { 39 | status: number 40 | message?: string 41 | error?: 'BadQueryString' 42 | } 43 | 44 | export type HandlerOutput = HandlerError | HandlerSuccess 45 | export type HandlerReqCtx = { 46 | auth: HA 47 | params: QueryParams 48 | input: HandlerInput 49 | req: express.Request 50 | res: express.Response 51 | } 52 | export type Handler = ( 53 | ctx: HandlerReqCtx, 54 | ) => Promise | HandlerOutput 55 | -------------------------------------------------------------------------------- /query_module/bluej.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | const char *kProcedureHackerNews = "hacker_news"; 7 | const char *kArgumentHackerNewsVotes = "votes"; 8 | const char *kArgumentHackerNewsItemHourAge = "item_hour_age"; 9 | const char *kArgumentHackerNewsGravity = "gravity"; 10 | const char *kReturnHackerNewsScore = "score"; 11 | 12 | void HackerNews(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *result, mgp_memory *memory) { 13 | mgp::memory = memory; 14 | const auto &arguments = mgp::List(args); 15 | const auto record_factory = mgp::RecordFactory(result); 16 | try { 17 | const auto votes = arguments[0].ValueInt(); 18 | const auto item_hour_age = arguments[1].ValueInt(); 19 | const auto gravity = arguments[2].ValueDouble(); 20 | const auto score = 1000000.0 * (votes / pow((item_hour_age + 2), gravity)); 21 | auto record = record_factory.NewRecord(); 22 | record.Insert(kReturnHackerNewsScore, score); 23 | } catch (const std::exception &e) { 24 | record_factory.SetErrorMessage(e.what()); 25 | return; 26 | } 27 | } 28 | 29 | extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) { 30 | try { 31 | mgp::memory = memory; 32 | std::vector params = { 33 | mgp::Parameter(kArgumentHackerNewsVotes, mgp::Type::Int), 34 | mgp::Parameter(kArgumentHackerNewsItemHourAge, mgp::Type::Int), 35 | mgp::Parameter(kArgumentHackerNewsGravity, mgp::Type::Double), 36 | }; 37 | std::vector returns = {mgp::Return(kReturnHackerNewsScore, mgp::Type::Double)}; 38 | AddProcedure(HackerNews, kProcedureHackerNews, mgp::ProcedureType::Read, params, returns, module, memory); 39 | } catch (const std::exception &e) { 40 | return 1; 41 | } 42 | return 0; 43 | } 44 | 45 | extern "C" int mgp_shutdown_module() { return 0; } 46 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/putRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | /** The handle or DID of the repo. */ 15 | repo: string 16 | /** The NSID of the record collection. */ 17 | collection: string 18 | /** The key of the record. */ 19 | rkey: string 20 | /** Validate the record? */ 21 | validate: boolean 22 | /** The record to write. */ 23 | record: {} 24 | /** Compare and swap with the previous record by cid. */ 25 | swapRecord?: string | null 26 | /** Compare and swap with the previous commit by cid. */ 27 | swapCommit?: string 28 | [k: string]: unknown 29 | } 30 | 31 | export interface OutputSchema { 32 | uri: string 33 | cid: string 34 | [k: string]: unknown 35 | } 36 | 37 | export interface HandlerInput { 38 | encoding: 'application/json' 39 | body: InputSchema 40 | } 41 | 42 | export interface HandlerSuccess { 43 | encoding: 'application/json' 44 | body: OutputSchema 45 | headers?: { [key: string]: string } 46 | } 47 | 48 | export interface HandlerError { 49 | status: number 50 | message?: string 51 | error?: 'InvalidSwap' 52 | } 53 | 54 | export type HandlerOutput = HandlerError | HandlerSuccess 55 | export type HandlerReqCtx = { 56 | auth: HA 57 | params: QueryParams 58 | input: HandlerInput 59 | req: express.Request 60 | res: express.Response 61 | } 62 | export type Handler = ( 63 | ctx: HandlerReqCtx, 64 | ) => Promise | HandlerOutput 65 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/getLikes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | 12 | export interface QueryParams { 13 | uri: string 14 | cid?: string 15 | limit: number 16 | cursor?: string 17 | } 18 | 19 | export type InputSchema = undefined 20 | 21 | export interface OutputSchema { 22 | uri: string 23 | cid?: string 24 | cursor?: string 25 | likes: Like[] 26 | [k: string]: unknown 27 | } 28 | 29 | export type HandlerInput = undefined 30 | 31 | export interface HandlerSuccess { 32 | encoding: 'application/json' 33 | body: OutputSchema 34 | headers?: { [key: string]: string } 35 | } 36 | 37 | export interface HandlerError { 38 | status: number 39 | message?: string 40 | } 41 | 42 | export type HandlerOutput = HandlerError | HandlerSuccess 43 | export type HandlerReqCtx = { 44 | auth: HA 45 | params: QueryParams 46 | input: HandlerInput 47 | req: express.Request 48 | res: express.Response 49 | } 50 | export type Handler = ( 51 | ctx: HandlerReqCtx, 52 | ) => Promise | HandlerOutput 53 | 54 | export interface Like { 55 | indexedAt: string 56 | createdAt: string 57 | actor: AppBskyActorDefs.ProfileView 58 | [k: string]: unknown 59 | } 60 | 61 | export function isLike(v: unknown): v is Like { 62 | return ( 63 | isObj(v) && hasProp(v, '$type') && v.$type === 'app.bsky.feed.getLikes#like' 64 | ) 65 | } 66 | 67 | export function validateLike(v: unknown): ValidationResult { 68 | return lexicons.validate('app.bsky.feed.getLikes#like', v) 69 | } 70 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/createAppPassword.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | name: string 15 | [k: string]: unknown 16 | } 17 | 18 | export type OutputSchema = AppPassword 19 | 20 | export interface HandlerInput { 21 | encoding: 'application/json' 22 | body: InputSchema 23 | } 24 | 25 | export interface HandlerSuccess { 26 | encoding: 'application/json' 27 | body: OutputSchema 28 | headers?: { [key: string]: string } 29 | } 30 | 31 | export interface HandlerError { 32 | status: number 33 | message?: string 34 | error?: 'AccountTakedown' 35 | } 36 | 37 | export type HandlerOutput = HandlerError | HandlerSuccess 38 | export type HandlerReqCtx = { 39 | auth: HA 40 | params: QueryParams 41 | input: HandlerInput 42 | req: express.Request 43 | res: express.Response 44 | } 45 | export type Handler = ( 46 | ctx: HandlerReqCtx, 47 | ) => Promise | HandlerOutput 48 | 49 | export interface AppPassword { 50 | name: string 51 | password: string 52 | createdAt: string 53 | [k: string]: unknown 54 | } 55 | 56 | export function isAppPassword(v: unknown): v is AppPassword { 57 | return ( 58 | isObj(v) && 59 | hasProp(v, '$type') && 60 | v.$type === 'com.atproto.server.createAppPassword#appPassword' 61 | ) 62 | } 63 | 64 | export function validateAppPassword(v: unknown): ValidationResult { 65 | return lexicons.validate( 66 | 'com.atproto.server.createAppPassword#appPassword', 67 | v, 68 | ) 69 | } 70 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/server/createInviteCodes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export interface InputSchema { 14 | codeCount: number 15 | useCount: number 16 | forAccounts?: string[] 17 | [k: string]: unknown 18 | } 19 | 20 | export interface OutputSchema { 21 | codes: AccountCodes[] 22 | [k: string]: unknown 23 | } 24 | 25 | export interface HandlerInput { 26 | encoding: 'application/json' 27 | body: InputSchema 28 | } 29 | 30 | export interface HandlerSuccess { 31 | encoding: 'application/json' 32 | body: OutputSchema 33 | headers?: { [key: string]: string } 34 | } 35 | 36 | export interface HandlerError { 37 | status: number 38 | message?: string 39 | } 40 | 41 | export type HandlerOutput = HandlerError | HandlerSuccess 42 | export type HandlerReqCtx = { 43 | auth: HA 44 | params: QueryParams 45 | input: HandlerInput 46 | req: express.Request 47 | res: express.Response 48 | } 49 | export type Handler = ( 50 | ctx: HandlerReqCtx, 51 | ) => Promise | HandlerOutput 52 | 53 | export interface AccountCodes { 54 | account: string 55 | codes: string[] 56 | [k: string]: unknown 57 | } 58 | 59 | export function isAccountCodes(v: unknown): v is AccountCodes { 60 | return ( 61 | isObj(v) && 62 | hasProp(v, '$type') && 63 | v.$type === 'com.atproto.server.createInviteCodes#accountCodes' 64 | ) 65 | } 66 | 67 | export function validateAccountCodes(v: unknown): ValidationResult { 68 | return lexicons.validate( 69 | 'com.atproto.server.createInviteCodes#accountCodes', 70 | v, 71 | ) 72 | } 73 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyUnspeccedDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. For typeahead search, only simple term match is supported, not full syntax */ 14 | q: string 15 | /** if true, acts as fast/simple 'typeahead' query */ 16 | typeahead?: boolean 17 | limit: number 18 | /** optional pagination mechanism; may not necessarily allow scrolling through entire result set */ 19 | cursor?: string 20 | } 21 | 22 | export type InputSchema = undefined 23 | 24 | export interface OutputSchema { 25 | cursor?: string 26 | /** count of search hits. optional, may be rounded/truncated, and may not be possible to paginate through all hits */ 27 | hitsTotal?: number 28 | actors: AppBskyUnspeccedDefs.SkeletonSearchActor[] 29 | [k: string]: unknown 30 | } 31 | 32 | export type HandlerInput = undefined 33 | 34 | export interface HandlerSuccess { 35 | encoding: 'application/json' 36 | body: OutputSchema 37 | headers?: { [key: string]: string } 38 | } 39 | 40 | export interface HandlerError { 41 | status: number 42 | message?: string 43 | error?: 'BadQueryString' 44 | } 45 | 46 | export type HandlerOutput = HandlerError | HandlerSuccess 47 | export type HandlerReqCtx = { 48 | auth: HA 49 | params: QueryParams 50 | input: HandlerInput 51 | req: express.Request 52 | res: express.Response 53 | } 54 | export type Handler = ( 55 | ctx: HandlerReqCtx, 56 | ) => Promise | HandlerOutput 57 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/moderation/createReport.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoModerationDefs from './defs' 11 | import * as ComAtprotoAdminDefs from '../admin/defs' 12 | import * as ComAtprotoRepoStrongRef from '../repo/strongRef' 13 | 14 | export interface QueryParams {} 15 | 16 | export interface InputSchema { 17 | reasonType: ComAtprotoModerationDefs.ReasonType 18 | reason?: string 19 | subject: 20 | | ComAtprotoAdminDefs.RepoRef 21 | | ComAtprotoRepoStrongRef.Main 22 | | { $type: string; [k: string]: unknown } 23 | [k: string]: unknown 24 | } 25 | 26 | export interface OutputSchema { 27 | id: number 28 | reasonType: ComAtprotoModerationDefs.ReasonType 29 | reason?: string 30 | subject: 31 | | ComAtprotoAdminDefs.RepoRef 32 | | ComAtprotoRepoStrongRef.Main 33 | | { $type: string; [k: string]: unknown } 34 | reportedBy: string 35 | createdAt: string 36 | [k: string]: unknown 37 | } 38 | 39 | export interface HandlerInput { 40 | encoding: 'application/json' 41 | body: InputSchema 42 | } 43 | 44 | export interface HandlerSuccess { 45 | encoding: 'application/json' 46 | body: OutputSchema 47 | headers?: { [key: string]: string } 48 | } 49 | 50 | export interface HandlerError { 51 | status: number 52 | message?: string 53 | } 54 | 55 | export type HandlerOutput = HandlerError | HandlerSuccess 56 | export type HandlerReqCtx = { 57 | auth: HA 58 | params: QueryParams 59 | input: HandlerInput 60 | req: express.Request 61 | res: express.Response 62 | } 63 | export type Handler = ( 64 | ctx: HandlerReqCtx, 65 | ) => Promise | HandlerOutput 66 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/getModerationReports.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | 12 | export interface QueryParams { 13 | subject?: string 14 | ignoreSubjects?: string[] 15 | /** Get all reports that were actioned by a specific moderator */ 16 | actionedBy?: string 17 | /** Filter reports made by one or more DIDs */ 18 | reporters?: string[] 19 | resolved?: boolean 20 | actionType?: 21 | | 'com.atproto.admin.defs#takedown' 22 | | 'com.atproto.admin.defs#flag' 23 | | 'com.atproto.admin.defs#acknowledge' 24 | | 'com.atproto.admin.defs#escalate' 25 | | (string & {}) 26 | limit: number 27 | cursor?: string 28 | /** Reverse the order of the returned records? when true, returns reports in chronological order */ 29 | reverse?: boolean 30 | } 31 | 32 | export type InputSchema = undefined 33 | 34 | export interface OutputSchema { 35 | cursor?: string 36 | reports: ComAtprotoAdminDefs.ReportView[] 37 | [k: string]: unknown 38 | } 39 | 40 | export type HandlerInput = undefined 41 | 42 | export interface HandlerSuccess { 43 | encoding: 'application/json' 44 | body: OutputSchema 45 | headers?: { [key: string]: string } 46 | } 47 | 48 | export interface HandlerError { 49 | status: number 50 | message?: string 51 | } 52 | 53 | export type HandlerOutput = HandlerError | HandlerSuccess 54 | export type HandlerReqCtx = { 55 | auth: HA 56 | params: QueryParams 57 | input: HandlerInput 58 | req: express.Request 59 | res: express.Response 60 | } 61 | export type Handler = ( 62 | ctx: HandlerReqCtx, 63 | ) => Promise | HandlerOutput 64 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/admin/takeModerationAction.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as ComAtprotoAdminDefs from './defs' 11 | import * as ComAtprotoRepoStrongRef from '../repo/strongRef' 12 | 13 | export interface QueryParams {} 14 | 15 | export interface InputSchema { 16 | action: 17 | | 'com.atproto.admin.defs#takedown' 18 | | 'com.atproto.admin.defs#flag' 19 | | 'com.atproto.admin.defs#acknowledge' 20 | | (string & {}) 21 | subject: 22 | | ComAtprotoAdminDefs.RepoRef 23 | | ComAtprotoRepoStrongRef.Main 24 | | { $type: string; [k: string]: unknown } 25 | subjectBlobCids?: string[] 26 | createLabelVals?: string[] 27 | negateLabelVals?: string[] 28 | reason: string 29 | /** Indicates how long this action was meant to be in effect before automatically expiring. */ 30 | durationInHours?: number 31 | createdBy: string 32 | [k: string]: unknown 33 | } 34 | 35 | export type OutputSchema = ComAtprotoAdminDefs.ActionView 36 | 37 | export interface HandlerInput { 38 | encoding: 'application/json' 39 | body: InputSchema 40 | } 41 | 42 | export interface HandlerSuccess { 43 | encoding: 'application/json' 44 | body: OutputSchema 45 | headers?: { [key: string]: string } 46 | } 47 | 48 | export interface HandlerError { 49 | status: number 50 | message?: string 51 | error?: 'SubjectHasAction' 52 | } 53 | 54 | export type HandlerOutput = HandlerError | HandlerSuccess 55 | export type HandlerReqCtx = { 56 | auth: HA 57 | params: QueryParams 58 | input: HandlerInput 59 | req: express.Request 60 | res: express.Response 61 | } 62 | export type Handler = ( 63 | ctx: HandlerReqCtx, 64 | ) => Promise | HandlerOutput 65 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/label/subscribeLabels.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | import { HandlerAuth, ErrorFrame } from '@atproto/xrpc-server' 9 | import { IncomingMessage } from 'http' 10 | import * as ComAtprotoLabelDefs from './defs' 11 | 12 | export interface QueryParams { 13 | /** The last known event to backfill from. */ 14 | cursor?: number 15 | } 16 | 17 | export type OutputSchema = 18 | | Labels 19 | | Info 20 | | { $type: string; [k: string]: unknown } 21 | export type HandlerError = ErrorFrame<'FutureCursor'> 22 | export type HandlerOutput = HandlerError | OutputSchema 23 | export type HandlerReqCtx = { 24 | auth: HA 25 | params: QueryParams 26 | req: IncomingMessage 27 | signal: AbortSignal 28 | } 29 | export type Handler = ( 30 | ctx: HandlerReqCtx, 31 | ) => AsyncIterable 32 | 33 | export interface Labels { 34 | seq: number 35 | labels: ComAtprotoLabelDefs.Label[] 36 | [k: string]: unknown 37 | } 38 | 39 | export function isLabels(v: unknown): v is Labels { 40 | return ( 41 | isObj(v) && 42 | hasProp(v, '$type') && 43 | v.$type === 'com.atproto.label.subscribeLabels#labels' 44 | ) 45 | } 46 | 47 | export function validateLabels(v: unknown): ValidationResult { 48 | return lexicons.validate('com.atproto.label.subscribeLabels#labels', v) 49 | } 50 | 51 | export interface Info { 52 | name: 'OutdatedCursor' | (string & {}) 53 | message?: string 54 | [k: string]: unknown 55 | } 56 | 57 | export function isInfo(v: unknown): v is Info { 58 | return ( 59 | isObj(v) && 60 | hasProp(v, '$type') && 61 | v.$type === 'com.atproto.label.subscribeLabels#info' 62 | ) 63 | } 64 | 65 | export function validateInfo(v: unknown): ValidationResult { 66 | return lexicons.validate('com.atproto.label.subscribeLabels#info', v) 67 | } 68 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams {} 12 | 13 | export type InputSchema = undefined 14 | 15 | export interface OutputSchema { 16 | did: string 17 | feeds: Feed[] 18 | links?: Links 19 | [k: string]: unknown 20 | } 21 | 22 | export type HandlerInput = undefined 23 | 24 | export interface HandlerSuccess { 25 | encoding: 'application/json' 26 | body: OutputSchema 27 | headers?: { [key: string]: string } 28 | } 29 | 30 | export interface HandlerError { 31 | status: number 32 | message?: string 33 | } 34 | 35 | export type HandlerOutput = HandlerError | HandlerSuccess 36 | export type HandlerReqCtx = { 37 | auth: HA 38 | params: QueryParams 39 | input: HandlerInput 40 | req: express.Request 41 | res: express.Response 42 | } 43 | export type Handler = ( 44 | ctx: HandlerReqCtx, 45 | ) => Promise | HandlerOutput 46 | 47 | export interface Feed { 48 | uri: string 49 | [k: string]: unknown 50 | } 51 | 52 | export function isFeed(v: unknown): v is Feed { 53 | return ( 54 | isObj(v) && 55 | hasProp(v, '$type') && 56 | v.$type === 'app.bsky.feed.describeFeedGenerator#feed' 57 | ) 58 | } 59 | 60 | export function validateFeed(v: unknown): ValidationResult { 61 | return lexicons.validate('app.bsky.feed.describeFeedGenerator#feed', v) 62 | } 63 | 64 | export interface Links { 65 | privacyPolicy?: string 66 | termsOfService?: string 67 | [k: string]: unknown 68 | } 69 | 70 | export function isLinks(v: unknown): v is Links { 71 | return ( 72 | isObj(v) && 73 | hasProp(v, '$type') && 74 | v.$type === 'app.bsky.feed.describeFeedGenerator#links' 75 | ) 76 | } 77 | 78 | export function validateLinks(v: unknown): ValidationResult { 79 | return lexicons.validate('app.bsky.feed.describeFeedGenerator#links', v) 80 | } 81 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/embed/external.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Main { 10 | external: External 11 | [k: string]: unknown 12 | } 13 | 14 | export function isMain(v: unknown): v is Main { 15 | return ( 16 | isObj(v) && 17 | hasProp(v, '$type') && 18 | (v.$type === 'app.bsky.embed.external#main' || 19 | v.$type === 'app.bsky.embed.external') 20 | ) 21 | } 22 | 23 | export function validateMain(v: unknown): ValidationResult { 24 | return lexicons.validate('app.bsky.embed.external#main', v) 25 | } 26 | 27 | export interface External { 28 | uri: string 29 | title: string 30 | description: string 31 | thumb?: BlobRef 32 | [k: string]: unknown 33 | } 34 | 35 | export function isExternal(v: unknown): v is External { 36 | return ( 37 | isObj(v) && 38 | hasProp(v, '$type') && 39 | v.$type === 'app.bsky.embed.external#external' 40 | ) 41 | } 42 | 43 | export function validateExternal(v: unknown): ValidationResult { 44 | return lexicons.validate('app.bsky.embed.external#external', v) 45 | } 46 | 47 | export interface View { 48 | external: ViewExternal 49 | [k: string]: unknown 50 | } 51 | 52 | export function isView(v: unknown): v is View { 53 | return ( 54 | isObj(v) && 55 | hasProp(v, '$type') && 56 | v.$type === 'app.bsky.embed.external#view' 57 | ) 58 | } 59 | 60 | export function validateView(v: unknown): ValidationResult { 61 | return lexicons.validate('app.bsky.embed.external#view', v) 62 | } 63 | 64 | export interface ViewExternal { 65 | uri: string 66 | title: string 67 | description: string 68 | thumb?: string 69 | [k: string]: unknown 70 | } 71 | 72 | export function isViewExternal(v: unknown): v is ViewExternal { 73 | return ( 74 | isObj(v) && 75 | hasProp(v, '$type') && 76 | v.$type === 'app.bsky.embed.external#viewExternal' 77 | ) 78 | } 79 | 80 | export function validateViewExternal(v: unknown): ValidationResult { 81 | return lexicons.validate('app.bsky.embed.external#viewExternal', v) 82 | } 83 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/repo/listRecords.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | 11 | export interface QueryParams { 12 | /** The handle or DID of the repo. */ 13 | repo: string 14 | /** The NSID of the record type. */ 15 | collection: string 16 | /** The number of records to return. */ 17 | limit: number 18 | cursor?: string 19 | /** DEPRECATED: The lowest sort-ordered rkey to start from (exclusive) */ 20 | rkeyStart?: string 21 | /** DEPRECATED: The highest sort-ordered rkey to stop at (exclusive) */ 22 | rkeyEnd?: string 23 | /** Reverse the order of the returned records? */ 24 | reverse?: boolean 25 | } 26 | 27 | export type InputSchema = undefined 28 | 29 | export interface OutputSchema { 30 | cursor?: string 31 | records: Record[] 32 | [k: string]: unknown 33 | } 34 | 35 | export type HandlerInput = undefined 36 | 37 | export interface HandlerSuccess { 38 | encoding: 'application/json' 39 | body: OutputSchema 40 | headers?: { [key: string]: string } 41 | } 42 | 43 | export interface HandlerError { 44 | status: number 45 | message?: string 46 | } 47 | 48 | export type HandlerOutput = HandlerError | HandlerSuccess 49 | export type HandlerReqCtx = { 50 | auth: HA 51 | params: QueryParams 52 | input: HandlerInput 53 | req: express.Request 54 | res: express.Response 55 | } 56 | export type Handler = ( 57 | ctx: HandlerReqCtx, 58 | ) => Promise | HandlerOutput 59 | 60 | export interface Record { 61 | uri: string 62 | cid: string 63 | value: {} 64 | [k: string]: unknown 65 | } 66 | 67 | export function isRecord(v: unknown): v is Record { 68 | return ( 69 | isObj(v) && 70 | hasProp(v, '$type') && 71 | v.$type === 'com.atproto.repo.listRecords#record' 72 | ) 73 | } 74 | 75 | export function validateRecord(v: unknown): ValidationResult { 76 | return lexicons.validate('com.atproto.repo.listRecords#record', v) 77 | } 78 | -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- 1 | import http from 'http' 2 | import events from 'events' 3 | import express from 'express' 4 | import { DidResolver, MemoryCache } from '@atproto/identity' 5 | import { createServer } from './lexicon' 6 | import feedGeneration from './methods/feed-generation' 7 | import describeGenerator from './methods/describe-generator' 8 | import { createDb, Database, migrateToLatest } from './db' 9 | import { FirehoseSubscription } from './subscription' 10 | import { AppContext, Config } from './config' 11 | import wellKnown from './well-known' 12 | 13 | export class FeedGenerator { 14 | public app: express.Application 15 | public server?: http.Server 16 | public db: Database 17 | public firehose: FirehoseSubscription 18 | public cfg: Config 19 | 20 | constructor( 21 | app: express.Application, 22 | db: Database, 23 | firehose: FirehoseSubscription, 24 | cfg: Config, 25 | ) { 26 | this.app = app 27 | this.db = db 28 | this.firehose = firehose 29 | this.cfg = cfg 30 | } 31 | 32 | static create(cfg: Config) { 33 | const app = express() 34 | const db = createDb(cfg.sqliteLocation) 35 | const firehose = new FirehoseSubscription(db, cfg.subscriptionEndpoint) 36 | 37 | const didCache = new MemoryCache() 38 | const didResolver = new DidResolver({ 39 | plcUrl: 'https://plc.directory', 40 | didCache, 41 | }) 42 | 43 | const server = createServer({ 44 | validateResponse: true, 45 | payload: { 46 | jsonLimit: 100 * 1024, // 100kb 47 | textLimit: 100 * 1024, // 100kb 48 | blobLimit: 5 * 1024 * 1024, // 5mb 49 | }, 50 | }) 51 | const ctx: AppContext = { 52 | db, 53 | didResolver, 54 | cfg, 55 | } 56 | feedGeneration(server, ctx) 57 | describeGenerator(server, ctx) 58 | app.use(server.xrpc.router) 59 | app.use(wellKnown(ctx)) 60 | 61 | return new FeedGenerator(app, db, firehose, cfg) 62 | } 63 | 64 | async start(): Promise { 65 | await migrateToLatest(this.db) 66 | this.firehose.run(this.cfg.subscriptionReconnectDelay) 67 | this.server = this.app.listen(this.cfg.port, this.cfg.listenhost) 68 | await events.once(this.server, 'listening') 69 | return this.server 70 | } 71 | } 72 | 73 | export default FeedGenerator 74 | -------------------------------------------------------------------------------- /visualization/query_module/README.md: -------------------------------------------------------------------------------- 1 | # Instructions on how to build the Memgraph query module 2 | 3 | First run the following two commands to start running Memgraph Platform and setup a bash commandline which we will use for the next steps: 4 | 5 | ``` 6 | docker run -d -it -p 7687:7687 -p 7444:7444 -p 3000:3000 --name visualization_module_builder --add-host=host.docker.internal:host-gateway memgraph/memgraph-platform 7 | docker exec -u 0 -it visualization_module_builder bash 8 | ``` 9 | 10 | Now run: 11 | 12 | ``` 13 | apt update -y 14 | apt install -y git cmake gcc g++ vim clang-format libcurl4-openssl-dev 15 | git clone https://github.com/memgraph/mage 16 | cd mage 17 | git submodule update --init --recursive 18 | mkdir -p /mage/cpp/visualization 19 | ``` 20 | 21 | Now you need to copy the CMakeLists.txt and visualization.cpp files to /mage/cpp/visualization: 22 | In another shell: 23 | 24 | ``` 25 | docker ps 26 | ``` 27 | 28 | Copy the container ID 29 | Position yourself in this folder (bluej/visualization/query_module) 30 | Now run the following two lines: 31 | 32 | ``` 33 | docker cp ./CMakeLists.txt :/mage/cpp/visualization 34 | docker cp ./json.hpp :/mage/cpp/visualization 35 | docker cp ./visualization.cpp :/mage/cpp/visualization 36 | ``` 37 | 38 | We need to append the line "add_subdirectory(visualization)" to the /mage/cpp/CMakeLists.txt file. 39 | To do that, run the following commands back in the first shell: 40 | 41 | ``` 42 | cd /mage/cpp 43 | echo "add_subdirectory(visualization)" >> CMakeLists.txt 44 | ``` 45 | 46 | Finally, run the following commands to build the visualization.so shared object: 47 | 48 | ``` 49 | mkdir -p /mage/cpp/build 50 | cd /mage/cpp/build 51 | cmake -DCMAKE_BUILD_TYPE=Release .. 52 | make visualization 53 | ``` 54 | 55 | Now, the file visualization.so should exist in folder /mage/cpp/build/visualization. The final step is to copy it to /usr/lib/memgraph/query_modules (all MAGE query modules are stored here): 56 | 57 | ``` 58 | cd visualization 59 | cp visualization.so /usr/lib/memgraph/query_modules 60 | ``` 61 | 62 | To load the query module to Memgraph, run the following Cypher query in Memgraph Lab or mgconsole: 63 | 64 | ``` 65 | CALL mg.load_all(); 66 | ``` 67 | 68 | Now, you can check if the visualization query module exists (in Memgraph Lab, check the Query modules tab) and call its functions. -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/feed/threadgate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | export interface Record { 10 | post: string 11 | allow?: ( 12 | | MentionRule 13 | | FollowingRule 14 | | ListRule 15 | | { $type: string; [k: string]: unknown } 16 | )[] 17 | createdAt: string 18 | [k: string]: unknown 19 | } 20 | 21 | export function isRecord(v: unknown): v is Record { 22 | return ( 23 | isObj(v) && 24 | hasProp(v, '$type') && 25 | (v.$type === 'app.bsky.feed.threadgate#main' || 26 | v.$type === 'app.bsky.feed.threadgate') 27 | ) 28 | } 29 | 30 | export function validateRecord(v: unknown): ValidationResult { 31 | return lexicons.validate('app.bsky.feed.threadgate#main', v) 32 | } 33 | 34 | /** Allow replies from actors mentioned in your post. */ 35 | export interface MentionRule { 36 | [k: string]: unknown 37 | } 38 | 39 | export function isMentionRule(v: unknown): v is MentionRule { 40 | return ( 41 | isObj(v) && 42 | hasProp(v, '$type') && 43 | v.$type === 'app.bsky.feed.threadgate#mentionRule' 44 | ) 45 | } 46 | 47 | export function validateMentionRule(v: unknown): ValidationResult { 48 | return lexicons.validate('app.bsky.feed.threadgate#mentionRule', v) 49 | } 50 | 51 | /** Allow replies from actors you follow. */ 52 | export interface FollowingRule { 53 | [k: string]: unknown 54 | } 55 | 56 | export function isFollowingRule(v: unknown): v is FollowingRule { 57 | return ( 58 | isObj(v) && 59 | hasProp(v, '$type') && 60 | v.$type === 'app.bsky.feed.threadgate#followingRule' 61 | ) 62 | } 63 | 64 | export function validateFollowingRule(v: unknown): ValidationResult { 65 | return lexicons.validate('app.bsky.feed.threadgate#followingRule', v) 66 | } 67 | 68 | /** Allow replies from actors on a list. */ 69 | export interface ListRule { 70 | list: string 71 | [k: string]: unknown 72 | } 73 | 74 | export function isListRule(v: unknown): v is ListRule { 75 | return ( 76 | isObj(v) && 77 | hasProp(v, '$type') && 78 | v.$type === 'app.bsky.feed.threadgate#listRule' 79 | ) 80 | } 81 | 82 | export function validateListRule(v: unknown): ValidationResult { 83 | return lexicons.validate('app.bsky.feed.threadgate#listRule', v) 84 | } 85 | -------------------------------------------------------------------------------- /src/lexicon/types/app/bsky/notification/listNotifications.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import express from 'express' 5 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 6 | import { lexicons } from '../../../../lexicons' 7 | import { isObj, hasProp } from '../../../../util' 8 | import { CID } from 'multiformats/cid' 9 | import { HandlerAuth } from '@atproto/xrpc-server' 10 | import * as AppBskyActorDefs from '../actor/defs' 11 | import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs' 12 | 13 | export interface QueryParams { 14 | limit: number 15 | cursor?: string 16 | seenAt?: string 17 | } 18 | 19 | export type InputSchema = undefined 20 | 21 | export interface OutputSchema { 22 | cursor?: string 23 | notifications: Notification[] 24 | [k: string]: unknown 25 | } 26 | 27 | export type HandlerInput = undefined 28 | 29 | export interface HandlerSuccess { 30 | encoding: 'application/json' 31 | body: OutputSchema 32 | headers?: { [key: string]: string } 33 | } 34 | 35 | export interface HandlerError { 36 | status: number 37 | message?: string 38 | } 39 | 40 | export type HandlerOutput = HandlerError | HandlerSuccess 41 | export type HandlerReqCtx = { 42 | auth: HA 43 | params: QueryParams 44 | input: HandlerInput 45 | req: express.Request 46 | res: express.Response 47 | } 48 | export type Handler = ( 49 | ctx: HandlerReqCtx, 50 | ) => Promise | HandlerOutput 51 | 52 | export interface Notification { 53 | uri: string 54 | cid: string 55 | author: AppBskyActorDefs.ProfileView 56 | /** Expected values are 'like', 'repost', 'follow', 'mention', 'reply', and 'quote'. */ 57 | reason: 58 | | 'like' 59 | | 'repost' 60 | | 'follow' 61 | | 'mention' 62 | | 'reply' 63 | | 'quote' 64 | | (string & {}) 65 | reasonSubject?: string 66 | record: {} 67 | isRead: boolean 68 | indexedAt: string 69 | labels?: ComAtprotoLabelDefs.Label[] 70 | [k: string]: unknown 71 | } 72 | 73 | export function isNotification(v: unknown): v is Notification { 74 | return ( 75 | isObj(v) && 76 | hasProp(v, '$type') && 77 | v.$type === 'app.bsky.notification.listNotifications#notification' 78 | ) 79 | } 80 | 81 | export function validateNotification(v: unknown): ValidationResult { 82 | return lexicons.validate( 83 | 'app.bsky.notification.listNotifications#notification', 84 | v, 85 | ) 86 | } 87 | -------------------------------------------------------------------------------- /src/lexicon/types/com/atproto/label/defs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GENERATED CODE - DO NOT MODIFY 3 | */ 4 | import { ValidationResult, BlobRef } from '@atproto/lexicon' 5 | import { lexicons } from '../../../../lexicons' 6 | import { isObj, hasProp } from '../../../../util' 7 | import { CID } from 'multiformats/cid' 8 | 9 | /** Metadata tag on an atproto resource (eg, repo or record) */ 10 | export interface Label { 11 | /** DID of the actor who created this label */ 12 | src: string 13 | /** AT URI of the record, repository (account), or other resource which this label applies to */ 14 | uri: string 15 | /** optionally, CID specifying the specific version of 'uri' resource this label applies to */ 16 | cid?: string 17 | /** the short string name of the value or type of this label */ 18 | val: string 19 | /** if true, this is a negation label, overwriting a previous label */ 20 | neg?: boolean 21 | /** timestamp when this label was created */ 22 | cts: string 23 | [k: string]: unknown 24 | } 25 | 26 | export function isLabel(v: unknown): v is Label { 27 | return ( 28 | isObj(v) && 29 | hasProp(v, '$type') && 30 | v.$type === 'com.atproto.label.defs#label' 31 | ) 32 | } 33 | 34 | export function validateLabel(v: unknown): ValidationResult { 35 | return lexicons.validate('com.atproto.label.defs#label', v) 36 | } 37 | 38 | /** Metadata tags on an atproto record, published by the author within the record. */ 39 | export interface SelfLabels { 40 | values: SelfLabel[] 41 | [k: string]: unknown 42 | } 43 | 44 | export function isSelfLabels(v: unknown): v is SelfLabels { 45 | return ( 46 | isObj(v) && 47 | hasProp(v, '$type') && 48 | v.$type === 'com.atproto.label.defs#selfLabels' 49 | ) 50 | } 51 | 52 | export function validateSelfLabels(v: unknown): ValidationResult { 53 | return lexicons.validate('com.atproto.label.defs#selfLabels', v) 54 | } 55 | 56 | /** Metadata tag on an atproto record, published by the author within the record. Note -- schemas should use #selfLabels, not #selfLabel. */ 57 | export interface SelfLabel { 58 | /** the short string name of the value or type of this label */ 59 | val: string 60 | [k: string]: unknown 61 | } 62 | 63 | export function isSelfLabel(v: unknown): v is SelfLabel { 64 | return ( 65 | isObj(v) && 66 | hasProp(v, '$type') && 67 | v.$type === 'com.atproto.label.defs#selfLabel' 68 | ) 69 | } 70 | 71 | export function validateSelfLabel(v: unknown): ValidationResult { 72 | return lexicons.validate('com.atproto.label.defs#selfLabel', v) 73 | } 74 | -------------------------------------------------------------------------------- /scripts/import-authors.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { BskyAgent } from '@atproto/api' 3 | import * as dotenv from 'dotenv' 4 | import fs from 'fs' 5 | 6 | dotenv.config() 7 | 8 | const agent = new BskyAgent({ 9 | service: 'https://bsky.social/', 10 | }) 11 | 12 | // Function to resolve a handle to a DID using the getProfile XRPC call. Returns an empty string on failure 13 | async function fetchDid(handle: string): Promise { 14 | try { 15 | handle = handle.trim() 16 | let profile = await agent.getProfile({ actor: handle }) 17 | return profile.data.did 18 | } catch (err) { 19 | //console.error('fetchDid failed for', handle ) 20 | return '' 21 | } 22 | } 23 | 24 | async function downloadCSVData(): Promise { 25 | 26 | // Google sheet created by @jillianne.bsky.social / https://bsky.app/profile/did:plc:jjioi6tsi2v5oqz5bp2labs2 27 | const url = 'https://docs.google.com/spreadsheets/d/1HrhKRL7G8eaJxm2hk_J-Q0YMS1ztWY98RFPfnBkA_AA/gviz/tq?tqx=out:csv&sheet=Authors%20on%20Bluesky'; 28 | 29 | try { 30 | // Fetch the sheet as CSV so it can be parsed 31 | const response = await axios.get(url) 32 | const csvData: string = response.data 33 | 34 | // Split the CSV data into rows 35 | const rows: string[] = csvData.split('\n') 36 | 37 | // Extract the values from the first column starting at the 3rd row which contains the author handles 38 | const values: string[] = rows.slice(2).map((row) => row.split(',')[0].replace(/"|@/g, '')) 39 | 40 | // The handle then needs to be resolved to a DID that can be used in queries 41 | const fetchedValues = await Promise.all( 42 | values.map((value) => fetchDid(value)) 43 | ) 44 | // Some of them might fail lookup, so filter out any empty (failed) values 45 | const nonEmptyValues: string[] = fetchedValues.filter((value) => value !== '') 46 | 47 | // And finally we have a list of author DIDs from the spreadsheet 48 | return nonEmptyValues 49 | 50 | } catch (error) { 51 | console.error('Error downloading CSV data:', error) 52 | return [] 53 | } 54 | } 55 | 56 | async function run() { 57 | await agent.login({ identifier: process.env.FEEDGEN_HANDLE, password: process.env.FEEDGEN_PASSWORD }) 58 | const authors = await downloadCSVData() 59 | if (authors.length > 0) { 60 | fs.writeFile('authors.json', JSON.stringify(authors), err => { 61 | if (err) { 62 | console.error('Error writing file:', err) 63 | } 64 | }) 65 | } 66 | } 67 | 68 | run() 69 | --------------------------------------------------------------------------------