@atproto/bsky 0.0.209 → 0.0.211
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE.txt +1 -1
- package/dist/api/app/bsky/draft/createDraft.d.ts +4 -0
- package/dist/api/app/bsky/draft/createDraft.d.ts.map +1 -0
- package/dist/api/app/bsky/draft/createDraft.js +38 -0
- package/dist/api/app/bsky/draft/createDraft.js.map +1 -0
- package/dist/api/app/bsky/draft/deleteDraft.d.ts +4 -0
- package/dist/api/app/bsky/draft/deleteDraft.d.ts.map +1 -0
- package/dist/api/app/bsky/draft/deleteDraft.js +19 -0
- package/dist/api/app/bsky/draft/deleteDraft.js.map +1 -0
- package/dist/api/app/bsky/draft/getDrafts.d.ts +4 -0
- package/dist/api/app/bsky/draft/getDrafts.d.ts.map +1 -0
- package/dist/api/app/bsky/draft/getDrafts.js +36 -0
- package/dist/api/app/bsky/draft/getDrafts.js.map +1 -0
- package/dist/api/app/bsky/draft/updateDraft.d.ts +4 -0
- package/dist/api/app/bsky/draft/updateDraft.d.ts.map +1 -0
- package/dist/api/app/bsky/draft/updateDraft.js +24 -0
- package/dist/api/app/bsky/draft/updateDraft.js.map +1 -0
- package/dist/api/app/bsky/feed/searchPosts.js +3 -3
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +9 -8
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +3 -4
- package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +9 -8
- package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +37 -20
- package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js +6 -2
- package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getTrends.js +9 -8
- package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +10 -0
- package/dist/api/index.js.map +1 -1
- package/dist/config.d.ts +6 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -21
- package/dist/config.js.map +1 -1
- package/dist/data-plane/bsync/index.js +38 -0
- package/dist/data-plane/bsync/index.js.map +1 -1
- package/dist/data-plane/server/db/database-schema.d.ts +2 -1
- package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
- package/dist/data-plane/server/db/database-schema.js.map +1 -1
- package/dist/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.d.ts +4 -0
- package/dist/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.d.ts.map +1 -0
- package/dist/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.js +25 -0
- package/dist/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.js.map +1 -0
- package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
- package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
- package/dist/data-plane/server/db/migrations/index.js +2 -1
- package/dist/data-plane/server/db/migrations/index.js.map +1 -1
- package/dist/data-plane/server/db/pagination.d.ts +9 -0
- package/dist/data-plane/server/db/pagination.d.ts.map +1 -1
- package/dist/data-plane/server/db/pagination.js +7 -1
- package/dist/data-plane/server/db/pagination.js.map +1 -1
- package/dist/data-plane/server/db/tables/draft.d.ts +12 -0
- package/dist/data-plane/server/db/tables/draft.d.ts.map +1 -0
- package/dist/data-plane/server/db/tables/draft.js +5 -0
- package/dist/data-plane/server/db/tables/draft.js.map +1 -0
- package/dist/data-plane/server/indexing/index.d.ts +2 -0
- package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
- package/dist/data-plane/server/indexing/index.js +2 -0
- package/dist/data-plane/server/indexing/index.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts +7 -0
- package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts.map +1 -0
- package/dist/data-plane/server/indexing/plugins/germ-declaration.js +75 -0
- package/dist/data-plane/server/indexing/plugins/germ-declaration.js.map +1 -0
- package/dist/data-plane/server/routes/drafts.d.ts +6 -0
- package/dist/data-plane/server/routes/drafts.d.ts.map +1 -0
- package/dist/data-plane/server/routes/drafts.js +30 -0
- package/dist/data-plane/server/routes/drafts.js.map +1 -0
- package/dist/data-plane/server/routes/index.d.ts.map +1 -1
- package/dist/data-plane/server/routes/index.js +2 -0
- package/dist/data-plane/server/routes/index.js.map +1 -1
- package/dist/data-plane/server/routes/interactions.d.ts.map +1 -1
- package/dist/data-plane/server/routes/interactions.js +6 -0
- package/dist/data-plane/server/routes/interactions.js.map +1 -1
- package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
- package/dist/data-plane/server/routes/profile.js +5 -1
- package/dist/data-plane/server/routes/profile.js.map +1 -1
- package/dist/data-plane/server/routes/records.d.ts.map +1 -1
- package/dist/data-plane/server/routes/records.js +1 -0
- package/dist/data-plane/server/routes/records.js.map +1 -1
- package/dist/data-plane/server/util.d.ts +6 -6
- package/dist/feature-gates.d.ts +17 -14
- package/dist/feature-gates.d.ts.map +1 -1
- package/dist/feature-gates.js +67 -35
- package/dist/feature-gates.js.map +1 -1
- package/dist/hydration/actor.d.ts +5 -0
- package/dist/hydration/actor.d.ts.map +1 -1
- package/dist/hydration/actor.js +13 -0
- package/dist/hydration/actor.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +1 -1
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +6 -1
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +18 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +55 -1
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +1156 -278
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +455 -2
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +19 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js +18 -0
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/draft/createDraft.d.ts +27 -0
- package/dist/lexicon/types/app/bsky/draft/createDraft.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/createDraft.js +7 -0
- package/dist/lexicon/types/app/bsky/draft/createDraft.js.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/defs.d.ts +106 -0
- package/dist/lexicon/types/app/bsky/draft/defs.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/defs.js +97 -0
- package/dist/lexicon/types/app/bsky/draft/defs.js.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/deleteDraft.d.ts +14 -0
- package/dist/lexicon/types/app/bsky/draft/deleteDraft.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/deleteDraft.js +7 -0
- package/dist/lexicon/types/app/bsky/draft/deleteDraft.js.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/getDrafts.d.ts +24 -0
- package/dist/lexicon/types/app/bsky/draft/getDrafts.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/getDrafts.js +7 -0
- package/dist/lexicon/types/app/bsky/draft/getDrafts.js.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/updateDraft.d.ts +15 -0
- package/dist/lexicon/types/app/bsky/draft/updateDraft.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/draft/updateDraft.js +7 -0
- package/dist/lexicon/types/app/bsky/draft/updateDraft.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedUsers.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedUsersSkeleton.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedUsersSkeleton.js.map +1 -1
- package/dist/lexicon/types/com/germnetwork/declaration.d.ts +24 -0
- package/dist/lexicon/types/com/germnetwork/declaration.d.ts.map +1 -0
- package/dist/lexicon/types/com/germnetwork/declaration.js +27 -0
- package/dist/lexicon/types/com/germnetwork/declaration.js.map +1 -0
- package/dist/proto/bsky_connect.d.ts +22 -1
- package/dist/proto/bsky_connect.d.ts.map +1 -1
- package/dist/proto/bsky_connect.js +21 -0
- package/dist/proto/bsky_connect.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +119 -0
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +343 -5
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/stash.d.ts +1 -0
- package/dist/stash.d.ts.map +1 -1
- package/dist/stash.js +1 -0
- package/dist/stash.js.map +1 -1
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +15 -3
- package/dist/views/index.js.map +1 -1
- package/package.json +10 -10
- package/proto/bsky.proto +39 -1
- package/src/api/app/bsky/draft/createDraft.ts +46 -0
- package/src/api/app/bsky/draft/deleteDraft.ts +19 -0
- package/src/api/app/bsky/draft/getDrafts.ts +46 -0
- package/src/api/app/bsky/draft/updateDraft.ts +26 -0
- package/src/api/app/bsky/feed/searchPosts.ts +4 -4
- package/src/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +10 -10
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +2 -2
- package/src/api/app/bsky/unspecced/getSuggestedFeeds.ts +4 -5
- package/src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts +10 -10
- package/src/api/app/bsky/unspecced/getSuggestedUsers.ts +60 -25
- package/src/api/app/bsky/unspecced/getTrendingTopics.ts +9 -5
- package/src/api/app/bsky/unspecced/getTrends.ts +10 -10
- package/src/api/index.ts +10 -0
- package/src/config.ts +23 -26
- package/src/data-plane/bsync/index.ts +47 -0
- package/src/data-plane/server/db/database-schema.ts +3 -1
- package/src/data-plane/server/db/migrations/20260112T133951271Z-add-drafts.ts +24 -0
- package/src/data-plane/server/db/migrations/index.ts +1 -0
- package/src/data-plane/server/db/pagination.ts +8 -0
- package/src/data-plane/server/db/tables/draft.ts +11 -0
- package/src/data-plane/server/indexing/index.ts +3 -0
- package/src/data-plane/server/indexing/plugins/germ-declaration.ts +63 -0
- package/src/data-plane/server/routes/drafts.ts +37 -0
- package/src/data-plane/server/routes/index.ts +2 -0
- package/src/data-plane/server/routes/interactions.ts +6 -0
- package/src/data-plane/server/routes/profile.ts +8 -0
- package/src/data-plane/server/routes/records.ts +1 -0
- package/src/feature-gates.ts +83 -35
- package/src/hydration/actor.ts +26 -2
- package/src/hydration/hydrator.ts +8 -1
- package/src/index.ts +3 -3
- package/src/lexicon/index.ts +72 -0
- package/src/lexicon/lexicons.ts +465 -2
- package/src/lexicon/types/app/bsky/actor/defs.ts +37 -0
- package/src/lexicon/types/app/bsky/draft/createDraft.ts +46 -0
- package/src/lexicon/types/app/bsky/draft/defs.ts +208 -0
- package/src/lexicon/types/app/bsky/draft/deleteDraft.ts +33 -0
- package/src/lexicon/types/app/bsky/draft/getDrafts.ts +42 -0
- package/src/lexicon/types/app/bsky/draft/updateDraft.ts +34 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestedUsers.ts +1 -1
- package/src/lexicon/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts +1 -1
- package/src/lexicon/types/com/germnetwork/declaration.ts +53 -0
- package/src/proto/bsky_connect.ts +22 -1
- package/src/proto/bsky_pb.ts +235 -0
- package/src/stash.ts +3 -0
- package/src/views/index.ts +15 -3
- package/tests/views/__snapshots__/profile.test.ts.snap +7 -0
- package/tests/views/age-assurance-v2.test.ts +0 -2
- package/tests/views/age-assurance.test.ts +0 -2
- package/tests/views/drafts.test.ts +293 -0
- package/tests/views/profile.test.ts +58 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '../../../../hydration/hydrator'
|
|
10
10
|
import { Server } from '../../../../lexicon'
|
|
11
11
|
import { SkeletonTrend } from '../../../../lexicon/types/app/bsky/unspecced/defs'
|
|
12
|
-
import { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/
|
|
12
|
+
import { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/getTrends'
|
|
13
13
|
import {
|
|
14
14
|
HydrationFnInput,
|
|
15
15
|
PresentationFnInput,
|
|
@@ -33,11 +33,10 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
33
33
|
? req.headers['x-bsky-topics'].join(',')
|
|
34
34
|
: req.headers['x-bsky-topics'],
|
|
35
35
|
})
|
|
36
|
-
const
|
|
36
|
+
const result = await getTrends(
|
|
37
37
|
{
|
|
38
38
|
...params,
|
|
39
|
-
|
|
40
|
-
hydrateCtx: hydrateCtx.copy({ viewer }),
|
|
39
|
+
hydrateCtx,
|
|
41
40
|
headers,
|
|
42
41
|
},
|
|
43
42
|
ctx,
|
|
@@ -56,7 +55,7 @@ const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
|
|
|
56
55
|
const res = await ctx.topicsAgent.app.bsky.unspecced.getTrendsSkeleton(
|
|
57
56
|
{
|
|
58
57
|
limit: params.limit,
|
|
59
|
-
viewer: params.viewer,
|
|
58
|
+
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
60
59
|
},
|
|
61
60
|
{
|
|
62
61
|
headers: params.headers,
|
|
@@ -78,8 +77,9 @@ const hydration = async (
|
|
|
78
77
|
}
|
|
79
78
|
dids = dedupeStrs(dids)
|
|
80
79
|
const pairs: Map<string, string[]> = new Map()
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const viewer = params.hydrateCtx.viewer
|
|
81
|
+
if (viewer) {
|
|
82
|
+
pairs.set(viewer, dids)
|
|
83
83
|
}
|
|
84
84
|
const [profileState, bidirectionalBlocks] = await Promise.all([
|
|
85
85
|
ctx.hydrator.hydrateProfilesBasic(dids, params.hydrateCtx),
|
|
@@ -91,12 +91,12 @@ const hydration = async (
|
|
|
91
91
|
|
|
92
92
|
const noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {
|
|
93
93
|
const { skeleton, params, hydration } = input
|
|
94
|
-
|
|
95
|
-
if (!
|
|
94
|
+
const viewer = params.hydrateCtx.viewer
|
|
95
|
+
if (!viewer) {
|
|
96
96
|
return skeleton
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
const blocks = hydration.bidirectionalBlocks?.get(
|
|
99
|
+
const blocks = hydration.bidirectionalBlocks?.get(viewer)
|
|
100
100
|
const filteredSkeleton: SkeletonState = {
|
|
101
101
|
trends: skeleton.trends.map((t) => ({
|
|
102
102
|
...t,
|
package/src/api/index.ts
CHANGED
|
@@ -19,6 +19,10 @@ import removeData from './app/bsky/contact/removeData'
|
|
|
19
19
|
import sendNotification from './app/bsky/contact/sendNotification'
|
|
20
20
|
import startPhoneVerification from './app/bsky/contact/startPhoneVerification'
|
|
21
21
|
import verifyPhone from './app/bsky/contact/verifyPhone'
|
|
22
|
+
import createDraft from './app/bsky/draft/createDraft'
|
|
23
|
+
import deleteDraft from './app/bsky/draft/deleteDraft'
|
|
24
|
+
import getDrafts from './app/bsky/draft/getDrafts'
|
|
25
|
+
import updateDraft from './app/bsky/draft/updateDraft'
|
|
22
26
|
import getActorFeeds from './app/bsky/feed/getActorFeeds'
|
|
23
27
|
import getActorLikes from './app/bsky/feed/getActorLikes'
|
|
24
28
|
import getAuthorFeed from './app/bsky/feed/getAuthorFeed'
|
|
@@ -66,6 +70,7 @@ import putActivitySubscription from './app/bsky/notification/putActivitySubscrip
|
|
|
66
70
|
import putPreferences from './app/bsky/notification/putPreferences'
|
|
67
71
|
import putPreferencesV2 from './app/bsky/notification/putPreferencesV2'
|
|
68
72
|
import registerPush from './app/bsky/notification/registerPush'
|
|
73
|
+
import unregisterPush from './app/bsky/notification/unregisterPush'
|
|
69
74
|
import updateSeen from './app/bsky/notification/updateSeen'
|
|
70
75
|
import getAgeAssuranceState from './app/bsky/unspecced/getAgeAssuranceState'
|
|
71
76
|
import getConfig from './app/bsky/unspecced/getConfig'
|
|
@@ -104,6 +109,10 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
104
109
|
createBookmark(server, ctx)
|
|
105
110
|
deleteBookmark(server, ctx)
|
|
106
111
|
getBookmarks(server, ctx)
|
|
112
|
+
createDraft(server, ctx)
|
|
113
|
+
deleteDraft(server, ctx)
|
|
114
|
+
getDrafts(server, ctx)
|
|
115
|
+
updateDraft(server, ctx)
|
|
107
116
|
dismissMatch(server, ctx)
|
|
108
117
|
getMatches(server, ctx)
|
|
109
118
|
getSyncStatus(server, ctx)
|
|
@@ -172,6 +181,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
172
181
|
putPreferences(server, ctx)
|
|
173
182
|
putPreferencesV2(server, ctx)
|
|
174
183
|
registerPush(server, ctx)
|
|
184
|
+
unregisterPush(server, ctx)
|
|
175
185
|
getConfig(server, ctx)
|
|
176
186
|
getPopularFeedGenerators(server, ctx)
|
|
177
187
|
getTaggedSuggestions(server, ctx)
|
package/src/config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
|
+
import { noUndefinedVals } from '@atproto/common'
|
|
2
3
|
import { subLogger as log } from './logger'
|
|
3
4
|
|
|
4
5
|
type LiveNowConfig = {
|
|
@@ -80,8 +81,8 @@ export interface ServerConfigValues {
|
|
|
80
81
|
indexedAtEpoch?: Date
|
|
81
82
|
// misc/dev
|
|
82
83
|
blobCacheLocation?: string
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
growthBookApiHost?: string
|
|
85
|
+
growthBookClientKey?: string
|
|
85
86
|
// threads
|
|
86
87
|
bigThreadUris: Set<string>
|
|
87
88
|
bigThreadDepth?: number
|
|
@@ -106,6 +107,7 @@ export interface ServerConfigValues {
|
|
|
106
107
|
proxyPreferCompressed?: boolean
|
|
107
108
|
kws?: KwsConfig
|
|
108
109
|
debugFieldAllowedDids: Set<string>
|
|
110
|
+
draftsLimit: number
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
export class ServerConfig {
|
|
@@ -210,14 +212,12 @@ export class ServerConfig {
|
|
|
210
212
|
)
|
|
211
213
|
const modServiceDid = process.env.MOD_SERVICE_DID
|
|
212
214
|
assert(modServiceDid)
|
|
213
|
-
|
|
215
|
+
|
|
216
|
+
const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined
|
|
217
|
+
const growthBookClientKey =
|
|
214
218
|
process.env.NODE_ENV === 'test'
|
|
215
219
|
? 'secret-key'
|
|
216
|
-
: process.env.
|
|
217
|
-
const statsigEnv =
|
|
218
|
-
process.env.NODE_ENV === 'test'
|
|
219
|
-
? 'test'
|
|
220
|
-
: process.env.BSKY_STATSIG_ENV || 'development'
|
|
220
|
+
: process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined
|
|
221
221
|
const clientCheckEmailConfirmed =
|
|
222
222
|
process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'
|
|
223
223
|
const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'
|
|
@@ -322,6 +322,10 @@ export class ServerConfig {
|
|
|
322
322
|
envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),
|
|
323
323
|
)
|
|
324
324
|
|
|
325
|
+
const draftsLimit = process.env.BSKY_DRAFTS_LIMIT
|
|
326
|
+
? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)
|
|
327
|
+
: 500
|
|
328
|
+
|
|
325
329
|
return new ServerConfig({
|
|
326
330
|
version,
|
|
327
331
|
debugMode,
|
|
@@ -365,8 +369,8 @@ export class ServerConfig {
|
|
|
365
369
|
blobRateLimitBypassHostname,
|
|
366
370
|
adminPasswords,
|
|
367
371
|
modServiceDid,
|
|
368
|
-
|
|
369
|
-
|
|
372
|
+
growthBookApiHost,
|
|
373
|
+
growthBookClientKey,
|
|
370
374
|
clientCheckEmailConfirmed,
|
|
371
375
|
topicsEnabled,
|
|
372
376
|
indexedAtEpoch,
|
|
@@ -388,7 +392,8 @@ export class ServerConfig {
|
|
|
388
392
|
proxyPreferCompressed,
|
|
389
393
|
kws,
|
|
390
394
|
debugFieldAllowedDids,
|
|
391
|
-
|
|
395
|
+
draftsLimit,
|
|
396
|
+
...noUndefinedVals(overrides ?? {}),
|
|
392
397
|
})
|
|
393
398
|
}
|
|
394
399
|
|
|
@@ -565,12 +570,12 @@ export class ServerConfig {
|
|
|
565
570
|
return this.cfg.blobCacheLocation
|
|
566
571
|
}
|
|
567
572
|
|
|
568
|
-
get
|
|
569
|
-
return this.cfg.
|
|
573
|
+
get growthBookApiHost() {
|
|
574
|
+
return this.cfg.growthBookApiHost
|
|
570
575
|
}
|
|
571
576
|
|
|
572
|
-
get
|
|
573
|
-
return this.cfg.
|
|
577
|
+
get growthBookClientKey() {
|
|
578
|
+
return this.cfg.growthBookClientKey
|
|
574
579
|
}
|
|
575
580
|
|
|
576
581
|
get clientCheckEmailConfirmed() {
|
|
@@ -656,18 +661,10 @@ export class ServerConfig {
|
|
|
656
661
|
get debugFieldAllowedDids() {
|
|
657
662
|
return this.cfg.debugFieldAllowedDids
|
|
658
663
|
}
|
|
659
|
-
}
|
|
660
664
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
const result = {}
|
|
665
|
-
Object.entries(obj).forEach(([key, val]) => {
|
|
666
|
-
if (val !== undefined) {
|
|
667
|
-
result[key] = val
|
|
668
|
-
}
|
|
669
|
-
})
|
|
670
|
-
return result
|
|
665
|
+
get draftsLimit() {
|
|
666
|
+
return this.cfg.draftsLimit
|
|
667
|
+
}
|
|
671
668
|
}
|
|
672
669
|
|
|
673
670
|
function envList(str: string | undefined): string[] {
|
|
@@ -180,6 +180,8 @@ const createRoutes = (db: Database) => (router: ConnectRouter) =>
|
|
|
180
180
|
await handleAgeAssuranceV2EventOperation(db, req, now)
|
|
181
181
|
} else if (namespace === Namespaces.AppBskyBookmarkDefsBookmark) {
|
|
182
182
|
await handleBookmarkOperation(db, req, now)
|
|
183
|
+
} else if (namespace === Namespaces.AppBskyDraftDefsDraftWithId) {
|
|
184
|
+
await handleDraftOperation(db, req, now)
|
|
183
185
|
}
|
|
184
186
|
} catch (err) {
|
|
185
187
|
httpLogger.warn({ err, namespace }, 'mock bsync put operation failed')
|
|
@@ -415,3 +417,48 @@ const handleBookmarkOperation = async (
|
|
|
415
417
|
})
|
|
416
418
|
}
|
|
417
419
|
}
|
|
420
|
+
|
|
421
|
+
const handleDraftOperation = async (
|
|
422
|
+
db: Database,
|
|
423
|
+
req: PutOperationRequest,
|
|
424
|
+
now: string,
|
|
425
|
+
) => {
|
|
426
|
+
const { actorDid, key, method, payload } = req
|
|
427
|
+
|
|
428
|
+
if (method === Method.CREATE) {
|
|
429
|
+
const payloadString = Buffer.from(payload).toString('utf8')
|
|
430
|
+
|
|
431
|
+
await db.db
|
|
432
|
+
.insertInto('draft')
|
|
433
|
+
.values({
|
|
434
|
+
creator: actorDid,
|
|
435
|
+
key,
|
|
436
|
+
createdAt: now,
|
|
437
|
+
updatedAt: now,
|
|
438
|
+
payload: payloadString,
|
|
439
|
+
})
|
|
440
|
+
.execute()
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (method === Method.UPDATE) {
|
|
444
|
+
const payloadString = Buffer.from(payload).toString('utf8')
|
|
445
|
+
|
|
446
|
+
await db.db
|
|
447
|
+
.updateTable('draft')
|
|
448
|
+
.where('creator', '=', actorDid)
|
|
449
|
+
.where('key', '=', key)
|
|
450
|
+
.set({
|
|
451
|
+
updatedAt: now,
|
|
452
|
+
payload: payloadString,
|
|
453
|
+
})
|
|
454
|
+
.execute()
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (method === Method.DELETE) {
|
|
458
|
+
await db.db
|
|
459
|
+
.deleteFrom('draft')
|
|
460
|
+
.where('creator', '=', actorDid)
|
|
461
|
+
.where('key', '=', key)
|
|
462
|
+
.execute()
|
|
463
|
+
}
|
|
464
|
+
}
|
|
@@ -8,6 +8,7 @@ import * as algo from './tables/algo'
|
|
|
8
8
|
import * as blobTakedown from './tables/blob-takedown'
|
|
9
9
|
import * as bookmark from './tables/bookmark'
|
|
10
10
|
import * as didCache from './tables/did-cache'
|
|
11
|
+
import * as draft from './tables/draft'
|
|
11
12
|
import * as duplicateRecord from './tables/duplicate-record'
|
|
12
13
|
import * as feedGenerator from './tables/feed-generator'
|
|
13
14
|
import * as feedItem from './tables/feed-item'
|
|
@@ -83,6 +84,7 @@ export type DatabaseSchemaType = duplicateRecord.PartialDB &
|
|
|
83
84
|
verification.PartialDB &
|
|
84
85
|
privateData.PartialDB &
|
|
85
86
|
activitySubscription.PartialDB &
|
|
86
|
-
bookmark.PartialDB
|
|
87
|
+
bookmark.PartialDB &
|
|
88
|
+
draft.PartialDB
|
|
87
89
|
|
|
88
90
|
export type DatabaseSchema = Kysely<DatabaseSchemaType>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Kysely } from 'kysely'
|
|
2
|
+
|
|
3
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
+
await db.schema
|
|
5
|
+
.createTable('draft')
|
|
6
|
+
.addColumn('creator', 'varchar', (col) => col.notNull())
|
|
7
|
+
.addColumn('key', 'varchar', (col) => col.notNull())
|
|
8
|
+
.addColumn('createdAt', 'varchar', (col) => col.notNull())
|
|
9
|
+
.addColumn('updatedAt', 'varchar', (col) => col.notNull())
|
|
10
|
+
.addColumn('payload', 'text', (col) => col.notNull())
|
|
11
|
+
.addPrimaryKeyConstraint('draft_pkey', ['creator', 'key'])
|
|
12
|
+
.execute()
|
|
13
|
+
|
|
14
|
+
// Supports getting paginated drafts by updatedAt.
|
|
15
|
+
await db.schema
|
|
16
|
+
.createIndex('draft_creator_updated_at_key_idx')
|
|
17
|
+
.on('draft')
|
|
18
|
+
.columns(['creator', 'updatedAt', 'key'])
|
|
19
|
+
.execute()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
23
|
+
await db.schema.dropTable('draft').execute()
|
|
24
|
+
}
|
|
@@ -56,3 +56,4 @@ export * as _20250627T025331240Z from './20250627T025331240Z-add-actor-age-assur
|
|
|
56
56
|
export * as _20250812T183735692Z from './20250812T183735692Z-add-bookmarks'
|
|
57
57
|
export * as _20250813T174955711Z from './20250813T174955711Z-add-post-agg-bookmarks'
|
|
58
58
|
export * as _20251120T004738098Z from './20251120T004738098Z-update-actor-age-assurance-v2'
|
|
59
|
+
export * as _20260112T133951271Z from './20260112T133951271Z-add-drafts'
|
|
@@ -296,6 +296,14 @@ export class IsoSortAtKey extends IsoTimeKey<{
|
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
+
export class IsoUpdatedAtKey extends IsoTimeKey<{
|
|
300
|
+
updatedAt: string
|
|
301
|
+
}> {
|
|
302
|
+
labelResult(result: { updatedAt: string }) {
|
|
303
|
+
return { primary: result.updatedAt }
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
299
307
|
type KeyResult = { key: string }
|
|
300
308
|
type RkeyLabeledResult = SingleKeyCursor
|
|
301
309
|
|
|
@@ -21,6 +21,7 @@ import * as Block from './plugins/block'
|
|
|
21
21
|
import * as ChatDeclaration from './plugins/chat-declaration'
|
|
22
22
|
import * as FeedGenerator from './plugins/feed-generator'
|
|
23
23
|
import * as Follow from './plugins/follow'
|
|
24
|
+
import * as GermDeclaration from './plugins/germ-declaration'
|
|
24
25
|
import * as Labeler from './plugins/labeler'
|
|
25
26
|
import * as Like from './plugins/like'
|
|
26
27
|
import * as List from './plugins/list'
|
|
@@ -55,6 +56,7 @@ export class IndexingService {
|
|
|
55
56
|
labeler: Labeler.PluginType
|
|
56
57
|
notifDeclaration: NotifDeclaration.PluginType
|
|
57
58
|
chatDeclaration: ChatDeclaration.PluginType
|
|
59
|
+
germDeclaration: GermDeclaration.PluginType
|
|
58
60
|
verification: Verification.PluginType
|
|
59
61
|
status: Status.PluginType
|
|
60
62
|
}
|
|
@@ -81,6 +83,7 @@ export class IndexingService {
|
|
|
81
83
|
labeler: Labeler.makePlugin(this.db, this.background),
|
|
82
84
|
notifDeclaration: NotifDeclaration.makePlugin(this.db, this.background),
|
|
83
85
|
chatDeclaration: ChatDeclaration.makePlugin(this.db, this.background),
|
|
86
|
+
germDeclaration: GermDeclaration.makePlugin(this.db, this.background),
|
|
84
87
|
verification: Verification.makePlugin(this.db, this.background),
|
|
85
88
|
status: Status.makePlugin(this.db, this.background),
|
|
86
89
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid'
|
|
2
|
+
import { AtUri } from '@atproto/syntax'
|
|
3
|
+
import * as lex from '../../../../lexicon/lexicons'
|
|
4
|
+
import { BackgroundQueue } from '../../background'
|
|
5
|
+
import { Database } from '../../db'
|
|
6
|
+
import { DatabaseSchema } from '../../db/database-schema'
|
|
7
|
+
import { RecordProcessor } from '../processor'
|
|
8
|
+
|
|
9
|
+
// @NOTE this indexer is a placeholder to ensure it gets indexed in the generic records table
|
|
10
|
+
|
|
11
|
+
const lexId = lex.ids.ComGermnetworkDeclaration
|
|
12
|
+
|
|
13
|
+
const insertFn = async (
|
|
14
|
+
_db: DatabaseSchema,
|
|
15
|
+
uri: AtUri,
|
|
16
|
+
_cid: CID,
|
|
17
|
+
_obj: unknown,
|
|
18
|
+
_timestamp: string,
|
|
19
|
+
): Promise<unknown | null> => {
|
|
20
|
+
if (uri.rkey !== 'self') return null
|
|
21
|
+
return true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const findDuplicate = async (): Promise<AtUri | null> => {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const notifsForInsert = () => {
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const deleteFn = async (
|
|
33
|
+
_db: DatabaseSchema,
|
|
34
|
+
uri: AtUri,
|
|
35
|
+
): Promise<unknown | null> => {
|
|
36
|
+
if (uri.rkey !== 'self') return null
|
|
37
|
+
return true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const notifsForDelete = () => {
|
|
41
|
+
return { notifs: [], toDelete: [] }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type PluginType = RecordProcessor<unknown, unknown>
|
|
45
|
+
|
|
46
|
+
export const makePlugin = (
|
|
47
|
+
db: Database,
|
|
48
|
+
background: BackgroundQueue,
|
|
49
|
+
): PluginType => {
|
|
50
|
+
const processor = new RecordProcessor(db, background, {
|
|
51
|
+
lexId,
|
|
52
|
+
insertFn,
|
|
53
|
+
findDuplicate,
|
|
54
|
+
deleteFn,
|
|
55
|
+
notifsForInsert,
|
|
56
|
+
notifsForDelete,
|
|
57
|
+
})
|
|
58
|
+
// @TODO use lexicon validation
|
|
59
|
+
processor.assertValidRecord = () => null
|
|
60
|
+
return processor
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default makePlugin
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PlainMessage, Timestamp } from '@bufbuild/protobuf'
|
|
2
|
+
import { ServiceImpl } from '@connectrpc/connect'
|
|
3
|
+
import { Service } from '../../../proto/bsky_connect'
|
|
4
|
+
import { DraftInfo } from '../../../proto/bsky_pb'
|
|
5
|
+
import { Database } from '../db'
|
|
6
|
+
import { IsoUpdatedAtKey } from '../db/pagination'
|
|
7
|
+
|
|
8
|
+
export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
9
|
+
async getActorDrafts(req) {
|
|
10
|
+
const { actorDid, cursor, limit } = req
|
|
11
|
+
const { ref } = db.db.dynamic
|
|
12
|
+
|
|
13
|
+
let builder = db.db
|
|
14
|
+
.selectFrom('draft')
|
|
15
|
+
.where('draft.creator', '=', actorDid)
|
|
16
|
+
.selectAll()
|
|
17
|
+
|
|
18
|
+
const key = new IsoUpdatedAtKey(ref('draft.updatedAt'))
|
|
19
|
+
builder = key.paginate(builder, {
|
|
20
|
+
cursor,
|
|
21
|
+
limit,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const res = await builder.execute()
|
|
25
|
+
return {
|
|
26
|
+
drafts: res.map(
|
|
27
|
+
(d): PlainMessage<DraftInfo> => ({
|
|
28
|
+
key: d.key,
|
|
29
|
+
payload: Buffer.from(d.payload),
|
|
30
|
+
createdAt: Timestamp.fromDate(new Date(d.createdAt)),
|
|
31
|
+
updatedAt: Timestamp.fromDate(new Date(d.updatedAt)),
|
|
32
|
+
}),
|
|
33
|
+
),
|
|
34
|
+
cursor: key.packFromResult(res),
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
})
|
|
@@ -5,6 +5,7 @@ import { Database } from '../db'
|
|
|
5
5
|
import activitySubscription from './activity-subscription'
|
|
6
6
|
import blocks from './blocks'
|
|
7
7
|
import bookmarks from './bookmarks'
|
|
8
|
+
import drafts from './drafts'
|
|
8
9
|
import feedGens from './feed-gens'
|
|
9
10
|
import feeds from './feeds'
|
|
10
11
|
import follows from './follows'
|
|
@@ -34,6 +35,7 @@ export default (db: Database, idResolver: IdResolver) =>
|
|
|
34
35
|
...activitySubscription(db),
|
|
35
36
|
...blocks(db),
|
|
36
37
|
...bookmarks(db),
|
|
38
|
+
...drafts(db),
|
|
37
39
|
...feedGens(db),
|
|
38
40
|
...feeds(db),
|
|
39
41
|
...follows(db),
|
|
@@ -49,6 +49,11 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
49
49
|
.whereRef('creator', '=', ref('profile_agg.did'))
|
|
50
50
|
.select(countAll.as('val'))
|
|
51
51
|
.as('starterPacksCount'),
|
|
52
|
+
db.db
|
|
53
|
+
.selectFrom('draft')
|
|
54
|
+
.whereRef('creator', '=', ref('profile_agg.did'))
|
|
55
|
+
.select(countAll.as('val'))
|
|
56
|
+
.as('draftsCount'),
|
|
52
57
|
])
|
|
53
58
|
.execute()
|
|
54
59
|
const byDid = keyBy(res, 'did')
|
|
@@ -61,6 +66,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
61
66
|
starterPacks: req.dids.map(
|
|
62
67
|
(uri) => byDid.get(uri)?.starterPacksCount ?? 0,
|
|
63
68
|
),
|
|
69
|
+
drafts: req.dids.map((uri) => byDid.get(uri)?.draftsCount ?? 0),
|
|
64
70
|
}
|
|
65
71
|
},
|
|
66
72
|
async getStarterPackCounts(req) {
|
|
@@ -38,6 +38,9 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
38
38
|
const notifDeclarationUris = dids.map(
|
|
39
39
|
(did) => `at://${did}/app.bsky.notification.declaration/self`,
|
|
40
40
|
)
|
|
41
|
+
const germDeclarationUris = dids.map(
|
|
42
|
+
(did) => `at://${did}/com.germnetwork.declaration/self`,
|
|
43
|
+
)
|
|
41
44
|
const { ref } = db.db.dynamic
|
|
42
45
|
const [
|
|
43
46
|
handlesRes,
|
|
@@ -46,6 +49,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
46
49
|
statuses,
|
|
47
50
|
chatDeclarations,
|
|
48
51
|
notifDeclarations,
|
|
52
|
+
germDeclarations,
|
|
49
53
|
] = await Promise.all([
|
|
50
54
|
db.db
|
|
51
55
|
.selectFrom('actor')
|
|
@@ -73,6 +77,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
73
77
|
getRecords(db)({ uris: statusUris }),
|
|
74
78
|
getRecords(db)({ uris: chatDeclarationUris }),
|
|
75
79
|
getRecords(db)({ uris: notifDeclarationUris }),
|
|
80
|
+
getRecords(db)({ uris: germDeclarationUris }),
|
|
76
81
|
])
|
|
77
82
|
|
|
78
83
|
const verificationsBySubjectDid = verificationsReceived.reduce(
|
|
@@ -95,6 +100,8 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
95
100
|
chatDeclarations.records[i].record,
|
|
96
101
|
)
|
|
97
102
|
|
|
103
|
+
const germDeclaration = germDeclarations.records[i]
|
|
104
|
+
|
|
98
105
|
const verifications = verificationsBySubjectDid.get(did) ?? []
|
|
99
106
|
const verifiedBy: VerifiedBy = verifications.reduce((acc, cur) => {
|
|
100
107
|
acc[cur.creator] = {
|
|
@@ -173,6 +180,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
173
180
|
trustedVerifier: row?.trustedVerifier ?? false,
|
|
174
181
|
verifiedBy,
|
|
175
182
|
statusRecord: status,
|
|
183
|
+
germRecord: germDeclaration,
|
|
176
184
|
tags: [],
|
|
177
185
|
profileTags: [],
|
|
178
186
|
allowActivitySubscriptionsFrom: activitySubscription(),
|
|
@@ -27,6 +27,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
27
27
|
db,
|
|
28
28
|
ids.AppBskyNotificationDeclaration,
|
|
29
29
|
),
|
|
30
|
+
getGermDeclarationRecords: getRecords(db, ids.ComGermnetworkDeclaration),
|
|
30
31
|
getStarterPackRecords: getRecords(db, ids.AppBskyGraphStarterpack),
|
|
31
32
|
getVerificationRecords: getRecords(db, ids.AppBskyGraphVerification),
|
|
32
33
|
getStatusRecords: getRecords(db, ids.AppBskyActorStatus),
|