Update NSID semantics to final ()

* Improve lex-cli to remove files that no longer exist

* Update lex-cli to use new ns

* Rename lexicons: todo.adx to com.atproto, todo.social to app.bsky

* Improve lex-cli md generator
This commit is contained in:
Paul Frazee 2022-10-12 14:32:18 -05:00 committed by GitHub
parent 7f2dfb8d50
commit 90cdb99bdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
180 changed files with 1510 additions and 1363 deletions
lexicons
packages

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.createAccount",
"id": "com.atproto.createAccount",
"type": "procedure",
"description": "Create an account.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.createInviteCode",
"id": "com.atproto.createInviteCode",
"type": "procedure",
"description": "Create an invite code.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.createSession",
"id": "com.atproto.createSession",
"type": "procedure",
"description": "Create an authentication session.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.deleteAccount",
"id": "com.atproto.deleteAccount",
"type": "procedure",
"description": "Delete an account.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.deleteSession",
"id": "com.atproto.deleteSession",
"type": "procedure",
"description": "Delete the current session.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.getAccount",
"id": "com.atproto.getAccount",
"type": "query",
"description": "Get information about an account.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.getAccountsConfig",
"id": "com.atproto.getAccountsConfig",
"type": "query",
"description": "Get a document describing the service's accounts configuration.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.getSession",
"id": "com.atproto.getSession",
"type": "query",
"description": "Get information about the current session.",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoBatchWrite",
"id": "com.atproto.repoBatchWrite",
"type": "procedure",
"description": "Apply a batch transaction of creates, puts, and deletes.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoCreateRecord",
"id": "com.atproto.repoCreateRecord",
"type": "procedure",
"description": "Create a new record.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoDeleteRecord",
"id": "com.atproto.repoDeleteRecord",
"type": "procedure",
"description": "Delete a record.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoDescribe",
"id": "com.atproto.repoDescribe",
"type": "query",
"description": "Get information about the repo, including the list of collections.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoGetRecord",
"id": "com.atproto.repoGetRecord",
"type": "query",
"description": "Fetch a record.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoListRecords",
"id": "com.atproto.repoListRecords",
"type": "query",
"description": "List a range of records in a collection.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.repoPutRecord",
"id": "com.atproto.repoPutRecord",
"type": "procedure",
"description": "Write a record.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.requestAccountPasswordReset",
"id": "com.atproto.requestAccountPasswordReset",
"type": "procedure",
"description": "Initiate a user account password reset via email",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.resetAccountPassword",
"id": "com.atproto.resetAccountPassword",
"type": "procedure",
"description": "Reset a user account password using a token",
"parameters": {},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.resolveName",
"id": "com.atproto.resolveName",
"type": "query",
"description": "Provides the DID of a repo.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.syncGetRepo",
"id": "com.atproto.syncGetRepo",
"type": "query",
"description": "Gets the repo state.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.syncGetRoot",
"id": "com.atproto.syncGetRoot",
"type": "query",
"description": "Gets the current root CID of a repo.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.adx.syncUpdateRepo",
"id": "com.atproto.syncUpdateRepo",
"type": "procedure",
"description": "Writes commits to a repo.",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.badge",
"id": "app.bsky.badge",
"type": "record",
"description": "An assertion about the subject by this user.",
"record": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.follow",
"id": "app.bsky.follow",
"type": "record",
"description": "A social follow",
"record": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getAuthorFeed",
"id": "app.bsky.getAuthorFeed",
"type": "query",
"description": "A view of a user's feed",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getHomeFeed",
"id": "app.bsky.getHomeFeed",
"type": "query",
"description": "A view of the user's home feed",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getLikedBy",
"id": "app.bsky.getLikedBy",
"type": "query",
"parameters": {
"uri": {"type": "string", "required": true},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getNotificationCount",
"id": "app.bsky.getNotificationCount",
"type": "query",
"parameters": { },
"output": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getNotifications",
"id": "app.bsky.getNotifications",
"type": "query",
"parameters": {
"limit": {"type": "number", "maximum": 100},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getPostThread",
"id": "app.bsky.getPostThread",
"type": "query",
"parameters": {
"uri": {"type": "string", "required": true},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getProfile",
"id": "app.bsky.getProfile",
"type": "query",
"parameters": {
"user": {"type": "string", "required": true}

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getRepostedBy",
"id": "app.bsky.getRepostedBy",
"type": "query",
"parameters": {
"uri": {"type": "string", "required": true},

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getUserFollowers",
"id": "app.bsky.getUserFollowers",
"type": "query",
"description": "Who is following a user?",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.getUserFollows",
"id": "app.bsky.getUserFollows",
"type": "query",
"description": "Who is a user following?",
"parameters": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.like",
"id": "app.bsky.like",
"type": "record",
"record": {
"type": "object",

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.mediaEmbed",
"id": "app.bsky.mediaEmbed",
"type": "record",
"description": "A list of media embedded in a post or document.",
"record": {

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.post",
"id": "app.bsky.post",
"type": "record",
"record": {
"type": "object",

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.postNotificationsSeen",
"id": "app.bsky.postNotificationsSeen",
"type": "procedure",
"description": "Notify server that the user has seen notifications",
"parameters": { },

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.profile",
"id": "app.bsky.profile",
"type": "record",
"record": {
"type": "object",

@ -1,6 +1,6 @@
{
"lexicon": 1,
"id": "todo.social.repost",
"id": "app.bsky.repost",
"type": "record",
"record": {
"type": "object",

@ -8,22 +8,22 @@ import API from '@adxp/api'
const client = API.service('http://example.com')
// xrpc methods
const res1 = await client.todo.adx.repoCreateRecord(
{did: alice.did, type: 'todo.social.post'},
const res1 = await client.com.atproto.repoCreateRecord(
{did: alice.did, type: 'app.bsky.post'},
{
$type: 'todo.social.post',
$type: 'app.bsky.post',
text: 'Hello, world!',
createdAt: (new Date()).toISOString()
}
)
const res2 = await client.todo.adx.repoListRecords({did: alice.did, type: 'todo.social.post'})
const res2 = await client.com.atproto.repoListRecords({did: alice.did, type: 'app.bsky.post'})
// repo record methods
const res3 = await client.todo.social.post.create({did: alice.did}, {
const res3 = await client.app.bsky.post.create({did: alice.did}, {
text: 'Hello, world!',
createdAt: (new Date()).toISOString()
})
const res4 = await client.todo.social.post.list({did: alice.did})
const res4 = await client.app.bsky.post.list({did: alice.did})
```
## License

@ -3,7 +3,7 @@
"version": "0.0.1",
"main": "src/index.ts",
"scripts": {
"codegen": "lex gen-api ./src ../../schemas/todo.adx/* ../../schemas/todo.social/*",
"codegen": "lex gen-api ./src ../../lexicons/atproto.com/* ../../lexicons/bsky.app/*",
"prettier": "prettier --check src/",
"prettier:fix": "prettier --write src/",
"lint": "eslint . --ext .ts,.tsx",

File diff suppressed because it is too large Load Diff

@ -6,7 +6,7 @@ import { MethodSchema, RecordSchema } from '@adxp/lexicon'
export const methodSchemas: MethodSchema[] = [
{
lexicon: 1,
id: 'todo.adx.createAccount',
id: 'com.atproto.createAccount',
type: 'procedure',
description: 'Create an account.',
parameters: {},
@ -66,7 +66,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.createInviteCode',
id: 'com.atproto.createInviteCode',
type: 'procedure',
description: 'Create an invite code.',
parameters: {},
@ -97,7 +97,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.createSession',
id: 'com.atproto.createSession',
type: 'procedure',
description: 'Create an authentication session.',
parameters: {},
@ -137,7 +137,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.deleteAccount',
id: 'com.atproto.deleteAccount',
type: 'procedure',
description: 'Delete an account.',
parameters: {},
@ -152,7 +152,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.deleteSession',
id: 'com.atproto.deleteSession',
type: 'procedure',
description: 'Delete the current session.',
parameters: {},
@ -167,7 +167,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.getAccount',
id: 'com.atproto.getAccount',
type: 'query',
description: 'Get information about an account.',
parameters: {},
@ -182,7 +182,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.getAccountsConfig',
id: 'com.atproto.getAccountsConfig',
type: 'query',
description:
"Get a document describing the service's accounts configuration.",
@ -208,7 +208,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.getSession',
id: 'com.atproto.getSession',
type: 'query',
description: 'Get information about the current session.',
parameters: {},
@ -230,7 +230,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoBatchWrite',
id: 'com.atproto.repoBatchWrite',
type: 'procedure',
description: 'Apply a batch transaction of creates, puts, and deletes.',
parameters: {
@ -315,7 +315,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoCreateRecord',
id: 'com.atproto.repoCreateRecord',
type: 'procedure',
description: 'Create a new record.',
parameters: {
@ -354,7 +354,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoDeleteRecord',
id: 'com.atproto.repoDeleteRecord',
type: 'procedure',
description: 'Delete a record.',
parameters: {
@ -377,7 +377,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoDescribe',
id: 'com.atproto.repoDescribe',
type: 'query',
description:
'Get information about the repo, including the list of collections.',
@ -418,7 +418,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoGetRecord',
id: 'com.atproto.repoGetRecord',
type: 'query',
description: 'Fetch a record.',
parameters: {
@ -456,7 +456,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoListRecords',
id: 'com.atproto.repoListRecords',
type: 'query',
description: 'List a range of records in a collection.',
parameters: {
@ -517,7 +517,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.repoPutRecord',
id: 'com.atproto.repoPutRecord',
type: 'procedure',
description: 'Write a record.',
parameters: {
@ -561,7 +561,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.requestAccountPasswordReset',
id: 'com.atproto.requestAccountPasswordReset',
type: 'procedure',
description: 'Initiate a user account password reset via email',
parameters: {},
@ -587,7 +587,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.resetAccountPassword',
id: 'com.atproto.resetAccountPassword',
type: 'procedure',
description: 'Reset a user account password using a token',
parameters: {},
@ -624,7 +624,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.resolveName',
id: 'com.atproto.resolveName',
type: 'query',
description: 'Provides the DID of a repo.',
parameters: {
@ -649,7 +649,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.syncGetRepo',
id: 'com.atproto.syncGetRepo',
type: 'query',
description: 'Gets the repo state.',
parameters: {
@ -669,7 +669,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.syncGetRoot',
id: 'com.atproto.syncGetRoot',
type: 'query',
description: 'Gets the current root CID of a repo.',
parameters: {
@ -694,7 +694,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.adx.syncUpdateRepo',
id: 'com.atproto.syncUpdateRepo',
type: 'procedure',
description: 'Writes commits to a repo.',
parameters: {
@ -710,7 +710,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getAuthorFeed',
id: 'app.bsky.getAuthorFeed',
type: 'query',
description: "A view of a user's feed",
parameters: {
@ -877,7 +877,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getHomeFeed',
id: 'app.bsky.getHomeFeed',
type: 'query',
description: "A view of the user's home feed",
parameters: {
@ -1043,7 +1043,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getLikedBy',
id: 'app.bsky.getLikedBy',
type: 'query',
parameters: {
uri: {
@ -1100,7 +1100,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getNotificationCount',
id: 'app.bsky.getNotificationCount',
type: 'query',
parameters: {},
output: {
@ -1118,7 +1118,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getNotifications',
id: 'app.bsky.getNotifications',
type: 'query',
parameters: {
limit: {
@ -1200,7 +1200,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getPostThread',
id: 'app.bsky.getPostThread',
type: 'query',
parameters: {
uri: {
@ -1361,7 +1361,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getProfile',
id: 'app.bsky.getProfile',
type: 'query',
parameters: {
user: {
@ -1468,7 +1468,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getRepostedBy',
id: 'app.bsky.getRepostedBy',
type: 'query',
parameters: {
uri: {
@ -1525,7 +1525,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getUserFollowers',
id: 'app.bsky.getUserFollowers',
type: 'query',
description: 'Who is following a user?',
parameters: {
@ -1596,7 +1596,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.getUserFollows',
id: 'app.bsky.getUserFollows',
type: 'query',
description: 'Who is a user following?',
parameters: {
@ -1667,7 +1667,7 @@ export const methodSchemas: MethodSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.postNotificationsSeen',
id: 'app.bsky.postNotificationsSeen',
type: 'procedure',
description: 'Notify server that the user has seen notifications',
parameters: {},
@ -1693,7 +1693,7 @@ export const methodSchemas: MethodSchema[] = [
export const recordSchemas: RecordSchema[] = [
{
lexicon: 1,
id: 'todo.social.badge',
id: 'app.bsky.badge',
type: 'record',
description: 'An assertion about the subject by this user.',
record: {
@ -1773,7 +1773,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.follow',
id: 'app.bsky.follow',
type: 'record',
description: 'A social follow',
record: {
@ -1792,7 +1792,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.like',
id: 'app.bsky.like',
type: 'record',
record: {
type: 'object',
@ -1810,7 +1810,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.mediaEmbed',
id: 'app.bsky.mediaEmbed',
type: 'record',
description: 'A list of media embedded in a post or document.',
record: {
@ -1857,7 +1857,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.post',
id: 'app.bsky.post',
type: 'record',
record: {
type: 'object',
@ -1926,7 +1926,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.profile',
id: 'app.bsky.profile',
type: 'record',
record: {
type: 'object',
@ -1962,7 +1962,7 @@ export const recordSchemas: RecordSchema[] = [
},
{
lexicon: 1,
id: 'todo.social.repost',
id: 'app.bsky.repost',
type: 'record',
record: {
type: 'object',

@ -1,68 +0,0 @@
/**
* GENERATED CODE - DO NOT MODIFY
*/
import { Headers, XRPCError } from '@adxp/xrpc'
export interface QueryParams {
author?: string;
limit?: number;
before?: string;
}
export interface CallOptions {
headers?: Headers;
}
export type InputSchema = undefined
export interface OutputSchema {
feed: FeedItem[];
}
export interface FeedItem {
cursor?: string;
uri: string;
author: User;
repostedBy?: User;
record: {};
embed?: RecordEmbed | ExternalEmbed | UnknownEmbed;
replyCount: number;
repostCount: number;
likeCount: number;
indexedAt: string;
myState?: {
repost?: string,
like?: string,
};
}
export interface User {
did: string;
name: string;
displayName?: string;
}
export interface RecordEmbed {
type: 'record';
author: User;
record: {};
}
export interface ExternalEmbed {
type: 'external';
uri: string;
title: string;
description: string;
imageUri: string;
}
export interface UnknownEmbed {
type: string;
}
export interface Response {
success: boolean;
headers: Headers;
data: OutputSchema;
}
export function toKnownErr(e: any) {
if (e instanceof XRPCError) {
}
return e
}

@ -88,7 +88,7 @@ const envApi = {
// create the PDS account
const client = pds.getClient()
const pdsRes = await client.todo.adx.createAccount(
const pdsRes = await client.com.atproto.createAccount(
{},
{
email: usernameNoTld + '@test.com',

@ -80,13 +80,13 @@ export async function generateMockSetup(env: DevEnv) {
let _i = 1
for (const user of users) {
const res = await clients.loggedout.todo.adx.createAccount(
const res = await clients.loggedout.com.atproto.createAccount(
{},
{ email: user.email, username: user.username, password: user.password },
)
user.did = res.data.did
user.api.setHeader('Authorization', `Bearer ${res.data.jwt}`)
await user.api.todo.social.profile.create(
await user.api.app.bsky.profile.create(
{ did: user.did },
{
displayName: ucfirst(user.username).slice(0, -5),
@ -97,7 +97,7 @@ export async function generateMockSetup(env: DevEnv) {
// everybody follows everybody
const follow = async (author: User, subject: string) => {
await author.api.todo.social.follow.create(
await author.api.app.bsky.follow.create(
{ did: author.did },
{
subject,
@ -117,7 +117,7 @@ export async function generateMockSetup(env: DevEnv) {
for (let i = 0; i < postTexts.length; i++) {
const author = picka(users)
posts.push(
await author.api.todo.social.post.create(
await author.api.app.bsky.post.create(
{ did: author.did },
{
text: postTexts[i],
@ -127,7 +127,7 @@ export async function generateMockSetup(env: DevEnv) {
)
if (rand(10) === 0) {
const reposter = picka(users)
await reposter.api.todo.social.repost.create(
await reposter.api.app.bsky.repost.create(
{ did: reposter.did },
{
subject: picka(posts).uri,
@ -141,13 +141,13 @@ export async function generateMockSetup(env: DevEnv) {
for (let i = 0; i < 100; i++) {
const targetUri = picka(posts).uri
const urip = new AdxUri(targetUri)
const target = await alice.api.todo.social.post.get({
const target = await alice.api.app.bsky.post.get({
nameOrDid: urip.host,
tid: urip.recordKey,
})
const author = picka(users)
posts.push(
await author.api.todo.social.post.create(
await author.api.app.bsky.post.create(
{ did: author.did },
{
text: picka(replyTexts),
@ -165,7 +165,7 @@ export async function generateMockSetup(env: DevEnv) {
for (const post of posts) {
for (const user of users) {
if (rand(3) === 0) {
await user.api.todo.social.like.create(
await user.api.app.bsky.like.create(
{ did: user.did },
{
subject: post.uri,

@ -21,6 +21,7 @@
"@adxp/nsid": "*",
"ajv": "^8.11.0",
"ajv-formats": "^2.1.1",
"chalk": "^5.1.1",
"commander": "^9.4.0",
"json-schema-to-typescript": "^11.0.2",
"ts-morph": "^16.0.0",

@ -11,12 +11,12 @@ import { gen, schemasTs } from './common'
import { GeneratedAPI } from '../types'
import { schemasToNsidTree, NsidNS, toCamelCase, toTitleCase } from './util'
const ADX_METHODS = {
list: 'todo.adx.repoListRecords',
get: 'todo.adx.repoGetRecord',
create: 'todo.adx.repoCreateRecord',
put: 'todo.adx.repoPutRecord',
delete: 'todo.adx.repoDeleteRecord',
const ATP_METHODS = {
list: 'com.atproto.repoListRecords',
get: 'com.atproto.repoGetRecord',
create: 'com.atproto.repoCreateRecord',
put: 'com.atproto.repoPutRecord',
delete: 'com.atproto.repoDeleteRecord',
}
export async function genClientApi(schemas: Schema[]): Promise<GeneratedAPI> {
@ -310,11 +310,11 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
})
method.addParameter({
name: 'params',
type: `Omit<${toTitleCase(ADX_METHODS.list)}.QueryParams, "type">`,
type: `Omit<${toTitleCase(ATP_METHODS.list)}.QueryParams, "type">`,
})
method.setBodyText(
[
`const res = await this._service.xrpc.call('${ADX_METHODS.list}', { type: '${schema.id}', ...params })`,
`const res = await this._service.xrpc.call('${ATP_METHODS.list}', { type: '${schema.id}', ...params })`,
`return res.data`,
].join('\n'),
)
@ -328,11 +328,11 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
})
method.addParameter({
name: 'params',
type: `Omit<${toTitleCase(ADX_METHODS.get)}.QueryParams, "type">`,
type: `Omit<${toTitleCase(ATP_METHODS.get)}.QueryParams, "type">`,
})
method.setBodyText(
[
`const res = await this._service.xrpc.call('${ADX_METHODS.get}', { type: '${schema.id}', ...params })`,
`const res = await this._service.xrpc.call('${ATP_METHODS.get}', { type: '${schema.id}', ...params })`,
`return res.data`,
].join('\n'),
)
@ -346,7 +346,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
})
method.addParameter({
name: 'params',
type: `Omit<${toTitleCase(ADX_METHODS.create)}.QueryParams, "type">`,
type: `Omit<${toTitleCase(ATP_METHODS.create)}.QueryParams, "type">`,
})
method.addParameter({
name: 'record',
@ -359,7 +359,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
method.setBodyText(
[
`record.$type = '${schema.id}'`,
`const res = await this._service.xrpc.call('${ADX_METHODS.create}', { type: '${schema.id}', ...params }, record, {encoding: 'application/json', headers })`,
`const res = await this._service.xrpc.call('${ATP_METHODS.create}', { type: '${schema.id}', ...params }, record, {encoding: 'application/json', headers })`,
`return res.data`,
].join('\n'),
)
@ -373,7 +373,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
})
method.addParameter({
name: 'params',
type: `Omit<${toTitleCase(ADX_METHODS.put)}.QueryParams, "type">`,
type: `Omit<${toTitleCase(ATP_METHODS.put)}.QueryParams, "type">`,
})
method.addParameter({
name: 'record',
@ -386,7 +386,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
method.setBodyText(
[
`record.$type = '${schema.id}'`,
`const res = await this._service.xrpc.call('${ADX_METHODS.put}', { type: '${schema.id}', ...params }, record, {encoding: 'application/json', headers})`,
`const res = await this._service.xrpc.call('${ATP_METHODS.put}', { type: '${schema.id}', ...params }, record, {encoding: 'application/json', headers})`,
`return res.data`,
].join('\n'),
)
@ -400,7 +400,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
})
method.addParameter({
name: 'params',
type: `Omit<${toTitleCase(ADX_METHODS.delete)}.QueryParams, "type">`,
type: `Omit<${toTitleCase(ATP_METHODS.delete)}.QueryParams, "type">`,
})
method.addParameter({
name: 'headers?',
@ -409,7 +409,7 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
method.setBodyText(
[
`await this._service.xrpc.call('${ADX_METHODS.delete}', { type: '${schema.id}', ...params }, undefined, { headers })`,
`await this._service.xrpc.call('${ATP_METHODS.delete}', { type: '${schema.id}', ...params }, undefined, { headers })`,
].join('\n'),
)
}

@ -5,7 +5,15 @@ import fs from 'fs'
import { Command, InvalidArgumentError } from 'commander'
import yesno from 'yesno'
import { NSID } from '@adxp/nsid'
import { schemaTemplate, readAllSchemas, genMd, genTsObj } from './util'
import {
schemaTemplate,
readAllSchemas,
genTsObj,
genFileDiff,
printFileDiff,
applyFileDiff,
} from './util'
import * as mdGen from './mdgen'
import { genClientApi } from './codegen/client'
import { genServerApi } from './codegen/server'
@ -38,10 +46,24 @@ program
program
.command('gen-md')
.description('Generate markdown documentation')
.argument('<outfile>', 'path of the file to write to', toPath)
.argument('<schemas...>', 'paths of the schema files to include', toPaths)
.action((schemaPaths: string[]) => {
.action(async (outFilePath: string, schemaPaths: string[]) => {
if (!outFilePath.endsWith('.md')) {
console.error('Must supply the path to a .md file as the first parameter')
process.exit(1)
}
console.log('Writing', outFilePath)
const ok = await yesno({
question: 'Are you sure you want to continue? [y/N]',
defaultValue: false,
})
if (!ok) {
console.log('Aborted.')
process.exit(0)
}
const schemas = readAllSchemas(schemaPaths)
console.log(genMd(schemas))
await mdGen.process(outFilePath, schemas)
})
program
@ -61,11 +83,9 @@ program
.action(async (outDir: string, schemaPaths: string[]) => {
const schemas = readAllSchemas(schemaPaths)
const api = await genClientApi(schemas)
const diff = genFileDiff(outDir, api)
console.log('This will write the following files:')
for (const file of api.files) {
file.path = path.join(outDir, file.path)
console.log('-', file.path)
}
printFileDiff(diff)
const ok = await yesno({
question: 'Are you sure you want to continue? [y/N]',
defaultValue: false,
@ -74,10 +94,7 @@ program
console.log('Aborted.')
process.exit(0)
}
for (const file of api.files) {
fs.mkdirSync(path.join(file.path, '..'), { recursive: true })
fs.writeFileSync(file.path, file.content, 'utf8')
}
applyFileDiff(diff)
console.log('API generated.')
})
@ -89,11 +106,9 @@ program
.action(async (outDir: string, schemaPaths: string[]) => {
const schemas = readAllSchemas(schemaPaths)
const api = await genServerApi(schemas)
const diff = genFileDiff(outDir, api)
console.log('This will write the following files:')
for (const file of api.files) {
file.path = path.join(outDir, file.path)
console.log('-', file.path)
}
printFileDiff(diff)
const ok = await yesno({
question: 'Are you sure you want to continue? [y/N]',
defaultValue: false,
@ -102,10 +117,7 @@ program
console.log('Aborted.')
process.exit(0)
}
for (const file of api.files) {
fs.mkdirSync(path.join(file.path, '..'), { recursive: true })
fs.writeFileSync(file.path, file.content, 'utf8')
}
applyFileDiff(diff)
console.log('API generated.')
})

@ -0,0 +1,213 @@
import fs from 'fs'
import {
methodSchema,
MethodSchema,
recordSchema,
RecordSchema,
Schema,
} from '@adxp/lexicon'
import * as jsonSchemaToTs from 'json-schema-to-typescript'
const INSERT_START = [
'<!-- START lex generated content. Please keep comment here to allow auto update -->',
"<!-- DON'T EDIT THIS SECTION! INSTEAD RE-RUN lex TO UPDATE -->",
]
const INSERT_END = [
'<!-- END lex generated TOC please keep comment here to allow auto update -->',
]
export async function process(outFilePath: string, schemas: Schema[]) {
let existingContent = ''
try {
existingContent = fs.readFileSync(outFilePath, 'utf8')
} catch (e) {
// ignore - no existing content
}
let fileLines: StringTree = existingContent.split('\n')
// find previously generated content
let startIndex = fileLines.findIndex((line) => matchesStart(line))
let endIndex = fileLines.findIndex((line) => matchesEnd(line))
if (startIndex === -1) {
startIndex = fileLines.length
}
if (endIndex === -1) {
endIndex = fileLines.length
}
// generate & insert content
fileLines.splice(startIndex, endIndex - startIndex + 1, [
INSERT_START,
await genMdLines(schemas),
INSERT_END,
])
fs.writeFileSync(outFilePath, merge(fileLines), 'utf8')
}
async function genMdLines(schemas: Schema[]): Promise<StringTree> {
let xprcMethods: StringTree = []
let recordTypes: StringTree = []
for (const schema of schemas) {
if (methodSchema.safeParse(schema).success) {
xprcMethods = xprcMethods.concat(
await genMethodSchemaMd(schema as MethodSchema),
)
} else if (recordSchema.safeParse(schema).success) {
recordTypes = recordTypes.concat(
await genRecordSchemaMd(schema as RecordSchema),
)
}
}
let doc = [
recordTypes?.length ? recordTypes : undefined,
xprcMethods?.length ? xprcMethods : undefined,
]
return doc
}
async function genMethodSchemaMd(schema: MethodSchema): Promise<StringTree> {
const desc: StringTree = []
const params: StringTree = []
const input: StringTree = []
const output: StringTree = []
const doc: StringTree = [
`---`,
``,
`## ${schema.id}`,
'',
desc,
params,
input,
output,
]
desc.push(`<mark>RPC ${schema.type}</mark> ${schema.description || ''}`, ``)
if (schema.parameters && Object.keys(schema.parameters).length) {
params.push(`Parameters:`, ``)
for (const [k, desc] of Object.entries(schema.parameters)) {
const param: string[] = []
param.push(`- \`${k}\``)
param.push(desc.required ? `Required` : `Optional`)
param.push(`${desc.type}.`)
if (desc.description) {
param.push(desc.description)
}
if (desc.type === 'string') {
if (typeof desc.maxLength !== 'undefined') {
param.push(`Max length ${desc.maxLength}.`)
}
if (typeof desc.minLength !== 'undefined') {
param.push(`Min length ${desc.minLength}.`)
}
} else if (desc.type === 'number' || desc.type === 'integer') {
if (typeof desc.maximum !== 'undefined') {
param.push(`Max value ${desc.maximum}.`)
}
if (typeof desc.minimum !== 'undefined') {
param.push(`Min value ${desc.minimum}.`)
}
}
if (typeof desc.default !== 'undefined') {
param.push(`Defaults to ${desc.default}.`)
}
params.push(param.join(' '))
}
}
params.push('')
if (schema.input) {
input.push(`Input:`, ``)
if (schema.input.encoding) {
if (typeof schema.input.encoding === 'string') {
input.push(`- Encoding: ${schema.input.encoding}`)
} else if (Array.isArray(schema.input.encoding)) {
input.push(`- Possible encodings: ${schema.input.encoding.join(', ')}`)
}
}
if (schema.input.schema) {
input.push(`- Schema:`, ``)
input.push('```typescript')
input.push(
(
await jsonSchemaToTs.compile(schema.input.schema, 'InputBody', {
bannerComment: '',
additionalProperties: false,
})
).trim(),
)
input.push('```')
}
input.push('')
}
if (schema.output) {
output.push(`Output:`, ``)
if (schema.output.encoding) {
if (typeof schema.output.encoding === 'string') {
output.push(`- Encoding: ${schema.output.encoding}`)
} else if (Array.isArray(schema.output.encoding)) {
output.push(
`- Possible encodings: ${schema.output.encoding.join(', ')}`,
)
}
}
if (schema.output.schema) {
output.push(`- Schema:`, ``)
output.push('```typescript')
output.push(
(
await jsonSchemaToTs.compile(schema.output.schema, 'OutputBody', {
bannerComment: '',
additionalProperties: false,
})
).trim(),
)
output.push('```')
}
output.push('')
}
return doc
}
async function genRecordSchemaMd(schema: RecordSchema): Promise<StringTree> {
const desc: StringTree = []
const record: StringTree = []
const doc: StringTree = [`---`, ``, `## ${schema.id}`, '', desc, record]
desc.push(`<mark>Record type</mark> ${schema.description || ''}`, ``)
if (schema.record) {
record.push('```typescript')
record.push(
(
await jsonSchemaToTs.compile(schema.record, 'Record', {
bannerComment: '',
additionalProperties: false,
})
).trim(),
)
record.push('```')
record.push('')
}
return doc
}
type StringTree = (StringTree | string | undefined)[]
function merge(arr: StringTree): string {
return arr
.flat(10)
.filter((v) => typeof v === 'string')
.join('\n')
}
function matchesStart(line) {
return /<!-- START lex /.test(line)
}
function matchesEnd(line) {
return /<!-- END lex /.test(line)
}

@ -6,3 +6,9 @@ export interface GeneratedFile {
export interface GeneratedAPI {
files: GeneratedFile[]
}
export interface FileDiff {
act: 'add' | 'mod' | 'del'
path: string
content?: string
}

@ -1,5 +1,8 @@
import fs from 'fs'
import { methodSchema, MethodSchema, recordSchema, Schema } from '@adxp/lexicon'
import { join } from 'path'
import { methodSchema, recordSchema, Schema } from '@adxp/lexicon'
import chalk from 'chalk'
import { GeneratedAPI, FileDiff } from './types'
export function schemaTemplate(nsid: string, options?: Record<string, string>) {
return {
@ -69,109 +72,78 @@ export function readSchema(path: string): Schema {
}
}
export function genMd(schemas: Schema[]) {
let doc: StringTree = []
for (const schema of schemas) {
if (methodSchema.parse(schema)) {
doc = doc.concat(genMethodSchemaMd(schema as MethodSchema))
} else if (recordSchema.parse(schema)) {
// TODO
}
}
return merge(doc)
}
export function genMethodSchemaMd(schema: MethodSchema): StringTree {
const desc: StringTree = []
const params: StringTree = []
const input: StringTree = []
const output: StringTree = []
const doc: StringTree = [`## ${schema.id}`, '', desc, params, input, output]
desc.push(`(${schema.type}) ${schema.description || ''}`, ``)
if (schema.parameters && Object.keys(schema.parameters).length) {
params.push(`Parameters:`, ``)
for (const [k, desc] of Object.entries(schema.parameters)) {
const param: string[] = []
param.push(`- \`${k}\``)
param.push(desc.required ? `Required` : `Optional`)
param.push(`${desc.type}.`)
if (desc.description) {
param.push(desc.description)
}
if (desc.type === 'string') {
if (typeof desc.maxLength !== 'undefined') {
param.push(`Max length ${desc.maxLength}.`)
}
if (typeof desc.minLength !== 'undefined') {
param.push(`Min length ${desc.minLength}.`)
}
} else if (desc.type === 'number' || desc.type === 'integer') {
if (typeof desc.maximum !== 'undefined') {
param.push(`Max value ${desc.maximum}.`)
}
if (typeof desc.minimum !== 'undefined') {
param.push(`Min value ${desc.minimum}.`)
}
}
if (typeof desc.default !== 'undefined') {
param.push(`Defaults to ${desc.default}.`)
}
params.push(param.join(' '))
}
}
params.push('')
if (schema.input) {
input.push(`Input:`, ``)
if (schema.input.encoding) {
if (typeof schema.input.encoding === 'string') {
input.push(`- Encoding: ${schema.input.encoding}`)
} else if (Array.isArray(schema.input.encoding)) {
input.push(`- Possible encodings: ${schema.input.encoding.join(', ')}`)
}
}
if (schema.input.schema) {
input.push(`- Schema:`, ``)
input.push('```json')
input.push(JSON.stringify(schema.input.schema, null, 2))
input.push('```')
}
input.push('')
}
if (schema.output) {
output.push(`Output:`, ``)
if (schema.output.encoding) {
if (typeof schema.output.encoding === 'string') {
output.push(`- Encoding: ${schema.output.encoding}`)
} else if (Array.isArray(schema.output.encoding)) {
output.push(
`- Possible encodings: ${schema.output.encoding.join(', ')}`,
)
}
}
if (schema.output.schema) {
output.push(`- Schema:`, ``)
output.push('```json')
output.push(JSON.stringify(schema.output.schema, null, 2))
output.push('```')
}
output.push('')
}
return doc
}
export function genTsObj(schemas: Schema[]): string {
return `export const schemas = ${JSON.stringify(schemas, null, 2)}`
}
type StringTree = (StringTree | string | undefined)[]
function merge(arr: StringTree): string {
return arr
.flat(10)
.filter((v) => typeof v === 'string')
.join('\n')
export function genFileDiff(outDir: string, api: GeneratedAPI) {
const diffs: FileDiff[] = []
const existingFiles = readdirRecursiveSync(outDir)
for (const file of api.files) {
file.path = join(outDir, file.path)
if (existingFiles.includes(file.path)) {
diffs.push({ act: 'mod', path: file.path, content: file.content })
} else {
diffs.push({ act: 'add', path: file.path, content: file.content })
}
}
for (const filepath of existingFiles) {
if (api.files.find((f) => f.path === filepath)) {
// do nothing
} else {
diffs.push({ act: 'del', path: filepath })
}
}
return diffs
}
export function printFileDiff(diff: FileDiff[]) {
for (const d of diff) {
switch (d.act) {
case 'add':
console.log(`${chalk.greenBright('[+ add]')} ${d.path}`)
break
case 'mod':
console.log(`${chalk.yellowBright('[* mod]')} ${d.path}`)
break
case 'del':
console.log(`${chalk.redBright('[- del]')} ${d.path}`)
break
}
}
}
export function applyFileDiff(diff: FileDiff[]) {
for (const d of diff) {
switch (d.act) {
case 'add':
case 'mod':
fs.mkdirSync(join(d.path, '..'), { recursive: true }) // lazy way to make sure the parent dir exists
fs.writeFileSync(d.path, d.content || '', 'utf8')
break
case 'del':
fs.unlinkSync(d.path)
break
}
}
}
function readdirRecursiveSync(
root: string,
files: string[] = [],
prefix: string = '',
) {
var dir = join(root, prefix)
if (!fs.existsSync(dir)) return files
if (fs.statSync(dir).isDirectory())
fs.readdirSync(dir).forEach(function (name) {
readdirRecursiveSync(root, files, join(prefix, name))
})
else if (prefix.endsWith('.ts')) {
files.push(join(root, prefix))
}
return files
}

@ -4,7 +4,7 @@
"main": "src/index.ts",
"bin": "dist/bin.ts",
"scripts": {
"codegen": "lex gen-server ./src/lexicon ../../schemas/todo.adx/* ../../schemas/todo.social/*",
"codegen": "lex gen-server ./src/lexicon ../../lexicons/atproto.com/* ../../lexicons/bsky.app/*",
"build": "node ./build.js",
"start": "node dist/bin.js",
"test": "jest",

@ -1,6 +1,6 @@
import { AuthRequiredError } from '@adxp/xrpc-server'
import { Server } from '../../../lexicon'
import * as GetAuthorFeed from '../../../lexicon/types/todo/social/getAuthorFeed'
import * as GetAuthorFeed from '../../../lexicon/types/app/bsky/getAuthorFeed'
import * as locals from '../../../locals'
import { queryResultToFeedItem } from './util'
import {
@ -11,7 +11,7 @@ import {
} from '../../../db/util'
export default function (server: Server) {
server.todo.social.getAuthorFeed(
server.app.bsky.getAuthorFeed(
async (params: GetAuthorFeed.QueryParams, _input, req, res) => {
const { author, limit, before } = params
@ -26,9 +26,9 @@ export default function (server: Server) {
// @TODO break this query up, share parts with home feed and post thread
let builder = db.db
.selectFrom('todo_social_post as post')
.selectFrom('app_bsky_post as post')
// Determine result set of posts and reposts
.leftJoin('todo_social_repost as repost', 'repost.subject', 'post.uri')
.leftJoin('app_bsky_repost as repost', 'repost.subject', 'post.uri')
.leftJoin('user as originator', (join) =>
join
.onRef('originator.did', '=', 'post.creator')
@ -39,13 +39,13 @@ export default function (server: Server) {
// Select data for presentation into FeedItem
.leftJoin('user as author', 'author.did', 'post.creator')
.leftJoin(
'todo_social_profile as author_profile',
'app_bsky_profile as author_profile',
'author_profile.creator',
'author.did',
)
.leftJoin('user as reposted_by', 'reposted_by.did', 'repost.creator')
.leftJoin(
'todo_social_profile as reposted_by_profile',
'app_bsky_profile as reposted_by_profile',
'reposted_by_profile.creator',
'reposted_by.did',
)
@ -63,28 +63,28 @@ export default function (server: Server) {
isNotRepostClause.as('isNotRepost'),
postOrRepostIndexedAtClause.as('cursor'),
db.db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.whereRef('subject', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('likeCount'),
db.db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.whereRef('subject', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('repostCount'),
db.db
.selectFrom('todo_social_post')
.selectFrom('app_bsky_post')
.whereRef('replyParent', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('replyCount'),
db.db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))
.select('uri')
.as('requesterRepost'),
db.db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))
.select('uri')

@ -1,7 +1,7 @@
import { sql } from 'kysely'
import { AuthRequiredError, InvalidRequestError } from '@adxp/xrpc-server'
import { Server } from '../../../lexicon'
import * as GetHomeFeed from '../../../lexicon/types/todo/social/getHomeFeed'
import * as GetHomeFeed from '../../../lexicon/types/app/bsky/getHomeFeed'
import * as locals from '../../../locals'
import { FeedAlgorithm, isEnum, queryResultToFeedItem } from './util'
import {
@ -12,7 +12,7 @@ import {
} from '../../../db/util'
export default function (server: Server) {
server.todo.social.getHomeFeed(
server.app.bsky.getHomeFeed(
async (params: GetHomeFeed.QueryParams, _input, req, res) => {
const { algorithm, limit, before } = params
@ -35,9 +35,9 @@ export default function (server: Server) {
// @TODO break this query up, share parts with author feed and post thread
let builder = db.db
.selectFrom('todo_social_post as post')
.selectFrom('app_bsky_post as post')
// Determine result set of posts and reposts
.leftJoin('todo_social_repost as repost', 'repost.subject', 'post.uri')
.leftJoin('app_bsky_repost as repost', 'repost.subject', 'post.uri')
.leftJoin('user as originator', (join) =>
join
.onRef('originator.did', '=', 'post.creator')
@ -51,7 +51,7 @@ export default function (server: Server) {
})
.if(feedAlgorithm === FeedAlgorithm.ReverseChronological, (qb) => {
const followingIdsSubquery = db.db
.selectFrom('todo_social_follow as follow')
.selectFrom('app_bsky_follow as follow')
.select('follow.subject')
.where('follow.creator', '=', requester)
return qb
@ -67,13 +67,13 @@ export default function (server: Server) {
// Select data for presentation into FeedItem
.leftJoin('user as author', 'author.did', 'post.creator')
.leftJoin(
'todo_social_profile as author_profile',
'app_bsky_profile as author_profile',
'author_profile.creator',
'author.did',
)
.leftJoin('user as reposted_by', 'reposted_by.did', 'repost.creator')
.leftJoin(
'todo_social_profile as reposted_by_profile',
'app_bsky_profile as reposted_by_profile',
'reposted_by_profile.creator',
'reposted_by.did',
)
@ -91,28 +91,28 @@ export default function (server: Server) {
isNotRepostClause.as('isNotRepost'),
postOrRepostIndexedAtClause.as('cursor'),
db.db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.whereRef('subject', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('likeCount'),
db.db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.whereRef('subject', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('repostCount'),
db.db
.selectFrom('todo_social_post')
.selectFrom('app_bsky_post')
.whereRef('replyParent', '=', ref('post.uri'))
.select(countClause.as('count'))
.as('replyCount'),
db.db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))
.select('uri')
.as('requesterRepost'),
db.db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))
.select('uri')

@ -1,25 +1,21 @@
import { Server } from '../../../lexicon'
import * as GetLikedBy from '../../../lexicon/types/todo/social/getLikedBy'
import * as GetLikedBy from '../../../lexicon/types/app/bsky/getLikedBy'
import * as locals from '../../../locals'
import { paginate } from '../../../db/util'
import { sql } from 'kysely'
export default function (server: Server) {
server.todo.social.getLikedBy(
server.app.bsky.getLikedBy(
async (params: GetLikedBy.QueryParams, _input, _req, res) => {
const { uri, limit, before } = params
const { db } = locals.get(res)
let builder = db.db
.selectFrom('todo_social_like as like')
.selectFrom('app_bsky_like as like')
.where('like.subject', '=', uri)
.innerJoin('record', 'like.uri', 'record.uri')
.innerJoin('user', 'like.creator', 'user.did')
.leftJoin(
'todo_social_profile as profile',
'profile.creator',
'user.did',
)
.leftJoin('app_bsky_profile as profile', 'profile.creator', 'user.did')
.select([
'user.did as did',
'user.username as name',

@ -1,11 +1,11 @@
import { Server } from '../../../lexicon'
import { AuthRequiredError } from '@adxp/xrpc-server'
import * as GetNotificationCount from '../../../lexicon/types/todo/social/getNotificationCount'
import * as GetNotificationCount from '../../../lexicon/types/app/bsky/getNotificationCount'
import * as locals from '../../../locals'
import { countClause } from '../../../db/util'
export default function (server: Server) {
server.todo.social.getNotificationCount(
server.app.bsky.getNotificationCount(
async (params: GetNotificationCount.QueryParams, _input, req, res) => {
const { auth, db } = locals.get(res)
const requester = auth.getUserDid(req)

@ -1,12 +1,12 @@
import { sql } from 'kysely'
import { Server } from '../../../lexicon'
import { AuthRequiredError, InvalidRequestError } from '@adxp/xrpc-server'
import * as GetNotifications from '../../../lexicon/types/todo/social/getNotifications'
import * as GetNotifications from '../../../lexicon/types/app/bsky/getNotifications'
import * as locals from '../../../locals'
import { paginate } from '../../../db/util'
export default function (server: Server) {
server.todo.social.getNotifications(
server.app.bsky.getNotifications(
async (params: GetNotifications.QueryParams, _input, req, res) => {
const { limit, before } = params
@ -22,7 +22,7 @@ export default function (server: Server) {
.innerJoin('record', 'record.uri', 'notif.recordUri')
.innerJoin('user as author', 'author.did', 'notif.author')
.leftJoin(
'todo_social_profile as author_profile',
'app_bsky_profile as author_profile',
'author_profile.creator',
'author.did',
)

@ -1,13 +1,13 @@
import { Kysely } from 'kysely'
import { AuthRequiredError, InvalidRequestError } from '@adxp/xrpc-server'
import { Server } from '../../../lexicon'
import * as GetPostThread from '../../../lexicon/types/todo/social/getPostThread'
import * as GetPostThread from '../../../lexicon/types/app/bsky/getPostThread'
import * as locals from '../../../locals'
import { DatabaseSchema } from '../../../db/database-schema'
import { countClause } from '../../../db/util'
export default function (server: Server) {
server.todo.social.getPostThread(
server.app.bsky.getPostThread(
async (params: GetPostThread.QueryParams, _input, req, res) => {
const { uri, depth = 6 } = params
const { auth, db } = locals.get(res)
@ -71,11 +71,11 @@ const getReplies = async (
const postInfoBuilder = (db: Kysely<DatabaseSchema>, requester: string) => {
const { ref } = db.dynamic
return db
.selectFrom('todo_social_post as post')
.selectFrom('app_bsky_post as post')
.innerJoin('record', 'record.uri', 'post.uri')
.innerJoin('user as author', 'author.did', 'post.creator')
.leftJoin(
'todo_social_profile as author_profile',
'app_bsky_profile as author_profile',
'author.did',
'author_profile.creator',
)
@ -88,28 +88,28 @@ const postInfoBuilder = (db: Kysely<DatabaseSchema>, requester: string) => {
'record.raw as rawRecord',
'record.indexedAt as indexedAt',
db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.select(countClause.as('count'))
.whereRef('subject', '=', ref('post.uri'))
.as('likeCount'),
db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.select(countClause.as('count'))
.whereRef('subject', '=', ref('post.uri'))
.as('repostCount'),
db
.selectFrom('todo_social_post')
.selectFrom('app_bsky_post')
.select(countClause.as('count'))
.whereRef('replyParent', '=', ref('post.uri'))
.as('replyCount'),
db
.selectFrom('todo_social_repost')
.selectFrom('app_bsky_repost')
.select('uri')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))
.as('requesterRepost'),
db
.selectFrom('todo_social_like')
.selectFrom('app_bsky_like')
.select('uri')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('post.uri'))

@ -1,11 +1,11 @@
import { Server } from '../../../lexicon'
import { InvalidRequestError, AuthRequiredError } from '@adxp/xrpc-server'
import * as GetProfile from '../../../lexicon/types/todo/social/getProfile'
import * as GetProfile from '../../../lexicon/types/app/bsky/getProfile'
import { countClause, userWhereClause } from '../../../db/util'
import * as locals from '../../../locals'
export default function (server: Server) {
server.todo.social.getProfile(
server.app.bsky.getProfile(
async (params: GetProfile.QueryParams, _input, req, res) => {
const { user } = params
const { auth, db } = locals.get(res)
@ -20,33 +20,29 @@ export default function (server: Server) {
const queryRes = await db.db
.selectFrom('user')
.where(userWhereClause(user))
.leftJoin(
'todo_social_profile as profile',
'profile.creator',
'user.did',
)
.leftJoin('app_bsky_profile as profile', 'profile.creator', 'user.did')
.select([
'user.did as did',
'user.username as name',
'profile.displayName as displayName',
'profile.description as description',
db.db
.selectFrom('todo_social_follow')
.selectFrom('app_bsky_follow')
.whereRef('creator', '=', ref('user.did'))
.select(countClause.as('count'))
.as('followsCount'),
db.db
.selectFrom('todo_social_follow')
.selectFrom('app_bsky_follow')
.whereRef('subject', '=', ref('user.did'))
.select(countClause.as('count'))
.as('followersCount'),
db.db
.selectFrom('todo_social_post')
.selectFrom('app_bsky_post')
.whereRef('creator', '=', ref('user.did'))
.select(countClause.as('count'))
.as('postsCount'),
db.db
.selectFrom('todo_social_follow')
.selectFrom('app_bsky_follow')
.where('creator', '=', requester)
.whereRef('subject', '=', ref('user.did'))
.select('uri')

@ -1,25 +1,21 @@
import { sql } from 'kysely'
import { Server } from '../../../lexicon'
import * as GetRepostedBy from '../../../lexicon/types/todo/social/getRepostedBy'
import * as GetRepostedBy from '../../../lexicon/types/app/bsky/getRepostedBy'
import * as locals from '../../../locals'
import { paginate } from '../../../db/util'
export default function (server: Server) {
server.todo.social.getRepostedBy(
server.app.bsky.getRepostedBy(
async (params: GetRepostedBy.QueryParams, _input, _req, res) => {
const { uri, limit, before } = params
const { db } = locals.get(res)
let builder = db.db
.selectFrom('todo_social_repost as repost')
.selectFrom('app_bsky_repost as repost')
.where('repost.subject', '=', uri)
.innerJoin('record', 'repost.uri', 'record.uri')
.innerJoin('user', 'repost.creator', 'user.did')
.leftJoin(
'todo_social_profile as profile',
'profile.creator',
'user.did',
)
.leftJoin('app_bsky_profile as profile', 'profile.creator', 'user.did')
.select([
'user.did as did',
'user.username as name',

Some files were not shown because too many files have changed in this diff Show More