Notification preferences V2 endpoints (#3901)
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: rafael <rafael@blueskyweb.xyz>
This commit is contained in:
parent
cd4bed3c9e
commit
a48671e730
8
.changeset/violet-trees-dress.md
Normal file
8
.changeset/violet-trees-dress.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
"@atproto/ozone": patch
|
||||||
|
"@atproto/bsky": patch
|
||||||
|
"@atproto/api": patch
|
||||||
|
"@atproto/pds": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add notification preferences V2 lexicons
|
@ -5,6 +5,64 @@
|
|||||||
"recordDeleted": {
|
"recordDeleted": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
|
},
|
||||||
|
"chatPreference": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filter", "push"],
|
||||||
|
"properties": {
|
||||||
|
"filter": { "type": "string", "knownValues": ["all", "accepted"] },
|
||||||
|
"push": { "type": "boolean" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filterablePreference": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["filter", "list", "push"],
|
||||||
|
"properties": {
|
||||||
|
"filter": { "type": "string", "knownValues": ["all", "follows"] },
|
||||||
|
"list": { "type": "boolean" },
|
||||||
|
"push": { "type": "boolean" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"preference": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["list", "push"],
|
||||||
|
"properties": {
|
||||||
|
"list": { "type": "boolean" },
|
||||||
|
"push": { "type": "boolean" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"chat",
|
||||||
|
"follow",
|
||||||
|
"like",
|
||||||
|
"likeViaRepost",
|
||||||
|
"mention",
|
||||||
|
"quote",
|
||||||
|
"reply",
|
||||||
|
"repost",
|
||||||
|
"repostViaRepost",
|
||||||
|
"starterpackJoined",
|
||||||
|
"subscribedPost",
|
||||||
|
"unverified",
|
||||||
|
"verified"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"chat": { "type": "ref", "ref": "#chatPreference" },
|
||||||
|
"follow": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"like": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"likeViaRepost": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"mention": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"quote": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"reply": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"repost": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"repostViaRepost": { "type": "ref", "ref": "#filterablePreference" },
|
||||||
|
"starterpackJoined": { "type": "ref", "ref": "#preference" },
|
||||||
|
"subscribedPost": { "type": "ref", "ref": "#preference" },
|
||||||
|
"unverified": { "type": "ref", "ref": "#preference" },
|
||||||
|
"verified": { "type": "ref", "ref": "#preference" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
lexicons/app/bsky/notification/getPreferences.json
Normal file
27
lexicons/app/bsky/notification/getPreferences.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.notification.getPreferences",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "query",
|
||||||
|
"description": "Get notification-related preferences for an account. Requires auth.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "params",
|
||||||
|
"properties": {}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["preferences"],
|
||||||
|
"properties": {
|
||||||
|
"preferences": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preferences"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
lexicons/app/bsky/notification/putPreferencesV2.json
Normal file
83
lexicons/app/bsky/notification/putPreferencesV2.json
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"lexicon": 1,
|
||||||
|
"id": "app.bsky.notification.putPreferencesV2",
|
||||||
|
"defs": {
|
||||||
|
"main": {
|
||||||
|
"type": "procedure",
|
||||||
|
"description": "Set notification-related preferences for an account. Requires auth.",
|
||||||
|
"input": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"chat": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#chatPreference"
|
||||||
|
},
|
||||||
|
"follow": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"like": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"likeViaRepost": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"mention": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"quote": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"reply": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"repost": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"repostViaRepost": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#filterablePreference"
|
||||||
|
},
|
||||||
|
"starterpackJoined": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preference"
|
||||||
|
},
|
||||||
|
"subscribedPost": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preference"
|
||||||
|
},
|
||||||
|
"unverified": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preference"
|
||||||
|
},
|
||||||
|
"verified": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preference"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"encoding": "application/json",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["preferences"],
|
||||||
|
"properties": {
|
||||||
|
"preferences": {
|
||||||
|
"type": "ref",
|
||||||
|
"ref": "app.bsky.notification.defs#preferences"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
packages/api/src/client/index.ts
generated
28
packages/api/src/client/index.ts
generated
@ -174,9 +174,11 @@ import * as AppBskyLabelerDefs from './types/app/bsky/labeler/defs.js'
|
|||||||
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
||||||
import * as AppBskyLabelerService from './types/app/bsky/labeler/service.js'
|
import * as AppBskyLabelerService from './types/app/bsky/labeler/service.js'
|
||||||
import * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js'
|
import * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js'
|
||||||
|
import * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js'
|
||||||
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
||||||
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
||||||
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
||||||
|
import * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js'
|
||||||
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
||||||
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
||||||
import * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js'
|
import * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js'
|
||||||
@ -437,9 +439,11 @@ export * as AppBskyLabelerDefs from './types/app/bsky/labeler/defs.js'
|
|||||||
export * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
export * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
||||||
export * as AppBskyLabelerService from './types/app/bsky/labeler/service.js'
|
export * as AppBskyLabelerService from './types/app/bsky/labeler/service.js'
|
||||||
export * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js'
|
export * as AppBskyNotificationDefs from './types/app/bsky/notification/defs.js'
|
||||||
|
export * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js'
|
||||||
export * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
export * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
||||||
export * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
export * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
||||||
export * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
export * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
||||||
|
export * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js'
|
||||||
export * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
export * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
||||||
export * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
export * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
||||||
export * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js'
|
export * as AppBskyRichtextFacet from './types/app/bsky/richtext/facet.js'
|
||||||
@ -3343,6 +3347,18 @@ export class AppBskyNotificationNS {
|
|||||||
this._client = client
|
this._client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreferences(
|
||||||
|
params?: AppBskyNotificationGetPreferences.QueryParams,
|
||||||
|
opts?: AppBskyNotificationGetPreferences.CallOptions,
|
||||||
|
): Promise<AppBskyNotificationGetPreferences.Response> {
|
||||||
|
return this._client.call(
|
||||||
|
'app.bsky.notification.getPreferences',
|
||||||
|
params,
|
||||||
|
undefined,
|
||||||
|
opts,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
getUnreadCount(
|
getUnreadCount(
|
||||||
params?: AppBskyNotificationGetUnreadCount.QueryParams,
|
params?: AppBskyNotificationGetUnreadCount.QueryParams,
|
||||||
opts?: AppBskyNotificationGetUnreadCount.CallOptions,
|
opts?: AppBskyNotificationGetUnreadCount.CallOptions,
|
||||||
@ -3379,6 +3395,18 @@ export class AppBskyNotificationNS {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putPreferencesV2(
|
||||||
|
data?: AppBskyNotificationPutPreferencesV2.InputSchema,
|
||||||
|
opts?: AppBskyNotificationPutPreferencesV2.CallOptions,
|
||||||
|
): Promise<AppBskyNotificationPutPreferencesV2.Response> {
|
||||||
|
return this._client.call(
|
||||||
|
'app.bsky.notification.putPreferencesV2',
|
||||||
|
opts?.qp,
|
||||||
|
data,
|
||||||
|
opts,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
registerPush(
|
registerPush(
|
||||||
data?: AppBskyNotificationRegisterPush.InputSchema,
|
data?: AppBskyNotificationRegisterPush.InputSchema,
|
||||||
opts?: AppBskyNotificationRegisterPush.CallOptions,
|
opts?: AppBskyNotificationRegisterPush.CallOptions,
|
||||||
|
227
packages/api/src/client/lexicons.ts
generated
227
packages/api/src/client/lexicons.ts
generated
@ -9732,6 +9732,147 @@ export const schemaDict = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {},
|
properties: {},
|
||||||
},
|
},
|
||||||
|
chatPreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'accepted'],
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filterablePreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'list', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'follows'],
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['list', 'push'],
|
||||||
|
properties: {
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
type: 'object',
|
||||||
|
required: [
|
||||||
|
'chat',
|
||||||
|
'follow',
|
||||||
|
'like',
|
||||||
|
'likeViaRepost',
|
||||||
|
'mention',
|
||||||
|
'quote',
|
||||||
|
'reply',
|
||||||
|
'repost',
|
||||||
|
'repostViaRepost',
|
||||||
|
'starterpackJoined',
|
||||||
|
'subscribedPost',
|
||||||
|
'unverified',
|
||||||
|
'verified',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AppBskyNotificationGetPreferences: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.getPreferences',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'query',
|
||||||
|
description:
|
||||||
|
'Get notification-related preferences for an account. Requires auth.',
|
||||||
|
parameters: {
|
||||||
|
type: 'params',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppBskyNotificationGetUnreadCount: {
|
AppBskyNotificationGetUnreadCount: {
|
||||||
@ -9924,6 +10065,90 @@ export const schemaDict = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AppBskyNotificationPutPreferencesV2: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.putPreferencesV2',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'procedure',
|
||||||
|
description:
|
||||||
|
'Set notification-related preferences for an account. Requires auth.',
|
||||||
|
input: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
AppBskyNotificationRegisterPush: {
|
AppBskyNotificationRegisterPush: {
|
||||||
lexicon: 1,
|
lexicon: 1,
|
||||||
id: 'app.bsky.notification.registerPush',
|
id: 'app.bsky.notification.registerPush',
|
||||||
@ -16557,10 +16782,12 @@ export const ids = {
|
|||||||
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
||||||
AppBskyLabelerService: 'app.bsky.labeler.service',
|
AppBskyLabelerService: 'app.bsky.labeler.service',
|
||||||
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
||||||
|
AppBskyNotificationGetPreferences: 'app.bsky.notification.getPreferences',
|
||||||
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
||||||
AppBskyNotificationListNotifications:
|
AppBskyNotificationListNotifications:
|
||||||
'app.bsky.notification.listNotifications',
|
'app.bsky.notification.listNotifications',
|
||||||
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
||||||
|
AppBskyNotificationPutPreferencesV2: 'app.bsky.notification.putPreferencesV2',
|
||||||
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
||||||
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
||||||
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
||||||
|
@ -27,3 +27,79 @@ export function isRecordDeleted<V>(v: V) {
|
|||||||
export function validateRecordDeleted<V>(v: V) {
|
export function validateRecordDeleted<V>(v: V) {
|
||||||
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChatPreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#chatPreference'
|
||||||
|
filter: 'all' | 'accepted' | (string & {})
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashChatPreference = 'chatPreference'
|
||||||
|
|
||||||
|
export function isChatPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateChatPreference<V>(v: V) {
|
||||||
|
return validate<ChatPreference & V>(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterablePreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#filterablePreference'
|
||||||
|
filter: 'all' | 'follows' | (string & {})
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashFilterablePreference = 'filterablePreference'
|
||||||
|
|
||||||
|
export function isFilterablePreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateFilterablePreference<V>(v: V) {
|
||||||
|
return validate<FilterablePreference & V>(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preference {
|
||||||
|
$type?: 'app.bsky.notification.defs#preference'
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreference = 'preference'
|
||||||
|
|
||||||
|
export function isPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreference<V>(v: V) {
|
||||||
|
return validate<Preference & V>(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preferences {
|
||||||
|
$type?: 'app.bsky.notification.defs#preferences'
|
||||||
|
chat: ChatPreference
|
||||||
|
follow: FilterablePreference
|
||||||
|
like: FilterablePreference
|
||||||
|
likeViaRepost: FilterablePreference
|
||||||
|
mention: FilterablePreference
|
||||||
|
quote: FilterablePreference
|
||||||
|
reply: FilterablePreference
|
||||||
|
repost: FilterablePreference
|
||||||
|
repostViaRepost: FilterablePreference
|
||||||
|
starterpackJoined: Preference
|
||||||
|
subscribedPost: Preference
|
||||||
|
unverified: Preference
|
||||||
|
verified: Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreferences = 'preferences'
|
||||||
|
|
||||||
|
export function isPreferences<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreferences<V>(v: V) {
|
||||||
|
return validate<Preferences & V>(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
40
packages/api/src/client/types/app/bsky/notification/getPreferences.ts
generated
Normal file
40
packages/api/src/client/types/app/bsky/notification/getPreferences.ts
generated
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import { HeadersMap, XRPCError } from '@atproto/xrpc'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.getPreferences'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export type InputSchema = undefined
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CallOptions {
|
||||||
|
signal?: AbortSignal
|
||||||
|
headers?: HeadersMap
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
success: boolean
|
||||||
|
headers: HeadersMap
|
||||||
|
data: OutputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toKnownErr(e: any) {
|
||||||
|
return e
|
||||||
|
}
|
56
packages/api/src/client/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
56
packages/api/src/client/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import { HeadersMap, XRPCError } from '@atproto/xrpc'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.putPreferencesV2'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export interface InputSchema {
|
||||||
|
chat?: AppBskyNotificationDefs.ChatPreference
|
||||||
|
follow?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
like?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
likeViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
mention?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
quote?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
reply?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repostViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
starterpackJoined?: AppBskyNotificationDefs.Preference
|
||||||
|
subscribedPost?: AppBskyNotificationDefs.Preference
|
||||||
|
unverified?: AppBskyNotificationDefs.Preference
|
||||||
|
verified?: AppBskyNotificationDefs.Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CallOptions {
|
||||||
|
signal?: AbortSignal
|
||||||
|
headers?: HeadersMap
|
||||||
|
qp?: QueryParams
|
||||||
|
encoding?: 'application/json'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Response {
|
||||||
|
success: boolean
|
||||||
|
headers: HeadersMap
|
||||||
|
data: OutputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toKnownErr(e: any) {
|
||||||
|
return e
|
||||||
|
}
|
@ -753,6 +753,66 @@ message GetBlocklistSubscriptionsResponse {
|
|||||||
// Notifications
|
// Notifications
|
||||||
//
|
//
|
||||||
|
|
||||||
|
message GetNotificationPreferencesRequest {
|
||||||
|
repeated string dids = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NotificationChannelList {
|
||||||
|
bool enabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NotificationChannelPush {
|
||||||
|
bool enabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NotificationFilter {
|
||||||
|
NOTIFICATION_FILTER_UNSPECIFIED = 0;
|
||||||
|
NOTIFICATION_FILTER_ALL = 1;
|
||||||
|
NOTIFICATION_FILTER_FOLLOWS = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FilterableNotificationPreference {
|
||||||
|
NotificationFilter filter = 1;
|
||||||
|
NotificationChannelList list = 2;
|
||||||
|
NotificationChannelPush push = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NotificationPreference {
|
||||||
|
NotificationChannelList list = 1;
|
||||||
|
NotificationChannelPush push = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ChatNotificationFilter {
|
||||||
|
CHAT_NOTIFICATION_FILTER_UNSPECIFIED = 0;
|
||||||
|
CHAT_NOTIFICATION_FILTER_ALL = 1;
|
||||||
|
CHAT_NOTIFICATION_FILTER_ACCEPTED = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChatNotificationPreference {
|
||||||
|
ChatNotificationFilter filter = 1;
|
||||||
|
NotificationChannelPush push = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NotificationPreferences {
|
||||||
|
ChatNotificationPreference chat = 1;
|
||||||
|
FilterableNotificationPreference follow = 2;
|
||||||
|
FilterableNotificationPreference like = 3;
|
||||||
|
FilterableNotificationPreference like_via_repost = 4;
|
||||||
|
FilterableNotificationPreference mention = 5;
|
||||||
|
FilterableNotificationPreference quote = 6;
|
||||||
|
FilterableNotificationPreference reply = 7;
|
||||||
|
FilterableNotificationPreference repost = 8;
|
||||||
|
FilterableNotificationPreference repost_via_repost = 9;
|
||||||
|
NotificationPreference starterpack_joined = 10;
|
||||||
|
NotificationPreference subscribed_post = 11;
|
||||||
|
NotificationPreference unverified = 12;
|
||||||
|
NotificationPreference verified = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetNotificationPreferencesResponse {
|
||||||
|
repeated NotificationPreferences preferences = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// - list recent notifications for a user
|
// - list recent notifications for a user
|
||||||
// - notifications should include a uri for the record that caused the notif & a “reason” for the notification (reply, like, quotepost, etc)
|
// - notifications should include a uri for the record that caused the notif & a “reason” for the notification (reply, like, quotepost, etc)
|
||||||
// - this should include both read & unread notifs
|
// - this should include both read & unread notifs
|
||||||
@ -1256,6 +1316,7 @@ service Service {
|
|||||||
rpc GetBlocklistSubscriptions(GetBlocklistSubscriptionsRequest) returns (GetBlocklistSubscriptionsResponse);
|
rpc GetBlocklistSubscriptions(GetBlocklistSubscriptionsRequest) returns (GetBlocklistSubscriptionsResponse);
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
|
rpc GetNotificationPreferences(GetNotificationPreferencesRequest) returns (GetNotificationPreferencesResponse);
|
||||||
rpc GetNotifications(GetNotificationsRequest) returns (GetNotificationsResponse);
|
rpc GetNotifications(GetNotificationsRequest) returns (GetNotificationsResponse);
|
||||||
rpc GetNotificationSeen(GetNotificationSeenRequest) returns (GetNotificationSeenResponse);
|
rpc GetNotificationSeen(GetNotificationSeenRequest) returns (GetNotificationSeenResponse);
|
||||||
rpc GetUnreadNotificationCount(GetUnreadNotificationCountRequest) returns (GetUnreadNotificationCountResponse);
|
rpc GetUnreadNotificationCount(GetUnreadNotificationCountRequest) returns (GetUnreadNotificationCountResponse);
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
import assert from 'node:assert'
|
||||||
|
import { Un$Typed } from '@atproto/api'
|
||||||
|
import { UpstreamFailureError } from '@atproto/xrpc-server'
|
||||||
|
import { AppContext } from '../../../../context'
|
||||||
|
import { Server } from '../../../../lexicon'
|
||||||
|
import { Preferences } from '../../../../lexicon/types/app/bsky/notification/defs'
|
||||||
|
import { GetNotificationPreferencesResponse } from '../../../../proto/bsky_pb'
|
||||||
|
import { protobufToLex } from './util'
|
||||||
|
|
||||||
|
export default function (server: Server, ctx: AppContext) {
|
||||||
|
server.app.bsky.notification.getPreferences({
|
||||||
|
auth: ctx.authVerifier.standard,
|
||||||
|
handler: async ({ auth }) => {
|
||||||
|
const actorDid = auth.credentials.iss
|
||||||
|
const preferences = await computePreferences(ctx, actorDid)
|
||||||
|
return {
|
||||||
|
encoding: 'application/json',
|
||||||
|
body: {
|
||||||
|
preferences,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const computePreferences = async (
|
||||||
|
ctx: AppContext,
|
||||||
|
actorDid: string,
|
||||||
|
): Promise<Un$Typed<Preferences>> => {
|
||||||
|
let res: GetNotificationPreferencesResponse
|
||||||
|
try {
|
||||||
|
res = await ctx.dataplane.getNotificationPreferences({
|
||||||
|
dids: [actorDid],
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
throw new UpstreamFailureError(
|
||||||
|
'cannot get current notification preferences',
|
||||||
|
'NotificationPreferencesFailed',
|
||||||
|
{ cause: err },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(
|
||||||
|
res.preferences.length === 1,
|
||||||
|
`expected exactly one preferences entry, got ${res.preferences.length}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentPreferences = protobufToLex(res.preferences[0])
|
||||||
|
return currentPreferences
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
import assert from 'node:assert'
|
||||||
|
import { Un$Typed } from '@atproto/api'
|
||||||
|
import { UpstreamFailureError } from '@atproto/xrpc-server'
|
||||||
|
import { AppContext } from '../../../../context'
|
||||||
|
import { Server } from '../../../../lexicon'
|
||||||
|
import { Preferences } from '../../../../lexicon/types/app/bsky/notification/defs'
|
||||||
|
import { HandlerInput } from '../../../../lexicon/types/app/bsky/notification/putPreferencesV2'
|
||||||
|
import { GetNotificationPreferencesResponse } from '../../../../proto/bsky_pb'
|
||||||
|
import { protobufToLex } from './util'
|
||||||
|
|
||||||
|
export default function (server: Server, ctx: AppContext) {
|
||||||
|
server.app.bsky.notification.putPreferencesV2({
|
||||||
|
auth: ctx.authVerifier.standard,
|
||||||
|
handler: async ({ auth, input }) => {
|
||||||
|
const actorDid = auth.credentials.iss
|
||||||
|
const preferences = await computePreferences(ctx, actorDid, input)
|
||||||
|
|
||||||
|
// Notification preferences are created automatically on the dataplane on signup, so we just update.
|
||||||
|
await ctx.stashClient.update({
|
||||||
|
actorDid,
|
||||||
|
namespace: 'app.bsky.notification.defs#preferences',
|
||||||
|
key: 'self',
|
||||||
|
payload: preferences,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
encoding: 'application/json',
|
||||||
|
body: {
|
||||||
|
preferences,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const computePreferences = async (
|
||||||
|
ctx: AppContext,
|
||||||
|
actorDid: string,
|
||||||
|
input: HandlerInput,
|
||||||
|
): Promise<Un$Typed<Preferences>> => {
|
||||||
|
let res: GetNotificationPreferencesResponse
|
||||||
|
try {
|
||||||
|
res = await ctx.dataplane.getNotificationPreferences({
|
||||||
|
dids: [actorDid],
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
throw new UpstreamFailureError(
|
||||||
|
'cannot get current notification preferences',
|
||||||
|
'NotificationPreferencesFailed',
|
||||||
|
{ cause: err },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(
|
||||||
|
res.preferences.length === 1,
|
||||||
|
`expected exactly one preferences entry, got ${res.preferences.length}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentPreferences = protobufToLex(res.preferences[0])
|
||||||
|
const preferences = { ...currentPreferences, ...input.body }
|
||||||
|
return preferences
|
||||||
|
}
|
123
packages/bsky/src/api/app/bsky/notification/util.ts
Normal file
123
packages/bsky/src/api/app/bsky/notification/util.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import { Un$Typed } from '@atproto/api'
|
||||||
|
import {
|
||||||
|
ChatPreference,
|
||||||
|
FilterablePreference,
|
||||||
|
Preference,
|
||||||
|
Preferences,
|
||||||
|
} from '../../../../lexicon/types/app/bsky/notification/defs'
|
||||||
|
import {
|
||||||
|
ChatNotificationFilter,
|
||||||
|
ChatNotificationPreference,
|
||||||
|
FilterableNotificationPreference,
|
||||||
|
NotificationFilter,
|
||||||
|
NotificationPreference,
|
||||||
|
NotificationPreferences,
|
||||||
|
} from '../../../../proto/bsky_pb'
|
||||||
|
|
||||||
|
type DeepPartial<T> = T extends object
|
||||||
|
? {
|
||||||
|
[P in keyof T]?: DeepPartial<T[P]>
|
||||||
|
}
|
||||||
|
: T
|
||||||
|
|
||||||
|
const ensureChatPreference = (
|
||||||
|
p?: DeepPartial<ChatPreference>,
|
||||||
|
): ChatPreference => {
|
||||||
|
const filters = ['all', 'accepted']
|
||||||
|
return {
|
||||||
|
filter:
|
||||||
|
typeof p?.filter === 'string' && filters.includes(p.filter)
|
||||||
|
? p.filter
|
||||||
|
: 'all',
|
||||||
|
push: p?.push ?? true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensureFilterablePreference = (
|
||||||
|
p?: DeepPartial<FilterablePreference>,
|
||||||
|
): FilterablePreference => {
|
||||||
|
const filters = ['all', 'follows']
|
||||||
|
return {
|
||||||
|
filter:
|
||||||
|
typeof p?.filter === 'string' && filters.includes(p.filter)
|
||||||
|
? p.filter
|
||||||
|
: 'all',
|
||||||
|
list: p?.list ?? true,
|
||||||
|
push: p?.push ?? true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensurePreference = (p?: DeepPartial<Preference>): Preference => {
|
||||||
|
return {
|
||||||
|
list: p?.list ?? true,
|
||||||
|
push: p?.push ?? true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensurePreferences = (
|
||||||
|
p: DeepPartial<Preferences>,
|
||||||
|
): Un$Typed<Preferences> => {
|
||||||
|
return {
|
||||||
|
chat: ensureChatPreference(p.chat),
|
||||||
|
follow: ensureFilterablePreference(p.follow),
|
||||||
|
like: ensureFilterablePreference(p.like),
|
||||||
|
likeViaRepost: ensureFilterablePreference(p.likeViaRepost),
|
||||||
|
mention: ensureFilterablePreference(p.mention),
|
||||||
|
quote: ensureFilterablePreference(p.quote),
|
||||||
|
reply: ensureFilterablePreference(p.reply),
|
||||||
|
repost: ensureFilterablePreference(p.repost),
|
||||||
|
repostViaRepost: ensureFilterablePreference(p.repostViaRepost),
|
||||||
|
starterpackJoined: ensurePreference(p.starterpackJoined),
|
||||||
|
subscribedPost: ensurePreference(p.subscribedPost),
|
||||||
|
unverified: ensurePreference(p.unverified),
|
||||||
|
verified: ensurePreference(p.verified),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const protobufChatPreferenceToLex = (
|
||||||
|
p?: DeepPartial<ChatNotificationPreference>,
|
||||||
|
): DeepPartial<ChatPreference> => {
|
||||||
|
return {
|
||||||
|
filter: p?.filter === ChatNotificationFilter.ACCEPTED ? 'accepted' : 'all',
|
||||||
|
push: p?.push?.enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const protobufFilterablePreferenceToLex = (
|
||||||
|
p?: DeepPartial<FilterableNotificationPreference>,
|
||||||
|
): DeepPartial<FilterablePreference> => {
|
||||||
|
return {
|
||||||
|
filter: p?.filter === NotificationFilter.FOLLOWS ? 'follows' : 'all',
|
||||||
|
list: p?.list?.enabled,
|
||||||
|
push: p?.push?.enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const protobufPreferenceToLex = (
|
||||||
|
p?: DeepPartial<NotificationPreference>,
|
||||||
|
): DeepPartial<Preference> => {
|
||||||
|
return {
|
||||||
|
list: p?.list?.enabled,
|
||||||
|
push: p?.push?.enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const protobufToLex = (
|
||||||
|
res: DeepPartial<NotificationPreferences>,
|
||||||
|
): Un$Typed<Preferences> => {
|
||||||
|
return ensurePreferences({
|
||||||
|
chat: protobufChatPreferenceToLex(res.chat),
|
||||||
|
follow: protobufFilterablePreferenceToLex(res.follow),
|
||||||
|
like: protobufFilterablePreferenceToLex(res.like),
|
||||||
|
likeViaRepost: protobufFilterablePreferenceToLex(res.likeViaRepost),
|
||||||
|
mention: protobufFilterablePreferenceToLex(res.mention),
|
||||||
|
quote: protobufFilterablePreferenceToLex(res.quote),
|
||||||
|
reply: protobufFilterablePreferenceToLex(res.reply),
|
||||||
|
repost: protobufFilterablePreferenceToLex(res.repost),
|
||||||
|
repostViaRepost: protobufFilterablePreferenceToLex(res.repostViaRepost),
|
||||||
|
starterpackJoined: protobufPreferenceToLex(res.starterpackJoined),
|
||||||
|
subscribedPost: protobufPreferenceToLex(res.subscribedPost),
|
||||||
|
unverified: protobufPreferenceToLex(res.unverified),
|
||||||
|
verified: protobufPreferenceToLex(res.verified),
|
||||||
|
})
|
||||||
|
}
|
@ -42,9 +42,11 @@ import unmuteActor from './app/bsky/graph/unmuteActor'
|
|||||||
import unmuteActorList from './app/bsky/graph/unmuteActorList'
|
import unmuteActorList from './app/bsky/graph/unmuteActorList'
|
||||||
import unmuteThread from './app/bsky/graph/unmuteThread'
|
import unmuteThread from './app/bsky/graph/unmuteThread'
|
||||||
import getLabelerServices from './app/bsky/labeler/getServices'
|
import getLabelerServices from './app/bsky/labeler/getServices'
|
||||||
|
import getPreferences from './app/bsky/notification/getPreferences'
|
||||||
import getUnreadCount from './app/bsky/notification/getUnreadCount'
|
import getUnreadCount from './app/bsky/notification/getUnreadCount'
|
||||||
import listNotifications from './app/bsky/notification/listNotifications'
|
import listNotifications from './app/bsky/notification/listNotifications'
|
||||||
import putPreferences from './app/bsky/notification/putPreferences'
|
import putPreferences from './app/bsky/notification/putPreferences'
|
||||||
|
import putPreferencesV2 from './app/bsky/notification/putPreferencesV2'
|
||||||
import registerPush from './app/bsky/notification/registerPush'
|
import registerPush from './app/bsky/notification/registerPush'
|
||||||
import updateSeen from './app/bsky/notification/updateSeen'
|
import updateSeen from './app/bsky/notification/updateSeen'
|
||||||
import getConfig from './app/bsky/unspecced/getConfig'
|
import getConfig from './app/bsky/unspecced/getConfig'
|
||||||
@ -122,10 +124,12 @@ export default function (server: Server, ctx: AppContext) {
|
|||||||
searchActors(server, ctx)
|
searchActors(server, ctx)
|
||||||
searchActorsTypeahead(server, ctx)
|
searchActorsTypeahead(server, ctx)
|
||||||
getSuggestions(server, ctx)
|
getSuggestions(server, ctx)
|
||||||
|
getPreferences(server, ctx)
|
||||||
getUnreadCount(server, ctx)
|
getUnreadCount(server, ctx)
|
||||||
listNotifications(server, ctx)
|
listNotifications(server, ctx)
|
||||||
updateSeen(server, ctx)
|
updateSeen(server, ctx)
|
||||||
putPreferences(server, ctx)
|
putPreferences(server, ctx)
|
||||||
|
putPreferencesV2(server, ctx)
|
||||||
registerPush(server, ctx)
|
registerPush(server, ctx)
|
||||||
getConfig(server, ctx)
|
getConfig(server, ctx)
|
||||||
getPopularFeedGenerators(server, ctx)
|
getPopularFeedGenerators(server, ctx)
|
||||||
|
@ -13,6 +13,7 @@ import { DataPlaneClient, HostList } from './data-plane/client'
|
|||||||
import { FeatureGates } from './feature-gates'
|
import { FeatureGates } from './feature-gates'
|
||||||
import { Hydrator } from './hydration/hydrator'
|
import { Hydrator } from './hydration/hydrator'
|
||||||
import { httpLogger as log } from './logger'
|
import { httpLogger as log } from './logger'
|
||||||
|
import { StashClient } from './stash'
|
||||||
import {
|
import {
|
||||||
ParsedLabelers,
|
ParsedLabelers,
|
||||||
defaultLabelerHeader,
|
defaultLabelerHeader,
|
||||||
@ -35,6 +36,7 @@ export class AppContext {
|
|||||||
signingKey: Keypair
|
signingKey: Keypair
|
||||||
idResolver: IdResolver
|
idResolver: IdResolver
|
||||||
bsyncClient: BsyncClient
|
bsyncClient: BsyncClient
|
||||||
|
stashClient: StashClient
|
||||||
courierClient: CourierClient | undefined
|
courierClient: CourierClient | undefined
|
||||||
authVerifier: AuthVerifier
|
authVerifier: AuthVerifier
|
||||||
featureGates: FeatureGates
|
featureGates: FeatureGates
|
||||||
@ -94,6 +96,10 @@ export class AppContext {
|
|||||||
return this.opts.bsyncClient
|
return this.opts.bsyncClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get stashClient(): StashClient {
|
||||||
|
return this.opts.stashClient
|
||||||
|
}
|
||||||
|
|
||||||
get courierClient(): CourierClient | undefined {
|
get courierClient(): CourierClient | undefined {
|
||||||
return this.opts.courierClient
|
return this.opts.courierClient
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,15 @@ import http from 'node:http'
|
|||||||
import { ConnectRouter } from '@connectrpc/connect'
|
import { ConnectRouter } from '@connectrpc/connect'
|
||||||
import { expressConnectMiddleware } from '@connectrpc/connect-express'
|
import { expressConnectMiddleware } from '@connectrpc/connect-express'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
|
import { TID } from '@atproto/common'
|
||||||
import { AtUri } from '@atproto/syntax'
|
import { AtUri } from '@atproto/syntax'
|
||||||
import { ids } from '../../lexicon/lexicons'
|
import { ids } from '../../lexicon/lexicons'
|
||||||
import { Service } from '../../proto/bsync_connect'
|
import { Service } from '../../proto/bsync_connect'
|
||||||
import { MuteOperation_Type } from '../../proto/bsync_pb'
|
import {
|
||||||
|
Method,
|
||||||
|
MuteOperation_Type,
|
||||||
|
PutOperationRequest,
|
||||||
|
} from '../../proto/bsync_pb'
|
||||||
import { Database } from '../server/db'
|
import { Database } from '../server/db'
|
||||||
|
|
||||||
export class MockBsync {
|
export class MockBsync {
|
||||||
@ -138,7 +143,110 @@ const createRoutes = (db: Database) => (router: ConnectRouter) =>
|
|||||||
throw new Error('not implemented')
|
throw new Error('not implemented')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async putOperation(req) {
|
||||||
|
const { actorDid, namespace, key, method, payload } = req
|
||||||
|
if (
|
||||||
|
method !== Method.CREATE &&
|
||||||
|
method !== Method.UPDATE &&
|
||||||
|
method !== Method.DELETE
|
||||||
|
) {
|
||||||
|
throw new Error(`Unsupported method: ${method}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date().toISOString()
|
||||||
|
if (namespace === 'app.bsky.notification.defs#preferences') {
|
||||||
|
await handleNotificationPreferencesOperation(db, req, now)
|
||||||
|
} else {
|
||||||
|
await handleGenericOperation(db, req, now)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
operation: {
|
||||||
|
id: TID.nextStr(),
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
method,
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async scanOperations() {
|
||||||
|
throw new Error('not implemented')
|
||||||
|
},
|
||||||
|
|
||||||
async ping() {
|
async ping() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const handleNotificationPreferencesOperation = async (
|
||||||
|
db: Database,
|
||||||
|
req: PutOperationRequest,
|
||||||
|
now: string,
|
||||||
|
) => {
|
||||||
|
const { actorDid, namespace, key, method, payload } = req
|
||||||
|
if (method === Method.CREATE || method === Method.UPDATE) {
|
||||||
|
return db.db
|
||||||
|
.insertInto('private_data')
|
||||||
|
.values({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: Buffer.from(payload).toString('utf8'),
|
||||||
|
indexedAt: now,
|
||||||
|
updatedAt: now,
|
||||||
|
})
|
||||||
|
.onConflict((oc) =>
|
||||||
|
oc.columns(['actorDid', 'namespace', 'key']).doUpdateSet({
|
||||||
|
payload: Buffer.from(payload).toString('utf8'),
|
||||||
|
updatedAt: now,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleGenericOperation(db, req, now)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGenericOperation = async (
|
||||||
|
db: Database,
|
||||||
|
req: PutOperationRequest,
|
||||||
|
now: string,
|
||||||
|
) => {
|
||||||
|
const { actorDid, namespace, key, method, payload } = req
|
||||||
|
if (method === Method.CREATE) {
|
||||||
|
return db.db
|
||||||
|
.insertInto('private_data')
|
||||||
|
.values({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: Buffer.from(payload).toString('utf8'),
|
||||||
|
indexedAt: now,
|
||||||
|
updatedAt: now,
|
||||||
|
})
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method === Method.UPDATE) {
|
||||||
|
return db.db
|
||||||
|
.updateTable('private_data')
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', namespace)
|
||||||
|
.where('key', '=', key)
|
||||||
|
.set({
|
||||||
|
payload: Buffer.from(payload).toString('utf8'),
|
||||||
|
updatedAt: now,
|
||||||
|
})
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.db
|
||||||
|
.deleteFrom('private_data')
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', namespace)
|
||||||
|
.where('key', '=', key)
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ import * as post from './tables/post'
|
|||||||
import * as postAgg from './tables/post-agg'
|
import * as postAgg from './tables/post-agg'
|
||||||
import * as postEmbed from './tables/post-embed'
|
import * as postEmbed from './tables/post-embed'
|
||||||
import * as postgate from './tables/post-gate'
|
import * as postgate from './tables/post-gate'
|
||||||
|
import * as privateData from './tables/private-data'
|
||||||
import * as profile from './tables/profile'
|
import * as profile from './tables/profile'
|
||||||
import * as profileAgg from './tables/profile-agg'
|
import * as profileAgg from './tables/profile-agg'
|
||||||
import * as quote from './tables/quote'
|
import * as quote from './tables/quote'
|
||||||
@ -77,6 +78,7 @@ export type DatabaseSchemaType = duplicateRecord.PartialDB &
|
|||||||
starterPack.PartialDB &
|
starterPack.PartialDB &
|
||||||
taggedSuggestion.PartialDB &
|
taggedSuggestion.PartialDB &
|
||||||
quote.PartialDB &
|
quote.PartialDB &
|
||||||
verification.PartialDB
|
verification.PartialDB &
|
||||||
|
privateData.PartialDB
|
||||||
|
|
||||||
export type DatabaseSchema = Kysely<DatabaseSchemaType>
|
export type DatabaseSchema = Kysely<DatabaseSchemaType>
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
import { Kysely } from 'kysely'
|
||||||
|
|
||||||
|
export async function up(db: Kysely<unknown>): Promise<void> {
|
||||||
|
await db.schema
|
||||||
|
.createTable('private_data')
|
||||||
|
.addColumn('actorDid', 'varchar', (col) => col.notNull())
|
||||||
|
.addColumn('namespace', 'varchar', (col) => col.notNull())
|
||||||
|
.addColumn('key', 'varchar', (col) => col.notNull())
|
||||||
|
.addColumn('payload', 'text', (col) => col.notNull())
|
||||||
|
.addColumn('indexedAt', 'varchar', (col) => col.notNull())
|
||||||
|
.addColumn('updatedAt', 'varchar', (col) => col.notNull())
|
||||||
|
.addPrimaryKeyConstraint('private_data_pkey', [
|
||||||
|
'actorDid',
|
||||||
|
'namespace',
|
||||||
|
'key',
|
||||||
|
])
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(db: Kysely<unknown>): Promise<void> {
|
||||||
|
await db.schema.dropTable('private_data').execute()
|
||||||
|
}
|
@ -50,3 +50,4 @@ export * as _20250207T174822012Z from './20250207T174822012Z-add-label-exp'
|
|||||||
export * as _20250404T163421487Z from './20250404T163421487Z-verifications'
|
export * as _20250404T163421487Z from './20250404T163421487Z-verifications'
|
||||||
export * as _20250526T023712742Z from './20250526T023712742Z-like-repost-via'
|
export * as _20250526T023712742Z from './20250526T023712742Z-like-repost-via'
|
||||||
export * as _20250528T221913281Z from './20250528T221913281Z-add-record-tags'
|
export * as _20250528T221913281Z from './20250528T221913281Z-add-record-tags'
|
||||||
|
export * as _20250602T190357447Z from './20250602T190357447Z-add-private-data'
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
export interface PrivateData {
|
||||||
|
actorDid: string
|
||||||
|
namespace: string
|
||||||
|
key: string
|
||||||
|
// JSON-encoded
|
||||||
|
payload: string
|
||||||
|
indexedAt: string
|
||||||
|
updatedAt: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const tableName = 'private_data'
|
||||||
|
|
||||||
|
export type PartialDB = { [tableName]: PrivateData }
|
@ -14,6 +14,7 @@ import lists from './lists'
|
|||||||
import moderation from './moderation'
|
import moderation from './moderation'
|
||||||
import mutes from './mutes'
|
import mutes from './mutes'
|
||||||
import notifs from './notifs'
|
import notifs from './notifs'
|
||||||
|
import privateData from './private-data'
|
||||||
import profile from './profile'
|
import profile from './profile'
|
||||||
import quotes from './quotes'
|
import quotes from './quotes'
|
||||||
import records from './records'
|
import records from './records'
|
||||||
@ -40,6 +41,7 @@ export default (db: Database, idResolver: IdResolver) =>
|
|||||||
...moderation(db),
|
...moderation(db),
|
||||||
...mutes(db),
|
...mutes(db),
|
||||||
...notifs(db),
|
...notifs(db),
|
||||||
|
...privateData(db),
|
||||||
...profile(db),
|
...profile(db),
|
||||||
...quotes(db),
|
...quotes(db),
|
||||||
...records(db),
|
...records(db),
|
||||||
|
90
packages/bsky/src/data-plane/server/routes/private-data.ts
Normal file
90
packages/bsky/src/data-plane/server/routes/private-data.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { ServiceImpl } from '@connectrpc/connect'
|
||||||
|
import { keyBy } from '@atproto/common'
|
||||||
|
import {
|
||||||
|
ChatPreference,
|
||||||
|
FilterablePreference,
|
||||||
|
Preference,
|
||||||
|
Preferences,
|
||||||
|
} from '../../../lexicon/types/app/bsky/notification/defs'
|
||||||
|
import { Service } from '../../../proto/bsky_connect'
|
||||||
|
import {
|
||||||
|
ChatNotificationFilter,
|
||||||
|
ChatNotificationPreference,
|
||||||
|
FilterableNotificationPreference,
|
||||||
|
NotificationFilter,
|
||||||
|
NotificationPreference,
|
||||||
|
NotificationPreferences,
|
||||||
|
} from '../../../proto/bsky_pb'
|
||||||
|
import { Database } from '../db'
|
||||||
|
|
||||||
|
export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
||||||
|
async getNotificationPreferences(req) {
|
||||||
|
const { dids } = req
|
||||||
|
const res = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', 'in', dids)
|
||||||
|
.where('namespace', '=', 'app.bsky.notification.defs#preferences')
|
||||||
|
.where('key', '=', 'self')
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const byDid = keyBy(res, 'actorDid')
|
||||||
|
const preferences = dids.map((did) => {
|
||||||
|
const row = byDid.get(did)
|
||||||
|
if (!row) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
const p: Preferences = JSON.parse(row.payload)
|
||||||
|
return lexToProtobuf(p)
|
||||||
|
})
|
||||||
|
|
||||||
|
return { preferences }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const lexToProtobuf = (p: Preferences): NotificationPreferences => {
|
||||||
|
return new NotificationPreferences({
|
||||||
|
chat: lexChatPreferenceToProtobuf(p.chat),
|
||||||
|
follow: lexFilterablePreferenceToProtobuf(p.follow),
|
||||||
|
like: lexFilterablePreferenceToProtobuf(p.like),
|
||||||
|
likeViaRepost: lexFilterablePreferenceToProtobuf(p.likeViaRepost),
|
||||||
|
mention: lexFilterablePreferenceToProtobuf(p.mention),
|
||||||
|
quote: lexFilterablePreferenceToProtobuf(p.quote),
|
||||||
|
reply: lexFilterablePreferenceToProtobuf(p.reply),
|
||||||
|
repost: lexFilterablePreferenceToProtobuf(p.repost),
|
||||||
|
repostViaRepost: lexFilterablePreferenceToProtobuf(p.repostViaRepost),
|
||||||
|
starterpackJoined: lexPreferenceToProtobuf(p.starterpackJoined),
|
||||||
|
subscribedPost: lexPreferenceToProtobuf(p.subscribedPost),
|
||||||
|
unverified: lexPreferenceToProtobuf(p.unverified),
|
||||||
|
verified: lexPreferenceToProtobuf(p.verified),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const lexChatPreferenceToProtobuf = (
|
||||||
|
p: ChatPreference,
|
||||||
|
): ChatNotificationPreference =>
|
||||||
|
new ChatNotificationPreference({
|
||||||
|
filter:
|
||||||
|
p.filter === 'accepted'
|
||||||
|
? ChatNotificationFilter.ACCEPTED
|
||||||
|
: ChatNotificationFilter.ALL,
|
||||||
|
push: { enabled: p.push ?? true },
|
||||||
|
})
|
||||||
|
|
||||||
|
const lexFilterablePreferenceToProtobuf = (
|
||||||
|
p: FilterablePreference,
|
||||||
|
): FilterableNotificationPreference =>
|
||||||
|
new FilterableNotificationPreference({
|
||||||
|
filter:
|
||||||
|
p.filter === 'follows'
|
||||||
|
? NotificationFilter.FOLLOWS
|
||||||
|
: NotificationFilter.ALL,
|
||||||
|
list: { enabled: p.list ?? true },
|
||||||
|
push: { enabled: p.push ?? true },
|
||||||
|
})
|
||||||
|
|
||||||
|
const lexPreferenceToProtobuf = (p: Preference): NotificationPreference =>
|
||||||
|
new NotificationPreference({
|
||||||
|
list: { enabled: p.list ?? true },
|
||||||
|
push: { enabled: p.push ?? true },
|
||||||
|
})
|
@ -29,6 +29,7 @@ import * as imageServer from './image/server'
|
|||||||
import { ImageUriBuilder } from './image/uri'
|
import { ImageUriBuilder } from './image/uri'
|
||||||
import { createServer } from './lexicon'
|
import { createServer } from './lexicon'
|
||||||
import { loggerMiddleware } from './logger'
|
import { loggerMiddleware } from './logger'
|
||||||
|
import { createStashClient } from './stash'
|
||||||
import { Views } from './views'
|
import { Views } from './views'
|
||||||
import { VideoUriBuilder } from './views/util'
|
import { VideoUriBuilder } from './views/util'
|
||||||
|
|
||||||
@ -136,6 +137,8 @@ export class BskyAppView {
|
|||||||
interceptors: config.bsyncApiKey ? [bsyncAuth(config.bsyncApiKey)] : [],
|
interceptors: config.bsyncApiKey ? [bsyncAuth(config.bsyncApiKey)] : [],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const stashClient = createStashClient(bsyncClient)
|
||||||
|
|
||||||
const courierClient = config.courierUrl
|
const courierClient = config.courierUrl
|
||||||
? createCourierClient({
|
? createCourierClient({
|
||||||
baseUrl: config.courierUrl,
|
baseUrl: config.courierUrl,
|
||||||
@ -178,6 +181,7 @@ export class BskyAppView {
|
|||||||
signingKey,
|
signingKey,
|
||||||
idResolver,
|
idResolver,
|
||||||
bsyncClient,
|
bsyncClient,
|
||||||
|
stashClient,
|
||||||
courierClient,
|
courierClient,
|
||||||
authVerifier,
|
authVerifier,
|
||||||
featureGates,
|
featureGates,
|
||||||
|
24
packages/bsky/src/lexicon/index.ts
generated
24
packages/bsky/src/lexicon/index.ts
generated
@ -138,9 +138,11 @@ import * as AppBskyGraphUnmuteActor from './types/app/bsky/graph/unmuteActor.js'
|
|||||||
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
||||||
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
||||||
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
||||||
|
import * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js'
|
||||||
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
||||||
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
||||||
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
||||||
|
import * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js'
|
||||||
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
||||||
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
||||||
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
||||||
@ -1853,6 +1855,17 @@ export class AppBskyNotificationNS {
|
|||||||
this._server = server
|
this._server = server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreferences<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationGetPreferences.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationGetPreferences.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.getPreferences' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
getUnreadCount<AV extends AuthVerifier>(
|
getUnreadCount<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
@ -1886,6 +1899,17 @@ export class AppBskyNotificationNS {
|
|||||||
return this._server.xrpc.method(nsid, cfg)
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putPreferencesV2<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationPutPreferencesV2.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationPutPreferencesV2.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.putPreferencesV2' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
registerPush<AV extends AuthVerifier>(
|
registerPush<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
|
227
packages/bsky/src/lexicon/lexicons.ts
generated
227
packages/bsky/src/lexicon/lexicons.ts
generated
@ -9732,6 +9732,147 @@ export const schemaDict = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {},
|
properties: {},
|
||||||
},
|
},
|
||||||
|
chatPreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'accepted'],
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filterablePreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'list', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'follows'],
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['list', 'push'],
|
||||||
|
properties: {
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
type: 'object',
|
||||||
|
required: [
|
||||||
|
'chat',
|
||||||
|
'follow',
|
||||||
|
'like',
|
||||||
|
'likeViaRepost',
|
||||||
|
'mention',
|
||||||
|
'quote',
|
||||||
|
'reply',
|
||||||
|
'repost',
|
||||||
|
'repostViaRepost',
|
||||||
|
'starterpackJoined',
|
||||||
|
'subscribedPost',
|
||||||
|
'unverified',
|
||||||
|
'verified',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AppBskyNotificationGetPreferences: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.getPreferences',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'query',
|
||||||
|
description:
|
||||||
|
'Get notification-related preferences for an account. Requires auth.',
|
||||||
|
parameters: {
|
||||||
|
type: 'params',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppBskyNotificationGetUnreadCount: {
|
AppBskyNotificationGetUnreadCount: {
|
||||||
@ -9924,6 +10065,90 @@ export const schemaDict = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AppBskyNotificationPutPreferencesV2: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.putPreferencesV2',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'procedure',
|
||||||
|
description:
|
||||||
|
'Set notification-related preferences for an account. Requires auth.',
|
||||||
|
input: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
AppBskyNotificationRegisterPush: {
|
AppBskyNotificationRegisterPush: {
|
||||||
lexicon: 1,
|
lexicon: 1,
|
||||||
id: 'app.bsky.notification.registerPush',
|
id: 'app.bsky.notification.registerPush',
|
||||||
@ -12939,10 +13164,12 @@ export const ids = {
|
|||||||
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
||||||
AppBskyLabelerService: 'app.bsky.labeler.service',
|
AppBskyLabelerService: 'app.bsky.labeler.service',
|
||||||
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
||||||
|
AppBskyNotificationGetPreferences: 'app.bsky.notification.getPreferences',
|
||||||
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
||||||
AppBskyNotificationListNotifications:
|
AppBskyNotificationListNotifications:
|
||||||
'app.bsky.notification.listNotifications',
|
'app.bsky.notification.listNotifications',
|
||||||
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
||||||
|
AppBskyNotificationPutPreferencesV2: 'app.bsky.notification.putPreferencesV2',
|
||||||
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
||||||
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
||||||
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
||||||
|
@ -27,3 +27,79 @@ export function isRecordDeleted<V>(v: V) {
|
|||||||
export function validateRecordDeleted<V>(v: V) {
|
export function validateRecordDeleted<V>(v: V) {
|
||||||
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChatPreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#chatPreference'
|
||||||
|
filter: 'all' | 'accepted' | (string & {})
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashChatPreference = 'chatPreference'
|
||||||
|
|
||||||
|
export function isChatPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateChatPreference<V>(v: V) {
|
||||||
|
return validate<ChatPreference & V>(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterablePreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#filterablePreference'
|
||||||
|
filter: 'all' | 'follows' | (string & {})
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashFilterablePreference = 'filterablePreference'
|
||||||
|
|
||||||
|
export function isFilterablePreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateFilterablePreference<V>(v: V) {
|
||||||
|
return validate<FilterablePreference & V>(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preference {
|
||||||
|
$type?: 'app.bsky.notification.defs#preference'
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreference = 'preference'
|
||||||
|
|
||||||
|
export function isPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreference<V>(v: V) {
|
||||||
|
return validate<Preference & V>(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preferences {
|
||||||
|
$type?: 'app.bsky.notification.defs#preferences'
|
||||||
|
chat: ChatPreference
|
||||||
|
follow: FilterablePreference
|
||||||
|
like: FilterablePreference
|
||||||
|
likeViaRepost: FilterablePreference
|
||||||
|
mention: FilterablePreference
|
||||||
|
quote: FilterablePreference
|
||||||
|
reply: FilterablePreference
|
||||||
|
repost: FilterablePreference
|
||||||
|
repostViaRepost: FilterablePreference
|
||||||
|
starterpackJoined: Preference
|
||||||
|
subscribedPost: Preference
|
||||||
|
unverified: Preference
|
||||||
|
verified: Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreferences = 'preferences'
|
||||||
|
|
||||||
|
export function isPreferences<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreferences<V>(v: V) {
|
||||||
|
return validate<Preferences & V>(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
52
packages/bsky/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
52
packages/bsky/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.getPreferences'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export type InputSchema = undefined
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerInput = undefined
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
69
packages/bsky/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
69
packages/bsky/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.putPreferencesV2'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export interface InputSchema {
|
||||||
|
chat?: AppBskyNotificationDefs.ChatPreference
|
||||||
|
follow?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
like?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
likeViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
mention?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
quote?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
reply?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repostViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
starterpackJoined?: AppBskyNotificationDefs.Preference
|
||||||
|
subscribedPost?: AppBskyNotificationDefs.Preference
|
||||||
|
unverified?: AppBskyNotificationDefs.Preference
|
||||||
|
verified?: AppBskyNotificationDefs.Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerInput {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: InputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
11
packages/bsky/src/proto/bsky_connect.ts
generated
11
packages/bsky/src/proto/bsky_connect.ts
generated
@ -126,6 +126,8 @@ import {
|
|||||||
GetMutesResponse,
|
GetMutesResponse,
|
||||||
GetNewUserCountForRangeRequest,
|
GetNewUserCountForRangeRequest,
|
||||||
GetNewUserCountForRangeResponse,
|
GetNewUserCountForRangeResponse,
|
||||||
|
GetNotificationPreferencesRequest,
|
||||||
|
GetNotificationPreferencesResponse,
|
||||||
GetNotificationSeenRequest,
|
GetNotificationSeenRequest,
|
||||||
GetNotificationSeenResponse,
|
GetNotificationSeenResponse,
|
||||||
GetNotificationsRequest,
|
GetNotificationsRequest,
|
||||||
@ -732,6 +734,15 @@ export const Service = {
|
|||||||
/**
|
/**
|
||||||
* Notifications
|
* Notifications
|
||||||
*
|
*
|
||||||
|
* @generated from rpc bsky.Service.GetNotificationPreferences
|
||||||
|
*/
|
||||||
|
getNotificationPreferences: {
|
||||||
|
name: 'GetNotificationPreferences',
|
||||||
|
I: GetNotificationPreferencesRequest,
|
||||||
|
O: GetNotificationPreferencesResponse,
|
||||||
|
kind: MethodKind.Unary,
|
||||||
|
},
|
||||||
|
/**
|
||||||
* @generated from rpc bsky.Service.GetNotifications
|
* @generated from rpc bsky.Service.GetNotifications
|
||||||
*/
|
*/
|
||||||
getNotifications: {
|
getNotifications: {
|
||||||
|
669
packages/bsky/src/proto/bsky_pb.ts
generated
669
packages/bsky/src/proto/bsky_pb.ts
generated
@ -13,6 +13,58 @@ import type {
|
|||||||
} from '@bufbuild/protobuf'
|
} from '@bufbuild/protobuf'
|
||||||
import { Message, proto3, protoInt64, Timestamp } from '@bufbuild/protobuf'
|
import { Message, proto3, protoInt64, Timestamp } from '@bufbuild/protobuf'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum bsky.NotificationFilter
|
||||||
|
*/
|
||||||
|
export enum NotificationFilter {
|
||||||
|
/**
|
||||||
|
* @generated from enum value: NOTIFICATION_FILTER_UNSPECIFIED = 0;
|
||||||
|
*/
|
||||||
|
UNSPECIFIED = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum value: NOTIFICATION_FILTER_ALL = 1;
|
||||||
|
*/
|
||||||
|
ALL = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum value: NOTIFICATION_FILTER_FOLLOWS = 2;
|
||||||
|
*/
|
||||||
|
FOLLOWS = 2,
|
||||||
|
}
|
||||||
|
// Retrieve enum metadata with: proto3.getEnumType(NotificationFilter)
|
||||||
|
proto3.util.setEnumType(NotificationFilter, 'bsky.NotificationFilter', [
|
||||||
|
{ no: 0, name: 'NOTIFICATION_FILTER_UNSPECIFIED' },
|
||||||
|
{ no: 1, name: 'NOTIFICATION_FILTER_ALL' },
|
||||||
|
{ no: 2, name: 'NOTIFICATION_FILTER_FOLLOWS' },
|
||||||
|
])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum bsky.ChatNotificationFilter
|
||||||
|
*/
|
||||||
|
export enum ChatNotificationFilter {
|
||||||
|
/**
|
||||||
|
* @generated from enum value: CHAT_NOTIFICATION_FILTER_UNSPECIFIED = 0;
|
||||||
|
*/
|
||||||
|
UNSPECIFIED = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum value: CHAT_NOTIFICATION_FILTER_ALL = 1;
|
||||||
|
*/
|
||||||
|
ALL = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from enum value: CHAT_NOTIFICATION_FILTER_ACCEPTED = 2;
|
||||||
|
*/
|
||||||
|
ACCEPTED = 2,
|
||||||
|
}
|
||||||
|
// Retrieve enum metadata with: proto3.getEnumType(ChatNotificationFilter)
|
||||||
|
proto3.util.setEnumType(ChatNotificationFilter, 'bsky.ChatNotificationFilter', [
|
||||||
|
{ no: 0, name: 'CHAT_NOTIFICATION_FILTER_UNSPECIFIED' },
|
||||||
|
{ no: 1, name: 'CHAT_NOTIFICATION_FILTER_ALL' },
|
||||||
|
{ no: 2, name: 'CHAT_NOTIFICATION_FILTER_ACCEPTED' },
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from enum bsky.FeedType
|
* @generated from enum bsky.FeedType
|
||||||
*/
|
*/
|
||||||
@ -8180,6 +8232,623 @@ export class GetBlocklistSubscriptionsResponse extends Message<GetBlocklistSubsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.GetNotificationPreferencesRequest
|
||||||
|
*/
|
||||||
|
export class GetNotificationPreferencesRequest extends Message<GetNotificationPreferencesRequest> {
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated string dids = 1;
|
||||||
|
*/
|
||||||
|
dids: string[] = []
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<GetNotificationPreferencesRequest>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.GetNotificationPreferencesRequest'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{
|
||||||
|
no: 1,
|
||||||
|
name: 'dids',
|
||||||
|
kind: 'scalar',
|
||||||
|
T: 9 /* ScalarType.STRING */,
|
||||||
|
repeated: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): GetNotificationPreferencesRequest {
|
||||||
|
return new GetNotificationPreferencesRequest().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): GetNotificationPreferencesRequest {
|
||||||
|
return new GetNotificationPreferencesRequest().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): GetNotificationPreferencesRequest {
|
||||||
|
return new GetNotificationPreferencesRequest().fromJsonString(
|
||||||
|
jsonString,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| GetNotificationPreferencesRequest
|
||||||
|
| PlainMessage<GetNotificationPreferencesRequest>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| GetNotificationPreferencesRequest
|
||||||
|
| PlainMessage<GetNotificationPreferencesRequest>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(GetNotificationPreferencesRequest, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.NotificationChannelList
|
||||||
|
*/
|
||||||
|
export class NotificationChannelList extends Message<NotificationChannelList> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bool enabled = 1;
|
||||||
|
*/
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<NotificationChannelList>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.NotificationChannelList'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{ no: 1, name: 'enabled', kind: 'scalar', T: 8 /* ScalarType.BOOL */ },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): NotificationChannelList {
|
||||||
|
return new NotificationChannelList().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationChannelList {
|
||||||
|
return new NotificationChannelList().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationChannelList {
|
||||||
|
return new NotificationChannelList().fromJsonString(jsonString, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| NotificationChannelList
|
||||||
|
| PlainMessage<NotificationChannelList>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| NotificationChannelList
|
||||||
|
| PlainMessage<NotificationChannelList>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(NotificationChannelList, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.NotificationChannelPush
|
||||||
|
*/
|
||||||
|
export class NotificationChannelPush extends Message<NotificationChannelPush> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bool enabled = 1;
|
||||||
|
*/
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<NotificationChannelPush>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.NotificationChannelPush'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{ no: 1, name: 'enabled', kind: 'scalar', T: 8 /* ScalarType.BOOL */ },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): NotificationChannelPush {
|
||||||
|
return new NotificationChannelPush().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationChannelPush {
|
||||||
|
return new NotificationChannelPush().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationChannelPush {
|
||||||
|
return new NotificationChannelPush().fromJsonString(jsonString, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| NotificationChannelPush
|
||||||
|
| PlainMessage<NotificationChannelPush>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| NotificationChannelPush
|
||||||
|
| PlainMessage<NotificationChannelPush>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(NotificationChannelPush, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.FilterableNotificationPreference
|
||||||
|
*/
|
||||||
|
export class FilterableNotificationPreference extends Message<FilterableNotificationPreference> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationFilter filter = 1;
|
||||||
|
*/
|
||||||
|
filter = NotificationFilter.UNSPECIFIED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationChannelList list = 2;
|
||||||
|
*/
|
||||||
|
list?: NotificationChannelList
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationChannelPush push = 3;
|
||||||
|
*/
|
||||||
|
push?: NotificationChannelPush
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<FilterableNotificationPreference>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.FilterableNotificationPreference'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{
|
||||||
|
no: 1,
|
||||||
|
name: 'filter',
|
||||||
|
kind: 'enum',
|
||||||
|
T: proto3.getEnumType(NotificationFilter),
|
||||||
|
},
|
||||||
|
{ no: 2, name: 'list', kind: 'message', T: NotificationChannelList },
|
||||||
|
{ no: 3, name: 'push', kind: 'message', T: NotificationChannelPush },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): FilterableNotificationPreference {
|
||||||
|
return new FilterableNotificationPreference().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): FilterableNotificationPreference {
|
||||||
|
return new FilterableNotificationPreference().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): FilterableNotificationPreference {
|
||||||
|
return new FilterableNotificationPreference().fromJsonString(
|
||||||
|
jsonString,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| FilterableNotificationPreference
|
||||||
|
| PlainMessage<FilterableNotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| FilterableNotificationPreference
|
||||||
|
| PlainMessage<FilterableNotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(FilterableNotificationPreference, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.NotificationPreference
|
||||||
|
*/
|
||||||
|
export class NotificationPreference extends Message<NotificationPreference> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationChannelList list = 1;
|
||||||
|
*/
|
||||||
|
list?: NotificationChannelList
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationChannelPush push = 2;
|
||||||
|
*/
|
||||||
|
push?: NotificationChannelPush
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<NotificationPreference>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.NotificationPreference'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{ no: 1, name: 'list', kind: 'message', T: NotificationChannelList },
|
||||||
|
{ no: 2, name: 'push', kind: 'message', T: NotificationChannelPush },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): NotificationPreference {
|
||||||
|
return new NotificationPreference().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationPreference {
|
||||||
|
return new NotificationPreference().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationPreference {
|
||||||
|
return new NotificationPreference().fromJsonString(jsonString, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| NotificationPreference
|
||||||
|
| PlainMessage<NotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| NotificationPreference
|
||||||
|
| PlainMessage<NotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(NotificationPreference, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.ChatNotificationPreference
|
||||||
|
*/
|
||||||
|
export class ChatNotificationPreference extends Message<ChatNotificationPreference> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.ChatNotificationFilter filter = 1;
|
||||||
|
*/
|
||||||
|
filter = ChatNotificationFilter.UNSPECIFIED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationChannelPush push = 2;
|
||||||
|
*/
|
||||||
|
push?: NotificationChannelPush
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<ChatNotificationPreference>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.ChatNotificationPreference'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{
|
||||||
|
no: 1,
|
||||||
|
name: 'filter',
|
||||||
|
kind: 'enum',
|
||||||
|
T: proto3.getEnumType(ChatNotificationFilter),
|
||||||
|
},
|
||||||
|
{ no: 2, name: 'push', kind: 'message', T: NotificationChannelPush },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): ChatNotificationPreference {
|
||||||
|
return new ChatNotificationPreference().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): ChatNotificationPreference {
|
||||||
|
return new ChatNotificationPreference().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): ChatNotificationPreference {
|
||||||
|
return new ChatNotificationPreference().fromJsonString(jsonString, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| ChatNotificationPreference
|
||||||
|
| PlainMessage<ChatNotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| ChatNotificationPreference
|
||||||
|
| PlainMessage<ChatNotificationPreference>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(ChatNotificationPreference, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.NotificationPreferences
|
||||||
|
*/
|
||||||
|
export class NotificationPreferences extends Message<NotificationPreferences> {
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.ChatNotificationPreference chat = 1;
|
||||||
|
*/
|
||||||
|
chat?: ChatNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference follow = 2;
|
||||||
|
*/
|
||||||
|
follow?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference like = 3;
|
||||||
|
*/
|
||||||
|
like?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference like_via_repost = 4;
|
||||||
|
*/
|
||||||
|
likeViaRepost?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference mention = 5;
|
||||||
|
*/
|
||||||
|
mention?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference quote = 6;
|
||||||
|
*/
|
||||||
|
quote?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference reply = 7;
|
||||||
|
*/
|
||||||
|
reply?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference repost = 8;
|
||||||
|
*/
|
||||||
|
repost?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.FilterableNotificationPreference repost_via_repost = 9;
|
||||||
|
*/
|
||||||
|
repostViaRepost?: FilterableNotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationPreference starterpack_joined = 10;
|
||||||
|
*/
|
||||||
|
starterpackJoined?: NotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationPreference subscribed_post = 11;
|
||||||
|
*/
|
||||||
|
subscribedPost?: NotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationPreference unverified = 12;
|
||||||
|
*/
|
||||||
|
unverified?: NotificationPreference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bsky.NotificationPreference verified = 13;
|
||||||
|
*/
|
||||||
|
verified?: NotificationPreference
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<NotificationPreferences>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.NotificationPreferences'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{ no: 1, name: 'chat', kind: 'message', T: ChatNotificationPreference },
|
||||||
|
{
|
||||||
|
no: 2,
|
||||||
|
name: 'follow',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 3,
|
||||||
|
name: 'like',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 4,
|
||||||
|
name: 'like_via_repost',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 5,
|
||||||
|
name: 'mention',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 6,
|
||||||
|
name: 'quote',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 7,
|
||||||
|
name: 'reply',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 8,
|
||||||
|
name: 'repost',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 9,
|
||||||
|
name: 'repost_via_repost',
|
||||||
|
kind: 'message',
|
||||||
|
T: FilterableNotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 10,
|
||||||
|
name: 'starterpack_joined',
|
||||||
|
kind: 'message',
|
||||||
|
T: NotificationPreference,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
no: 11,
|
||||||
|
name: 'subscribed_post',
|
||||||
|
kind: 'message',
|
||||||
|
T: NotificationPreference,
|
||||||
|
},
|
||||||
|
{ no: 12, name: 'unverified', kind: 'message', T: NotificationPreference },
|
||||||
|
{ no: 13, name: 'verified', kind: 'message', T: NotificationPreference },
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): NotificationPreferences {
|
||||||
|
return new NotificationPreferences().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationPreferences {
|
||||||
|
return new NotificationPreferences().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): NotificationPreferences {
|
||||||
|
return new NotificationPreferences().fromJsonString(jsonString, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| NotificationPreferences
|
||||||
|
| PlainMessage<NotificationPreferences>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| NotificationPreferences
|
||||||
|
| PlainMessage<NotificationPreferences>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(NotificationPreferences, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message bsky.GetNotificationPreferencesResponse
|
||||||
|
*/
|
||||||
|
export class GetNotificationPreferencesResponse extends Message<GetNotificationPreferencesResponse> {
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated bsky.NotificationPreferences preferences = 1;
|
||||||
|
*/
|
||||||
|
preferences: NotificationPreferences[] = []
|
||||||
|
|
||||||
|
constructor(data?: PartialMessage<GetNotificationPreferencesResponse>) {
|
||||||
|
super()
|
||||||
|
proto3.util.initPartial(data, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly runtime: typeof proto3 = proto3
|
||||||
|
static readonly typeName = 'bsky.GetNotificationPreferencesResponse'
|
||||||
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
|
{
|
||||||
|
no: 1,
|
||||||
|
name: 'preferences',
|
||||||
|
kind: 'message',
|
||||||
|
T: NotificationPreferences,
|
||||||
|
repeated: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
static fromBinary(
|
||||||
|
bytes: Uint8Array,
|
||||||
|
options?: Partial<BinaryReadOptions>,
|
||||||
|
): GetNotificationPreferencesResponse {
|
||||||
|
return new GetNotificationPreferencesResponse().fromBinary(bytes, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJson(
|
||||||
|
jsonValue: JsonValue,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): GetNotificationPreferencesResponse {
|
||||||
|
return new GetNotificationPreferencesResponse().fromJson(jsonValue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromJsonString(
|
||||||
|
jsonString: string,
|
||||||
|
options?: Partial<JsonReadOptions>,
|
||||||
|
): GetNotificationPreferencesResponse {
|
||||||
|
return new GetNotificationPreferencesResponse().fromJsonString(
|
||||||
|
jsonString,
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static equals(
|
||||||
|
a:
|
||||||
|
| GetNotificationPreferencesResponse
|
||||||
|
| PlainMessage<GetNotificationPreferencesResponse>
|
||||||
|
| undefined,
|
||||||
|
b:
|
||||||
|
| GetNotificationPreferencesResponse
|
||||||
|
| PlainMessage<GetNotificationPreferencesResponse>
|
||||||
|
| undefined,
|
||||||
|
): boolean {
|
||||||
|
return proto3.util.equals(GetNotificationPreferencesResponse, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* - list recent notifications for a user
|
* - list recent notifications for a user
|
||||||
* - notifications should include a uri for the record that caused the notif & a “reason” for the notification (reply, like, quotepost, etc)
|
* - notifications should include a uri for the record that caused the notif & a “reason” for the notification (reply, like, quotepost, etc)
|
||||||
|
34
packages/bsky/src/proto/bsync_pb.ts
generated
34
packages/bsky/src/proto/bsync_pb.ts
generated
@ -736,14 +736,14 @@ export class Operation extends Message<Operation> {
|
|||||||
actorDid = ''
|
actorDid = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: string collection = 3;
|
* @generated from field: string namespace = 3;
|
||||||
*/
|
*/
|
||||||
collection = ''
|
namespace = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: string rkey = 4;
|
* @generated from field: string key = 4;
|
||||||
*/
|
*/
|
||||||
rkey = ''
|
key = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: bsync.Method method = 5;
|
* @generated from field: bsync.Method method = 5;
|
||||||
@ -765,8 +765,8 @@ export class Operation extends Message<Operation> {
|
|||||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
{ no: 1, name: 'id', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 1, name: 'id', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 2, name: 'actor_did', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 2, name: 'actor_did', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 3, name: 'collection', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 3, name: 'namespace', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 4, name: 'rkey', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 4, name: 'key', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 5, name: 'method', kind: 'enum', T: proto3.getEnumType(Method) },
|
{ no: 5, name: 'method', kind: 'enum', T: proto3.getEnumType(Method) },
|
||||||
{ no: 6, name: 'payload', kind: 'scalar', T: 12 /* ScalarType.BYTES */ },
|
{ no: 6, name: 'payload', kind: 'scalar', T: 12 /* ScalarType.BYTES */ },
|
||||||
])
|
])
|
||||||
@ -805,19 +805,19 @@ export class Operation extends Message<Operation> {
|
|||||||
*/
|
*/
|
||||||
export class PutOperationRequest extends Message<PutOperationRequest> {
|
export class PutOperationRequest extends Message<PutOperationRequest> {
|
||||||
/**
|
/**
|
||||||
* @generated from field: string collection = 1;
|
* @generated from field: string actor_did = 1;
|
||||||
*/
|
|
||||||
collection = ''
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string actor_did = 2;
|
|
||||||
*/
|
*/
|
||||||
actorDid = ''
|
actorDid = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: string rkey = 3;
|
* @generated from field: string namespace = 2;
|
||||||
*/
|
*/
|
||||||
rkey = ''
|
namespace = ''
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string key = 3;
|
||||||
|
*/
|
||||||
|
key = ''
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: bsync.Method method = 4;
|
* @generated from field: bsync.Method method = 4;
|
||||||
@ -837,9 +837,9 @@ export class PutOperationRequest extends Message<PutOperationRequest> {
|
|||||||
static readonly runtime: typeof proto3 = proto3
|
static readonly runtime: typeof proto3 = proto3
|
||||||
static readonly typeName = 'bsync.PutOperationRequest'
|
static readonly typeName = 'bsync.PutOperationRequest'
|
||||||
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
||||||
{ no: 1, name: 'collection', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 1, name: 'actor_did', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 2, name: 'actor_did', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 2, name: 'namespace', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 3, name: 'rkey', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
{ no: 3, name: 'key', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
|
||||||
{ no: 4, name: 'method', kind: 'enum', T: proto3.getEnumType(Method) },
|
{ no: 4, name: 'method', kind: 'enum', T: proto3.getEnumType(Method) },
|
||||||
{ no: 5, name: 'payload', kind: 'scalar', T: 12 /* ScalarType.BYTES */ },
|
{ no: 5, name: 'payload', kind: 'scalar', T: 12 /* ScalarType.BYTES */ },
|
||||||
])
|
])
|
||||||
|
75
packages/bsky/src/stash.ts
Normal file
75
packages/bsky/src/stash.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { LexValue, stringifyLex } from '@atproto/lexicon'
|
||||||
|
import { BsyncClient } from './bsync'
|
||||||
|
import { lexicons } from './lexicon/lexicons'
|
||||||
|
import { Method } from './proto/bsync_pb'
|
||||||
|
|
||||||
|
export const createStashClient = (bsyncClient: BsyncClient): StashClient => {
|
||||||
|
return new StashClient(bsyncClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
// An abstraction over the BsyncClient, that uses the bsync `PutOperation` RPC
|
||||||
|
// to store private data, which can be indexed by the dataplane and queried by the appview.
|
||||||
|
export class StashClient {
|
||||||
|
constructor(private readonly bsyncClient: BsyncClient) {}
|
||||||
|
|
||||||
|
create(input: CreateInput) {
|
||||||
|
this.validateLexicon(input.namespace, input.payload)
|
||||||
|
return this.putOperation(Method.CREATE, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
update(input: UpdateInput) {
|
||||||
|
this.validateLexicon(input.namespace, input.payload)
|
||||||
|
return this.putOperation(Method.UPDATE, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(input: DeleteInput) {
|
||||||
|
return this.putOperation(Method.DELETE, { ...input, payload: undefined })
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateLexicon(namespace: string, payload: LexValue) {
|
||||||
|
const result = lexicons.validate(namespace, payload)
|
||||||
|
if (!result.success) {
|
||||||
|
throw result.error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async putOperation(method: Method, input: PutOperationInput) {
|
||||||
|
const { actorDid, namespace, key, payload } = input
|
||||||
|
await this.bsyncClient.putOperation({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
method,
|
||||||
|
payload: payload
|
||||||
|
? Buffer.from(
|
||||||
|
stringifyLex({
|
||||||
|
$type: namespace,
|
||||||
|
...payload,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PutOperationInput = {
|
||||||
|
actorDid: string
|
||||||
|
namespace: string
|
||||||
|
key: string
|
||||||
|
payload: LexValue | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateInput = {
|
||||||
|
actorDid: string
|
||||||
|
namespace: string
|
||||||
|
key: string
|
||||||
|
payload: LexValue
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateInput = CreateInput
|
||||||
|
|
||||||
|
type DeleteInput = {
|
||||||
|
actorDid: string
|
||||||
|
namespace: string
|
||||||
|
key: string
|
||||||
|
}
|
156
packages/bsky/tests/stash.test.ts
Normal file
156
packages/bsky/tests/stash.test.ts
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
import { TestNetwork } from '@atproto/dev-env'
|
||||||
|
import { ProfileAssociatedChat } from '../dist/lexicon/types/app/bsky/actor/defs'
|
||||||
|
import { StashClient } from '../dist/stash'
|
||||||
|
|
||||||
|
type Database = TestNetwork['bsky']['db']
|
||||||
|
|
||||||
|
describe('private data', () => {
|
||||||
|
let network: TestNetwork
|
||||||
|
let stashClient: StashClient
|
||||||
|
let db: Database
|
||||||
|
|
||||||
|
const actorDid = 'did:plc:example'
|
||||||
|
// This lexicon has nothing special other than being simple, convenient to use in a test.
|
||||||
|
const namespace = 'app.bsky.actor.defs#profileAssociatedChat'
|
||||||
|
const key = 'self'
|
||||||
|
|
||||||
|
const validPayload0: ProfileAssociatedChat = { allowIncoming: 'all' }
|
||||||
|
const validPayload1: ProfileAssociatedChat = { allowIncoming: 'following' }
|
||||||
|
const invalidPayload: ProfileAssociatedChat = {
|
||||||
|
invalid: 'all',
|
||||||
|
} as unknown as ProfileAssociatedChat
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
network = await TestNetwork.create({
|
||||||
|
dbPostgresSchema: 'bsky_private_data',
|
||||||
|
})
|
||||||
|
db = network.bsky.db
|
||||||
|
stashClient = network.bsky.ctx.stashClient
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await clearPrivateData(db)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await network.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('creates entry', async () => {
|
||||||
|
await stashClient.create({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: validPayload0,
|
||||||
|
})
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
const dbResult = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', namespace)
|
||||||
|
.where('key', '=', key)
|
||||||
|
.executeTakeFirstOrThrow()
|
||||||
|
expect(dbResult).toStrictEqual({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: JSON.stringify({ $type: namespace, ...validPayload0 }),
|
||||||
|
indexedAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('validates lexicon', async () => {
|
||||||
|
expect(() =>
|
||||||
|
stashClient.create({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: invalidPayload,
|
||||||
|
}),
|
||||||
|
).toThrow('Object must have the property "allowIncoming"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('update', () => {
|
||||||
|
it('updates entry', async () => {
|
||||||
|
await stashClient.create({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: validPayload0,
|
||||||
|
})
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
await stashClient.update({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: validPayload1,
|
||||||
|
})
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
const dbResult = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', namespace)
|
||||||
|
.where('key', '=', key)
|
||||||
|
.executeTakeFirstOrThrow()
|
||||||
|
expect(dbResult).toStrictEqual({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: JSON.stringify({ $type: namespace, ...validPayload1 }),
|
||||||
|
indexedAt: expect.any(String),
|
||||||
|
updatedAt: expect.any(String),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('validates lexicon', async () => {
|
||||||
|
expect(() =>
|
||||||
|
stashClient.update({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: invalidPayload,
|
||||||
|
}),
|
||||||
|
).toThrow('Object must have the property "allowIncoming"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('delete', () => {
|
||||||
|
it('deletes entry', async () => {
|
||||||
|
await stashClient.create({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
payload: validPayload0,
|
||||||
|
})
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
await stashClient.delete({
|
||||||
|
actorDid,
|
||||||
|
namespace,
|
||||||
|
key,
|
||||||
|
})
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
const dbResult = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', namespace)
|
||||||
|
.where('key', '=', key)
|
||||||
|
.executeTakeFirst()
|
||||||
|
expect(dbResult).toBe(undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const clearPrivateData = async (db: Database) => {
|
||||||
|
await db.db.deleteFrom('private_data').execute()
|
||||||
|
}
|
@ -2,11 +2,22 @@ import { AtpAgent } from '@atproto/api'
|
|||||||
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
|
||||||
import { delayCursor } from '../../src/api/app/bsky/notification/listNotifications'
|
import { delayCursor } from '../../src/api/app/bsky/notification/listNotifications'
|
||||||
import { ids } from '../../src/lexicon/lexicons'
|
import { ids } from '../../src/lexicon/lexicons'
|
||||||
|
import {
|
||||||
|
ChatPreference,
|
||||||
|
FilterablePreference,
|
||||||
|
Preference,
|
||||||
|
Preferences,
|
||||||
|
} from '../../src/lexicon/types/app/bsky/notification/defs'
|
||||||
import { Notification } from '../../src/lexicon/types/app/bsky/notification/listNotifications'
|
import { Notification } from '../../src/lexicon/types/app/bsky/notification/listNotifications'
|
||||||
|
import { InputSchema } from '../../src/lexicon/types/app/bsky/notification/putPreferencesV2'
|
||||||
import { forSnapshot, paginateAll } from '../_util'
|
import { forSnapshot, paginateAll } from '../_util'
|
||||||
|
|
||||||
|
type Database = TestNetwork['bsky']['db']
|
||||||
|
|
||||||
describe('notification views', () => {
|
describe('notification views', () => {
|
||||||
let network: TestNetwork
|
let network: TestNetwork
|
||||||
|
let db: Database
|
||||||
|
|
||||||
let agent: AtpAgent
|
let agent: AtpAgent
|
||||||
let sc: SeedClient
|
let sc: SeedClient
|
||||||
|
|
||||||
@ -19,6 +30,7 @@ describe('notification views', () => {
|
|||||||
network = await TestNetwork.create({
|
network = await TestNetwork.create({
|
||||||
dbPostgresSchema: 'bsky_views_notifications',
|
dbPostgresSchema: 'bsky_views_notifications',
|
||||||
})
|
})
|
||||||
|
db = network.bsky.db
|
||||||
agent = network.bsky.getClient()
|
agent = network.bsky.getClient()
|
||||||
sc = network.getSeedClient()
|
sc = network.getSeedClient()
|
||||||
await basicSeed(sc)
|
await basicSeed(sc)
|
||||||
@ -905,4 +917,213 @@ describe('notification views', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('preferences v2', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await clearPrivateData(db)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
const fp: FilterablePreference = {
|
||||||
|
filter: 'all',
|
||||||
|
list: true,
|
||||||
|
push: true,
|
||||||
|
}
|
||||||
|
const p: Preference = {
|
||||||
|
list: true,
|
||||||
|
push: true,
|
||||||
|
}
|
||||||
|
const cp: ChatPreference = {
|
||||||
|
filter: 'all',
|
||||||
|
push: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
it('gets preferences filling up with the defaults', async () => {
|
||||||
|
const actorDid = sc.dids.carol
|
||||||
|
|
||||||
|
const getAndAssert = async (
|
||||||
|
expectedApi: Preferences,
|
||||||
|
expectedDb: Preferences | undefined,
|
||||||
|
) => {
|
||||||
|
const { data } = await agent.app.bsky.notification.getPreferences(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
headers: await network.serviceHeaders(
|
||||||
|
actorDid,
|
||||||
|
ids.AppBskyNotificationGetPreferences,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
expect(data.preferences).toStrictEqual(expectedApi)
|
||||||
|
|
||||||
|
const dbResult = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', 'app.bsky.notification.defs#preferences')
|
||||||
|
.where('key', '=', 'self')
|
||||||
|
.executeTakeFirst()
|
||||||
|
if (dbResult === undefined) {
|
||||||
|
expect(dbResult).toBe(expectedDb)
|
||||||
|
} else {
|
||||||
|
expect(dbResult).toStrictEqual({
|
||||||
|
actorDid: actorDid,
|
||||||
|
namespace: 'app.bsky.notification.defs#preferences',
|
||||||
|
key: 'self',
|
||||||
|
indexedAt: expect.any(String),
|
||||||
|
payload: expect.anything(), // Better to compare payload parsed.
|
||||||
|
updatedAt: expect.any(String),
|
||||||
|
})
|
||||||
|
expect(JSON.parse(dbResult.payload)).toStrictEqual({
|
||||||
|
$type: 'app.bsky.notification.defs#preferences',
|
||||||
|
...expectedDb,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedApi0: Preferences = {
|
||||||
|
chat: cp,
|
||||||
|
follow: fp,
|
||||||
|
like: fp,
|
||||||
|
likeViaRepost: fp,
|
||||||
|
mention: fp,
|
||||||
|
quote: fp,
|
||||||
|
reply: fp,
|
||||||
|
repost: fp,
|
||||||
|
repostViaRepost: fp,
|
||||||
|
starterpackJoined: p,
|
||||||
|
subscribedPost: p,
|
||||||
|
unverified: p,
|
||||||
|
verified: p,
|
||||||
|
}
|
||||||
|
// The user has no preferences set yet, so nothing stored.
|
||||||
|
const expectedDb0 = undefined
|
||||||
|
await getAndAssert(expectedApi0, expectedDb0)
|
||||||
|
|
||||||
|
await agent.app.bsky.notification.putPreferencesV2(
|
||||||
|
{ verified: { list: false, push: false } },
|
||||||
|
{
|
||||||
|
encoding: 'application/json',
|
||||||
|
headers: await network.serviceHeaders(
|
||||||
|
actorDid,
|
||||||
|
ids.AppBskyNotificationPutPreferencesV2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await network.processAll()
|
||||||
|
|
||||||
|
const expectedApi1: Preferences = {
|
||||||
|
chat: cp,
|
||||||
|
follow: fp,
|
||||||
|
like: fp,
|
||||||
|
likeViaRepost: fp,
|
||||||
|
mention: fp,
|
||||||
|
quote: fp,
|
||||||
|
reply: fp,
|
||||||
|
repost: fp,
|
||||||
|
repostViaRepost: fp,
|
||||||
|
starterpackJoined: p,
|
||||||
|
subscribedPost: p,
|
||||||
|
unverified: p,
|
||||||
|
verified: { list: false, push: false },
|
||||||
|
}
|
||||||
|
// Stored all the defaults.
|
||||||
|
const expectedDb1 = expectedApi1
|
||||||
|
await getAndAssert(expectedApi1, expectedDb1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('stores the preferences setting the defaults', async () => {
|
||||||
|
const actorDid = sc.dids.carol
|
||||||
|
|
||||||
|
const putAndAssert = async (
|
||||||
|
input: InputSchema,
|
||||||
|
expected: Preferences,
|
||||||
|
) => {
|
||||||
|
const { data } = await agent.app.bsky.notification.putPreferencesV2(
|
||||||
|
input,
|
||||||
|
{
|
||||||
|
encoding: 'application/json',
|
||||||
|
headers: await network.serviceHeaders(
|
||||||
|
actorDid,
|
||||||
|
ids.AppBskyNotificationPutPreferencesV2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await network.processAll()
|
||||||
|
expect(data.preferences).toStrictEqual(expected)
|
||||||
|
|
||||||
|
const dbResult = await db.db
|
||||||
|
.selectFrom('private_data')
|
||||||
|
.selectAll()
|
||||||
|
.where('actorDid', '=', actorDid)
|
||||||
|
.where('namespace', '=', 'app.bsky.notification.defs#preferences')
|
||||||
|
.where('key', '=', 'self')
|
||||||
|
.executeTakeFirstOrThrow()
|
||||||
|
expect(dbResult).toStrictEqual({
|
||||||
|
actorDid: actorDid,
|
||||||
|
namespace: 'app.bsky.notification.defs#preferences',
|
||||||
|
key: 'self',
|
||||||
|
indexedAt: expect.any(String),
|
||||||
|
payload: expect.anything(), // Better to compare payload parsed.
|
||||||
|
updatedAt: expect.any(String),
|
||||||
|
})
|
||||||
|
expect(JSON.parse(dbResult.payload)).toStrictEqual({
|
||||||
|
$type: 'app.bsky.notification.defs#preferences',
|
||||||
|
...expected,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const input0 = {
|
||||||
|
chat: {
|
||||||
|
push: false,
|
||||||
|
filter: 'accepted',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const expected0: Preferences = {
|
||||||
|
chat: input0.chat,
|
||||||
|
follow: fp,
|
||||||
|
like: fp,
|
||||||
|
likeViaRepost: fp,
|
||||||
|
mention: fp,
|
||||||
|
quote: fp,
|
||||||
|
reply: fp,
|
||||||
|
repost: fp,
|
||||||
|
repostViaRepost: fp,
|
||||||
|
starterpackJoined: p,
|
||||||
|
subscribedPost: p,
|
||||||
|
unverified: p,
|
||||||
|
verified: p,
|
||||||
|
}
|
||||||
|
await putAndAssert(input0, expected0)
|
||||||
|
|
||||||
|
const input1 = {
|
||||||
|
mention: {
|
||||||
|
list: false,
|
||||||
|
push: false,
|
||||||
|
filter: 'follows',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const expected1: Preferences = {
|
||||||
|
// Kept from the previous call.
|
||||||
|
chat: input0.chat,
|
||||||
|
follow: fp,
|
||||||
|
like: fp,
|
||||||
|
likeViaRepost: fp,
|
||||||
|
mention: input1.mention,
|
||||||
|
quote: fp,
|
||||||
|
reply: fp,
|
||||||
|
repost: fp,
|
||||||
|
repostViaRepost: fp,
|
||||||
|
starterpackJoined: p,
|
||||||
|
subscribedPost: p,
|
||||||
|
unverified: p,
|
||||||
|
verified: p,
|
||||||
|
}
|
||||||
|
await putAndAssert(input1, expected1)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const clearPrivateData = async (db: Database) => {
|
||||||
|
await db.db.deleteFrom('private_data').execute()
|
||||||
|
}
|
||||||
|
@ -82,6 +82,17 @@ const validateOp = (req: PutOperationRequest): Operation => {
|
|||||||
throw new ConnectError('operation method is invalid', Code.InvalidArgument)
|
throw new ConnectError('operation method is invalid', Code.InvalidArgument)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.method === Method.CREATE || req.method === Method.UPDATE) {
|
||||||
|
try {
|
||||||
|
JSON.parse(new TextDecoder().decode(req.payload))
|
||||||
|
} catch (error) {
|
||||||
|
throw new ConnectError(
|
||||||
|
'payload must be a valid JSON when method is CREATE or UPDATE',
|
||||||
|
Code.InvalidArgument,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (req.method === Method.DELETE && req.payload.length > 0) {
|
if (req.method === Method.DELETE && req.payload.length > 0) {
|
||||||
throw new ConnectError(
|
throw new ConnectError(
|
||||||
'cannot specify a payload when method is DELETE',
|
'cannot specify a payload when method is DELETE',
|
||||||
|
@ -16,6 +16,10 @@ describe('operations', () => {
|
|||||||
let bsync: BsyncService
|
let bsync: BsyncService
|
||||||
let client: BsyncClient
|
let client: BsyncClient
|
||||||
|
|
||||||
|
const validPayload0 = Buffer.from(JSON.stringify({ value: 0 }))
|
||||||
|
const validPayload1 = Buffer.from(JSON.stringify({ value: 1 }))
|
||||||
|
const invalidPayload = Buffer.from('{invalid json}')
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
bsync = await BsyncService.create(
|
bsync = await BsyncService.create(
|
||||||
envToCfg({
|
envToCfg({
|
||||||
@ -55,7 +59,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
await expect(tryPutOperation1).rejects.toEqual(
|
await expect(tryPutOperation1).rejects.toEqual(
|
||||||
new ConnectError('missing auth', Code.Unauthenticated),
|
new ConnectError('missing auth', Code.Unauthenticated),
|
||||||
@ -71,7 +75,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
await expect(tryPutOperation2).rejects.toEqual(
|
await expect(tryPutOperation2).rejects.toEqual(
|
||||||
new ConnectError('invalid api key', Code.Unauthenticated),
|
new ConnectError('invalid api key', Code.Unauthenticated),
|
||||||
@ -85,7 +89,7 @@ describe('operations', () => {
|
|||||||
namespace: 'bad-namespace',
|
namespace: 'bad-namespace',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([]),
|
payload: validPayload0,
|
||||||
}),
|
}),
|
||||||
).rejects.toEqual(
|
).rejects.toEqual(
|
||||||
new ConnectError(
|
new ConnectError(
|
||||||
@ -99,7 +103,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([]),
|
payload: validPayload0,
|
||||||
}),
|
}),
|
||||||
).rejects.toEqual(
|
).rejects.toEqual(
|
||||||
new ConnectError(
|
new ConnectError(
|
||||||
@ -113,7 +117,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: '',
|
key: '',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([]),
|
payload: validPayload0,
|
||||||
}),
|
}),
|
||||||
).rejects.toEqual(
|
).rejects.toEqual(
|
||||||
new ConnectError('operation key is required', Code.InvalidArgument),
|
new ConnectError('operation key is required', Code.InvalidArgument),
|
||||||
@ -124,18 +128,46 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.UNSPECIFIED,
|
method: Method.UNSPECIFIED,
|
||||||
payload: Buffer.from([]),
|
payload: validPayload0,
|
||||||
}),
|
}),
|
||||||
).rejects.toEqual(
|
).rejects.toEqual(
|
||||||
new ConnectError('operation method is invalid', Code.InvalidArgument),
|
new ConnectError('operation method is invalid', Code.InvalidArgument),
|
||||||
)
|
)
|
||||||
|
await expect(
|
||||||
|
client.putOperation({
|
||||||
|
actorDid: 'did:example:a',
|
||||||
|
namespace: 'app.bsky.some.col',
|
||||||
|
key: 'key1',
|
||||||
|
method: Method.CREATE,
|
||||||
|
payload: invalidPayload,
|
||||||
|
}),
|
||||||
|
).rejects.toEqual(
|
||||||
|
new ConnectError(
|
||||||
|
'payload must be a valid JSON when method is CREATE or UPDATE',
|
||||||
|
Code.InvalidArgument,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
await expect(
|
||||||
|
client.putOperation({
|
||||||
|
actorDid: 'did:example:a',
|
||||||
|
namespace: 'app.bsky.some.col',
|
||||||
|
key: 'key1',
|
||||||
|
method: Method.UPDATE,
|
||||||
|
payload: invalidPayload,
|
||||||
|
}),
|
||||||
|
).rejects.toEqual(
|
||||||
|
new ConnectError(
|
||||||
|
'payload must be a valid JSON when method is CREATE or UPDATE',
|
||||||
|
Code.InvalidArgument,
|
||||||
|
),
|
||||||
|
)
|
||||||
await expect(
|
await expect(
|
||||||
client.putOperation({
|
client.putOperation({
|
||||||
actorDid: 'did:example:a',
|
actorDid: 'did:example:a',
|
||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.DELETE,
|
method: Method.DELETE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
}),
|
}),
|
||||||
).rejects.toEqual(
|
).rejects.toEqual(
|
||||||
new ConnectError(
|
new ConnectError(
|
||||||
@ -151,14 +183,14 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
const res2 = await client.putOperation({
|
const res2 = await client.putOperation({
|
||||||
actorDid: 'did:example:a',
|
actorDid: 'did:example:a',
|
||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.UPDATE,
|
method: Method.UPDATE,
|
||||||
payload: Buffer.from([4, 5, 6]),
|
payload: validPayload1,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(res1.operation?.id).toBe('1')
|
expect(res1.operation?.id).toBe('1')
|
||||||
@ -170,7 +202,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
createdAt: expect.any(Date),
|
createdAt: expect.any(Date),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -179,7 +211,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.UPDATE,
|
method: Method.UPDATE,
|
||||||
payload: Buffer.from([4, 5, 6]),
|
payload: validPayload1,
|
||||||
createdAt: expect.any(Date),
|
createdAt: expect.any(Date),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
@ -191,7 +223,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
|
|
||||||
const op = res.operation
|
const op = res.operation
|
||||||
@ -202,7 +234,7 @@ describe('operations', () => {
|
|||||||
expect(op.namespace).toBe('app.bsky.some.col')
|
expect(op.namespace).toBe('app.bsky.some.col')
|
||||||
expect(op.key).toBe('key1')
|
expect(op.key).toBe('key1')
|
||||||
expect(op.method).toBe(Method.CREATE)
|
expect(op.method).toBe(Method.CREATE)
|
||||||
expect(op.payload).toEqual(Uint8Array.from([1, 2, 3]))
|
expect(op.payload).toEqual(new Uint8Array(validPayload0))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -237,7 +269,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +298,7 @@ describe('operations', () => {
|
|||||||
namespace: 'app.bsky.some.col',
|
namespace: 'app.bsky.some.col',
|
||||||
key: 'key1',
|
key: 'key1',
|
||||||
method: Method.CREATE,
|
method: Method.CREATE,
|
||||||
payload: Buffer.from([1, 2, 3]),
|
payload: validPayload0,
|
||||||
})
|
})
|
||||||
const res = await scanPromise
|
const res = await scanPromise
|
||||||
expect(res.operations.length).toEqual(1)
|
expect(res.operations.length).toEqual(1)
|
||||||
|
24
packages/ozone/src/lexicon/index.ts
generated
24
packages/ozone/src/lexicon/index.ts
generated
@ -138,9 +138,11 @@ import * as AppBskyGraphUnmuteActor from './types/app/bsky/graph/unmuteActor.js'
|
|||||||
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
||||||
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
||||||
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
||||||
|
import * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js'
|
||||||
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
||||||
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
||||||
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
||||||
|
import * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js'
|
||||||
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
||||||
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
||||||
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
||||||
@ -1903,6 +1905,17 @@ export class AppBskyNotificationNS {
|
|||||||
this._server = server
|
this._server = server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreferences<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationGetPreferences.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationGetPreferences.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.getPreferences' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
getUnreadCount<AV extends AuthVerifier>(
|
getUnreadCount<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
@ -1936,6 +1949,17 @@ export class AppBskyNotificationNS {
|
|||||||
return this._server.xrpc.method(nsid, cfg)
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putPreferencesV2<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationPutPreferencesV2.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationPutPreferencesV2.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.putPreferencesV2' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
registerPush<AV extends AuthVerifier>(
|
registerPush<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
|
227
packages/ozone/src/lexicon/lexicons.ts
generated
227
packages/ozone/src/lexicon/lexicons.ts
generated
@ -9732,6 +9732,147 @@ export const schemaDict = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {},
|
properties: {},
|
||||||
},
|
},
|
||||||
|
chatPreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'accepted'],
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filterablePreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'list', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'follows'],
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['list', 'push'],
|
||||||
|
properties: {
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
type: 'object',
|
||||||
|
required: [
|
||||||
|
'chat',
|
||||||
|
'follow',
|
||||||
|
'like',
|
||||||
|
'likeViaRepost',
|
||||||
|
'mention',
|
||||||
|
'quote',
|
||||||
|
'reply',
|
||||||
|
'repost',
|
||||||
|
'repostViaRepost',
|
||||||
|
'starterpackJoined',
|
||||||
|
'subscribedPost',
|
||||||
|
'unverified',
|
||||||
|
'verified',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AppBskyNotificationGetPreferences: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.getPreferences',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'query',
|
||||||
|
description:
|
||||||
|
'Get notification-related preferences for an account. Requires auth.',
|
||||||
|
parameters: {
|
||||||
|
type: 'params',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppBskyNotificationGetUnreadCount: {
|
AppBskyNotificationGetUnreadCount: {
|
||||||
@ -9924,6 +10065,90 @@ export const schemaDict = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AppBskyNotificationPutPreferencesV2: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.putPreferencesV2',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'procedure',
|
||||||
|
description:
|
||||||
|
'Set notification-related preferences for an account. Requires auth.',
|
||||||
|
input: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
AppBskyNotificationRegisterPush: {
|
AppBskyNotificationRegisterPush: {
|
||||||
lexicon: 1,
|
lexicon: 1,
|
||||||
id: 'app.bsky.notification.registerPush',
|
id: 'app.bsky.notification.registerPush',
|
||||||
@ -16557,10 +16782,12 @@ export const ids = {
|
|||||||
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
||||||
AppBskyLabelerService: 'app.bsky.labeler.service',
|
AppBskyLabelerService: 'app.bsky.labeler.service',
|
||||||
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
||||||
|
AppBskyNotificationGetPreferences: 'app.bsky.notification.getPreferences',
|
||||||
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
||||||
AppBskyNotificationListNotifications:
|
AppBskyNotificationListNotifications:
|
||||||
'app.bsky.notification.listNotifications',
|
'app.bsky.notification.listNotifications',
|
||||||
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
||||||
|
AppBskyNotificationPutPreferencesV2: 'app.bsky.notification.putPreferencesV2',
|
||||||
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
||||||
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
||||||
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
||||||
|
@ -27,3 +27,79 @@ export function isRecordDeleted<V>(v: V) {
|
|||||||
export function validateRecordDeleted<V>(v: V) {
|
export function validateRecordDeleted<V>(v: V) {
|
||||||
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChatPreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#chatPreference'
|
||||||
|
filter: 'all' | 'accepted' | (string & {})
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashChatPreference = 'chatPreference'
|
||||||
|
|
||||||
|
export function isChatPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateChatPreference<V>(v: V) {
|
||||||
|
return validate<ChatPreference & V>(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterablePreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#filterablePreference'
|
||||||
|
filter: 'all' | 'follows' | (string & {})
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashFilterablePreference = 'filterablePreference'
|
||||||
|
|
||||||
|
export function isFilterablePreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateFilterablePreference<V>(v: V) {
|
||||||
|
return validate<FilterablePreference & V>(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preference {
|
||||||
|
$type?: 'app.bsky.notification.defs#preference'
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreference = 'preference'
|
||||||
|
|
||||||
|
export function isPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreference<V>(v: V) {
|
||||||
|
return validate<Preference & V>(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preferences {
|
||||||
|
$type?: 'app.bsky.notification.defs#preferences'
|
||||||
|
chat: ChatPreference
|
||||||
|
follow: FilterablePreference
|
||||||
|
like: FilterablePreference
|
||||||
|
likeViaRepost: FilterablePreference
|
||||||
|
mention: FilterablePreference
|
||||||
|
quote: FilterablePreference
|
||||||
|
reply: FilterablePreference
|
||||||
|
repost: FilterablePreference
|
||||||
|
repostViaRepost: FilterablePreference
|
||||||
|
starterpackJoined: Preference
|
||||||
|
subscribedPost: Preference
|
||||||
|
unverified: Preference
|
||||||
|
verified: Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreferences = 'preferences'
|
||||||
|
|
||||||
|
export function isPreferences<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreferences<V>(v: V) {
|
||||||
|
return validate<Preferences & V>(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
52
packages/ozone/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
52
packages/ozone/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.getPreferences'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export type InputSchema = undefined
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerInput = undefined
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
69
packages/ozone/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
69
packages/ozone/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.putPreferencesV2'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export interface InputSchema {
|
||||||
|
chat?: AppBskyNotificationDefs.ChatPreference
|
||||||
|
follow?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
like?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
likeViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
mention?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
quote?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
reply?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repostViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
starterpackJoined?: AppBskyNotificationDefs.Preference
|
||||||
|
subscribedPost?: AppBskyNotificationDefs.Preference
|
||||||
|
unverified?: AppBskyNotificationDefs.Preference
|
||||||
|
verified?: AppBskyNotificationDefs.Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerInput {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: InputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
24
packages/pds/src/lexicon/index.ts
generated
24
packages/pds/src/lexicon/index.ts
generated
@ -138,9 +138,11 @@ import * as AppBskyGraphUnmuteActor from './types/app/bsky/graph/unmuteActor.js'
|
|||||||
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
import * as AppBskyGraphUnmuteActorList from './types/app/bsky/graph/unmuteActorList.js'
|
||||||
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
import * as AppBskyGraphUnmuteThread from './types/app/bsky/graph/unmuteThread.js'
|
||||||
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
import * as AppBskyLabelerGetServices from './types/app/bsky/labeler/getServices.js'
|
||||||
|
import * as AppBskyNotificationGetPreferences from './types/app/bsky/notification/getPreferences.js'
|
||||||
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
import * as AppBskyNotificationGetUnreadCount from './types/app/bsky/notification/getUnreadCount.js'
|
||||||
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
import * as AppBskyNotificationListNotifications from './types/app/bsky/notification/listNotifications.js'
|
||||||
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
import * as AppBskyNotificationPutPreferences from './types/app/bsky/notification/putPreferences.js'
|
||||||
|
import * as AppBskyNotificationPutPreferencesV2 from './types/app/bsky/notification/putPreferencesV2.js'
|
||||||
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush.js'
|
||||||
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
||||||
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
||||||
@ -1903,6 +1905,17 @@ export class AppBskyNotificationNS {
|
|||||||
this._server = server
|
this._server = server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreferences<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationGetPreferences.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationGetPreferences.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.getPreferences' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
getUnreadCount<AV extends AuthVerifier>(
|
getUnreadCount<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
@ -1936,6 +1949,17 @@ export class AppBskyNotificationNS {
|
|||||||
return this._server.xrpc.method(nsid, cfg)
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putPreferencesV2<AV extends AuthVerifier>(
|
||||||
|
cfg: ConfigOf<
|
||||||
|
AV,
|
||||||
|
AppBskyNotificationPutPreferencesV2.Handler<ExtractAuth<AV>>,
|
||||||
|
AppBskyNotificationPutPreferencesV2.HandlerReqCtx<ExtractAuth<AV>>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const nsid = 'app.bsky.notification.putPreferencesV2' // @ts-ignore
|
||||||
|
return this._server.xrpc.method(nsid, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
registerPush<AV extends AuthVerifier>(
|
registerPush<AV extends AuthVerifier>(
|
||||||
cfg: ConfigOf<
|
cfg: ConfigOf<
|
||||||
AV,
|
AV,
|
||||||
|
227
packages/pds/src/lexicon/lexicons.ts
generated
227
packages/pds/src/lexicon/lexicons.ts
generated
@ -9732,6 +9732,147 @@ export const schemaDict = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {},
|
properties: {},
|
||||||
},
|
},
|
||||||
|
chatPreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'accepted'],
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filterablePreference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['filter', 'list', 'push'],
|
||||||
|
properties: {
|
||||||
|
filter: {
|
||||||
|
type: 'string',
|
||||||
|
knownValues: ['all', 'follows'],
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preference: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['list', 'push'],
|
||||||
|
properties: {
|
||||||
|
list: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
push: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preferences: {
|
||||||
|
type: 'object',
|
||||||
|
required: [
|
||||||
|
'chat',
|
||||||
|
'follow',
|
||||||
|
'like',
|
||||||
|
'likeViaRepost',
|
||||||
|
'mention',
|
||||||
|
'quote',
|
||||||
|
'reply',
|
||||||
|
'repost',
|
||||||
|
'repostViaRepost',
|
||||||
|
'starterpackJoined',
|
||||||
|
'subscribedPost',
|
||||||
|
'unverified',
|
||||||
|
'verified',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AppBskyNotificationGetPreferences: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.getPreferences',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'query',
|
||||||
|
description:
|
||||||
|
'Get notification-related preferences for an account. Requires auth.',
|
||||||
|
parameters: {
|
||||||
|
type: 'params',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppBskyNotificationGetUnreadCount: {
|
AppBskyNotificationGetUnreadCount: {
|
||||||
@ -9924,6 +10065,90 @@ export const schemaDict = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AppBskyNotificationPutPreferencesV2: {
|
||||||
|
lexicon: 1,
|
||||||
|
id: 'app.bsky.notification.putPreferencesV2',
|
||||||
|
defs: {
|
||||||
|
main: {
|
||||||
|
type: 'procedure',
|
||||||
|
description:
|
||||||
|
'Set notification-related preferences for an account. Requires auth.',
|
||||||
|
input: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
chat: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#chatPreference',
|
||||||
|
},
|
||||||
|
follow: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
like: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
likeViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
mention: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
quote: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
reply: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
repostViaRepost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#filterablePreference',
|
||||||
|
},
|
||||||
|
starterpackJoined: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
subscribedPost: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
unverified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
verified: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preference',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
encoding: 'application/json',
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['preferences'],
|
||||||
|
properties: {
|
||||||
|
preferences: {
|
||||||
|
type: 'ref',
|
||||||
|
ref: 'lex:app.bsky.notification.defs#preferences',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
AppBskyNotificationRegisterPush: {
|
AppBskyNotificationRegisterPush: {
|
||||||
lexicon: 1,
|
lexicon: 1,
|
||||||
id: 'app.bsky.notification.registerPush',
|
id: 'app.bsky.notification.registerPush',
|
||||||
@ -16557,10 +16782,12 @@ export const ids = {
|
|||||||
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
|
||||||
AppBskyLabelerService: 'app.bsky.labeler.service',
|
AppBskyLabelerService: 'app.bsky.labeler.service',
|
||||||
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
AppBskyNotificationDefs: 'app.bsky.notification.defs',
|
||||||
|
AppBskyNotificationGetPreferences: 'app.bsky.notification.getPreferences',
|
||||||
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
AppBskyNotificationGetUnreadCount: 'app.bsky.notification.getUnreadCount',
|
||||||
AppBskyNotificationListNotifications:
|
AppBskyNotificationListNotifications:
|
||||||
'app.bsky.notification.listNotifications',
|
'app.bsky.notification.listNotifications',
|
||||||
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
AppBskyNotificationPutPreferences: 'app.bsky.notification.putPreferences',
|
||||||
|
AppBskyNotificationPutPreferencesV2: 'app.bsky.notification.putPreferencesV2',
|
||||||
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
AppBskyNotificationRegisterPush: 'app.bsky.notification.registerPush',
|
||||||
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
AppBskyNotificationUpdateSeen: 'app.bsky.notification.updateSeen',
|
||||||
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
AppBskyRichtextFacet: 'app.bsky.richtext.facet',
|
||||||
|
@ -27,3 +27,79 @@ export function isRecordDeleted<V>(v: V) {
|
|||||||
export function validateRecordDeleted<V>(v: V) {
|
export function validateRecordDeleted<V>(v: V) {
|
||||||
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
return validate<RecordDeleted & V>(v, id, hashRecordDeleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChatPreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#chatPreference'
|
||||||
|
filter: 'all' | 'accepted' | (string & {})
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashChatPreference = 'chatPreference'
|
||||||
|
|
||||||
|
export function isChatPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateChatPreference<V>(v: V) {
|
||||||
|
return validate<ChatPreference & V>(v, id, hashChatPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterablePreference {
|
||||||
|
$type?: 'app.bsky.notification.defs#filterablePreference'
|
||||||
|
filter: 'all' | 'follows' | (string & {})
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashFilterablePreference = 'filterablePreference'
|
||||||
|
|
||||||
|
export function isFilterablePreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateFilterablePreference<V>(v: V) {
|
||||||
|
return validate<FilterablePreference & V>(v, id, hashFilterablePreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preference {
|
||||||
|
$type?: 'app.bsky.notification.defs#preference'
|
||||||
|
list: boolean
|
||||||
|
push: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreference = 'preference'
|
||||||
|
|
||||||
|
export function isPreference<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreference<V>(v: V) {
|
||||||
|
return validate<Preference & V>(v, id, hashPreference)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Preferences {
|
||||||
|
$type?: 'app.bsky.notification.defs#preferences'
|
||||||
|
chat: ChatPreference
|
||||||
|
follow: FilterablePreference
|
||||||
|
like: FilterablePreference
|
||||||
|
likeViaRepost: FilterablePreference
|
||||||
|
mention: FilterablePreference
|
||||||
|
quote: FilterablePreference
|
||||||
|
reply: FilterablePreference
|
||||||
|
repost: FilterablePreference
|
||||||
|
repostViaRepost: FilterablePreference
|
||||||
|
starterpackJoined: Preference
|
||||||
|
subscribedPost: Preference
|
||||||
|
unverified: Preference
|
||||||
|
verified: Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashPreferences = 'preferences'
|
||||||
|
|
||||||
|
export function isPreferences<V>(v: V) {
|
||||||
|
return is$typed(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validatePreferences<V>(v: V) {
|
||||||
|
return validate<Preferences & V>(v, id, hashPreferences)
|
||||||
|
}
|
||||||
|
52
packages/pds/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
52
packages/pds/src/lexicon/types/app/bsky/notification/getPreferences.ts
generated
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.getPreferences'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export type InputSchema = undefined
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerInput = undefined
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
69
packages/pds/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
69
packages/pds/src/lexicon/types/app/bsky/notification/putPreferencesV2.ts
generated
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* GENERATED CODE - DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
import express from 'express'
|
||||||
|
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
||||||
|
import { CID } from 'multiformats/cid'
|
||||||
|
import { validate as _validate } from '../../../../lexicons'
|
||||||
|
import {
|
||||||
|
type $Typed,
|
||||||
|
is$typed as _is$typed,
|
||||||
|
type OmitKey,
|
||||||
|
} from '../../../../util'
|
||||||
|
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
||||||
|
import type * as AppBskyNotificationDefs from './defs.js'
|
||||||
|
|
||||||
|
const is$typed = _is$typed,
|
||||||
|
validate = _validate
|
||||||
|
const id = 'app.bsky.notification.putPreferencesV2'
|
||||||
|
|
||||||
|
export interface QueryParams {}
|
||||||
|
|
||||||
|
export interface InputSchema {
|
||||||
|
chat?: AppBskyNotificationDefs.ChatPreference
|
||||||
|
follow?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
like?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
likeViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
mention?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
quote?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
reply?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
repostViaRepost?: AppBskyNotificationDefs.FilterablePreference
|
||||||
|
starterpackJoined?: AppBskyNotificationDefs.Preference
|
||||||
|
subscribedPost?: AppBskyNotificationDefs.Preference
|
||||||
|
unverified?: AppBskyNotificationDefs.Preference
|
||||||
|
verified?: AppBskyNotificationDefs.Preference
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OutputSchema {
|
||||||
|
preferences: AppBskyNotificationDefs.Preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerInput {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: InputSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerSuccess {
|
||||||
|
encoding: 'application/json'
|
||||||
|
body: OutputSchema
|
||||||
|
headers?: { [key: string]: string }
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HandlerError {
|
||||||
|
status: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
||||||
|
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
||||||
|
auth: HA
|
||||||
|
params: QueryParams
|
||||||
|
input: HandlerInput
|
||||||
|
req: express.Request
|
||||||
|
res: express.Response
|
||||||
|
resetRouteRateLimits: () => Promise<void>
|
||||||
|
}
|
||||||
|
export type Handler<HA extends HandlerAuth = never> = (
|
||||||
|
ctx: HandlerReqCtx<HA>,
|
||||||
|
) => Promise<HandlerOutput> | HandlerOutput
|
Loading…
x
Reference in New Issue
Block a user