@atproto/bsky 0.0.14 → 0.0.16

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.
Files changed (195) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/api/app/bsky/feed/searchPosts.d.ts +3 -0
  3. package/dist/api/com/atproto/moderation/util.d.ts +4 -3
  4. package/dist/config.d.ts +2 -2
  5. package/dist/context.d.ts +16 -1
  6. package/dist/db/index.js +26 -1
  7. package/dist/db/index.js.map +3 -3
  8. package/dist/db/migrations/20231003T202833377Z-create-moderation-subject-status.d.ts +3 -0
  9. package/dist/db/migrations/index.d.ts +1 -0
  10. package/dist/db/pagination.d.ts +2 -1
  11. package/dist/db/{periodic-moderation-action-reversal.d.ts → periodic-moderation-event-reversal.d.ts} +3 -5
  12. package/dist/db/tables/moderation.d.ts +24 -34
  13. package/dist/feed-gen/types.d.ts +1 -1
  14. package/dist/index.d.ts +2 -1
  15. package/dist/index.js +3332 -2430
  16. package/dist/index.js.map +3 -3
  17. package/dist/lexicon/index.d.ts +18 -18
  18. package/dist/lexicon/lexicons.d.ts +460 -385
  19. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -7
  20. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +1 -0
  21. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +116 -48
  22. package/dist/lexicon/types/com/atproto/admin/{takeModerationAction.d.ts → emitModerationEvent.d.ts} +5 -6
  23. package/dist/lexicon/types/com/atproto/admin/{getModerationAction.d.ts → getModerationEvent.d.ts} +1 -1
  24. package/dist/lexicon/types/com/atproto/admin/{getModerationActions.d.ts → queryModerationEvents.d.ts} +5 -1
  25. package/dist/lexicon/types/com/atproto/admin/{getModerationReports.d.ts → queryModerationStatuses.d.ts} +12 -6
  26. package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +1 -0
  27. package/dist/lexicon/types/com/atproto/{admin/getModerationReport.d.ts → temp/fetchLabels.d.ts} +7 -3
  28. package/dist/migrate-moderation-data.d.ts +1 -0
  29. package/dist/services/actor/views.d.ts +2 -5
  30. package/dist/services/feed/index.d.ts +1 -0
  31. package/dist/services/feed/util.d.ts +9 -1
  32. package/dist/services/feed/views.d.ts +6 -17
  33. package/dist/services/graph/index.d.ts +5 -29
  34. package/dist/services/graph/types.d.ts +1 -0
  35. package/dist/services/moderation/index.d.ts +135 -72
  36. package/dist/services/moderation/pagination.d.ts +36 -0
  37. package/dist/services/moderation/status.d.ts +13 -0
  38. package/dist/services/moderation/types.d.ts +35 -0
  39. package/dist/services/moderation/views.d.ts +18 -14
  40. package/dist/util/debug.d.ts +1 -1
  41. package/package.json +14 -15
  42. package/src/api/app/bsky/actor/getSuggestions.ts +45 -21
  43. package/src/api/app/bsky/feed/getActorFeeds.ts +2 -1
  44. package/src/api/app/bsky/feed/getActorLikes.ts +1 -3
  45. package/src/api/app/bsky/feed/getAuthorFeed.ts +1 -3
  46. package/src/api/app/bsky/feed/getFeed.ts +9 -9
  47. package/src/api/app/bsky/feed/getFeedGenerator.ts +3 -0
  48. package/src/api/app/bsky/feed/getFeedGenerators.ts +2 -1
  49. package/src/api/app/bsky/feed/getListFeed.ts +1 -3
  50. package/src/api/app/bsky/feed/getPostThread.ts +31 -58
  51. package/src/api/app/bsky/feed/getPosts.ts +21 -18
  52. package/src/api/app/bsky/feed/getSuggestedFeeds.ts +2 -1
  53. package/src/api/app/bsky/feed/getTimeline.ts +1 -3
  54. package/src/api/app/bsky/feed/searchPosts.ts +130 -0
  55. package/src/api/app/bsky/graph/getList.ts +6 -3
  56. package/src/api/app/bsky/graph/getListBlocks.ts +3 -2
  57. package/src/api/app/bsky/graph/getListMutes.ts +2 -1
  58. package/src/api/app/bsky/graph/getLists.ts +2 -1
  59. package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +3 -1
  60. package/src/api/blob-resolver.ts +6 -11
  61. package/src/api/com/atproto/admin/emitModerationEvent.ts +220 -0
  62. package/src/api/com/atproto/admin/{getModerationActions.ts → getModerationEvent.ts} +5 -11
  63. package/src/api/com/atproto/admin/getRecord.ts +1 -0
  64. package/src/api/com/atproto/admin/{getModerationReports.ts → queryModerationEvents.ts} +13 -16
  65. package/src/api/com/atproto/admin/queryModerationStatuses.ts +55 -0
  66. package/src/api/com/atproto/admin/util.ts +3 -1
  67. package/src/api/com/atproto/moderation/createReport.ts +9 -7
  68. package/src/api/com/atproto/moderation/util.ts +38 -20
  69. package/src/api/com/atproto/temp/fetchLabels.ts +30 -0
  70. package/src/api/index.ts +12 -14
  71. package/src/auth.ts +29 -21
  72. package/src/auto-moderator/index.ts +26 -19
  73. package/src/config.ts +6 -6
  74. package/src/context.ts +15 -9
  75. package/src/db/migrations/20231003T202833377Z-create-moderation-subject-status.ts +123 -0
  76. package/src/db/migrations/index.ts +1 -0
  77. package/src/db/pagination.ts +26 -3
  78. package/src/db/{periodic-moderation-action-reversal.ts → periodic-moderation-event-reversal.ts} +51 -55
  79. package/src/db/tables/moderation.ts +35 -52
  80. package/src/feed-gen/best-of-follows.ts +6 -3
  81. package/src/feed-gen/bsky-team.ts +1 -1
  82. package/src/feed-gen/hot-classic.ts +1 -1
  83. package/src/feed-gen/mutuals.ts +6 -2
  84. package/src/feed-gen/types.ts +1 -1
  85. package/src/feed-gen/whats-hot.ts +1 -1
  86. package/src/feed-gen/with-friends.ts +7 -3
  87. package/src/index.ts +2 -1
  88. package/src/lexicon/index.ts +52 -67
  89. package/src/lexicon/lexicons.ts +674 -579
  90. package/src/lexicon/types/app/bsky/actor/defs.ts +2 -2
  91. package/src/lexicon/types/app/bsky/actor/searchActors.ts +2 -2
  92. package/src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts +2 -2
  93. package/src/lexicon/types/app/bsky/feed/defs.ts +1 -18
  94. package/src/lexicon/types/app/bsky/feed/searchPosts.ts +3 -3
  95. package/src/lexicon/types/app/bsky/graph/defs.ts +3 -2
  96. package/src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts +4 -4
  97. package/src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts +3 -3
  98. package/src/lexicon/types/com/atproto/admin/defs.ts +278 -84
  99. package/src/lexicon/types/com/atproto/admin/disableAccountInvites.ts +1 -1
  100. package/src/lexicon/types/com/atproto/admin/{takeModerationAction.ts → emitModerationEvent.ts} +13 -11
  101. package/src/lexicon/types/com/atproto/admin/enableAccountInvites.ts +1 -1
  102. package/src/lexicon/types/com/atproto/admin/{getModerationReport.ts → getModerationEvent.ts} +1 -1
  103. package/src/lexicon/types/com/atproto/admin/{getModerationReports.ts → queryModerationEvents.ts} +8 -15
  104. package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +70 -0
  105. package/src/lexicon/types/com/atproto/admin/sendEmail.ts +1 -0
  106. package/src/lexicon/types/com/atproto/label/defs.ts +9 -9
  107. package/src/lexicon/types/com/atproto/label/queryLabels.ts +2 -2
  108. package/src/lexicon/types/com/atproto/repo/applyWrites.ts +1 -1
  109. package/src/lexicon/types/com/atproto/repo/createRecord.ts +2 -2
  110. package/src/lexicon/types/com/atproto/repo/deleteRecord.ts +2 -2
  111. package/src/lexicon/types/com/atproto/repo/listRecords.ts +1 -1
  112. package/src/lexicon/types/com/atproto/repo/putRecord.ts +3 -3
  113. package/src/lexicon/types/com/atproto/sync/listBlobs.ts +1 -1
  114. package/src/lexicon/types/com/atproto/sync/subscribeRepos.ts +4 -4
  115. package/src/lexicon/types/com/atproto/{admin/getModerationActions.ts → temp/fetchLabels.ts} +3 -5
  116. package/src/migrate-moderation-data.ts +414 -0
  117. package/src/services/actor/views.ts +5 -14
  118. package/src/services/feed/index.ts +26 -7
  119. package/src/services/feed/util.ts +47 -19
  120. package/src/services/feed/views.ts +68 -4
  121. package/src/services/graph/index.ts +21 -3
  122. package/src/services/graph/types.ts +1 -0
  123. package/src/services/indexing/plugins/block.ts +2 -3
  124. package/src/services/indexing/plugins/feed-generator.ts +2 -3
  125. package/src/services/indexing/plugins/follow.ts +2 -3
  126. package/src/services/indexing/plugins/like.ts +2 -3
  127. package/src/services/indexing/plugins/list-block.ts +2 -3
  128. package/src/services/indexing/plugins/list-item.ts +2 -3
  129. package/src/services/indexing/plugins/list.ts +2 -3
  130. package/src/services/indexing/plugins/post.ts +3 -4
  131. package/src/services/indexing/plugins/repost.ts +2 -3
  132. package/src/services/indexing/plugins/thread-gate.ts +2 -3
  133. package/src/services/label/index.ts +2 -3
  134. package/src/services/moderation/index.ts +380 -395
  135. package/src/services/moderation/pagination.ts +96 -0
  136. package/src/services/moderation/status.ts +244 -0
  137. package/src/services/moderation/types.ts +49 -0
  138. package/src/services/moderation/views.ts +278 -329
  139. package/src/util/debug.ts +2 -2
  140. package/tests/__snapshots__/feed-generation.test.ts.snap +322 -6
  141. package/tests/__snapshots__/indexing.test.ts.snap +0 -6
  142. package/tests/admin/__snapshots__/get-record.test.ts.snap +30 -132
  143. package/tests/admin/__snapshots__/get-repo.test.ts.snap +14 -60
  144. package/tests/admin/__snapshots__/moderation-events.test.ts.snap +146 -0
  145. package/tests/admin/__snapshots__/moderation-statuses.test.ts.snap +64 -0
  146. package/tests/admin/__snapshots__/moderation.test.ts.snap +0 -125
  147. package/tests/admin/get-record.test.ts +5 -9
  148. package/tests/admin/get-repo.test.ts +38 -9
  149. package/tests/admin/moderation-events.test.ts +221 -0
  150. package/tests/admin/moderation-statuses.test.ts +145 -0
  151. package/tests/admin/moderation.test.ts +512 -860
  152. package/tests/admin/repo-search.test.ts +2 -3
  153. package/tests/auto-moderator/fuzzy-matcher.test.ts +2 -1
  154. package/tests/auto-moderator/takedowns.test.ts +45 -18
  155. package/tests/feed-generation.test.ts +57 -9
  156. package/tests/views/__snapshots__/block-lists.test.ts.snap +3 -9
  157. package/tests/views/__snapshots__/blocks.test.ts.snap +0 -9
  158. package/tests/views/__snapshots__/mute-lists.test.ts.snap +5 -5
  159. package/tests/views/__snapshots__/mutes.test.ts.snap +0 -3
  160. package/tests/views/__snapshots__/thread.test.ts.snap +0 -30
  161. package/tests/views/actor-search.test.ts +2 -3
  162. package/tests/views/author-feed.test.ts +42 -36
  163. package/tests/views/follows.test.ts +40 -35
  164. package/tests/views/list-feed.test.ts +17 -9
  165. package/tests/views/notifications.test.ts +13 -9
  166. package/tests/views/profile.test.ts +20 -18
  167. package/tests/views/suggestions.test.ts +15 -7
  168. package/tests/views/thread.test.ts +54 -26
  169. package/tests/views/threadgating.test.ts +51 -19
  170. package/tests/views/timeline.test.ts +21 -13
  171. package/dist/api/com/atproto/admin/reverseModerationAction.d.ts +0 -3
  172. package/dist/api/com/atproto/admin/takeModerationAction.d.ts +0 -3
  173. package/dist/lexicon/types/com/atproto/admin/resolveModerationReports.d.ts +0 -36
  174. package/dist/lexicon/types/com/atproto/admin/reverseModerationAction.d.ts +0 -36
  175. package/src/api/com/atproto/admin/getModerationAction.ts +0 -44
  176. package/src/api/com/atproto/admin/getModerationReport.ts +0 -43
  177. package/src/api/com/atproto/admin/resolveModerationReports.ts +0 -24
  178. package/src/api/com/atproto/admin/reverseModerationAction.ts +0 -115
  179. package/src/api/com/atproto/admin/takeModerationAction.ts +0 -156
  180. package/src/lexicon/types/com/atproto/admin/getModerationAction.ts +0 -41
  181. package/src/lexicon/types/com/atproto/admin/resolveModerationReports.ts +0 -49
  182. package/src/lexicon/types/com/atproto/admin/reverseModerationAction.ts +0 -49
  183. package/tests/admin/__snapshots__/get-moderation-action.test.ts.snap +0 -172
  184. package/tests/admin/__snapshots__/get-moderation-actions.test.ts.snap +0 -178
  185. package/tests/admin/__snapshots__/get-moderation-report.test.ts.snap +0 -177
  186. package/tests/admin/__snapshots__/get-moderation-reports.test.ts.snap +0 -307
  187. package/tests/admin/get-moderation-action.test.ts +0 -100
  188. package/tests/admin/get-moderation-actions.test.ts +0 -164
  189. package/tests/admin/get-moderation-report.test.ts +0 -100
  190. package/tests/admin/get-moderation-reports.test.ts +0 -332
  191. /package/dist/api/com/atproto/admin/{getModerationAction.d.ts → emitModerationEvent.d.ts} +0 -0
  192. /package/dist/api/com/atproto/admin/{getModerationActions.d.ts → getModerationEvent.d.ts} +0 -0
  193. /package/dist/api/com/atproto/admin/{getModerationReport.d.ts → queryModerationEvents.d.ts} +0 -0
  194. /package/dist/api/com/atproto/admin/{getModerationReports.d.ts → queryModerationStatuses.d.ts} +0 -0
  195. /package/dist/api/com/atproto/{admin/resolveModerationReports.d.ts → temp/fetchLabels.d.ts} +0 -0
@@ -5,7 +5,6 @@ import {
5
5
  GeneratorView,
6
6
  PostView,
7
7
  } from '../../lexicon/types/app/bsky/feed/defs'
8
- import { isListRule } from '../../lexicon/types/app/bsky/feed/threadgate'
9
8
  import {
10
9
  Main as EmbedImages,
11
10
  isMain as isEmbedImages,
@@ -22,6 +21,8 @@ import {
22
21
  ViewNotFound,
23
22
  ViewRecord,
24
23
  } from '../../lexicon/types/app/bsky/embed/record'
24
+ import { Record as PostRecord } from '../../lexicon/types/app/bsky/feed/post'
25
+ import { isListRule } from '../../lexicon/types/app/bsky/feed/threadgate'
25
26
  import {
26
27
  PostEmbedViews,
27
28
  FeedGenInfo,
@@ -39,6 +40,8 @@ import { ImageUriBuilder } from '../../image/uri'
39
40
  import { LabelCache } from '../../label-cache'
40
41
  import { ActorInfoMap, ActorService } from '../actor'
41
42
  import { ListInfoMap, GraphService } from '../graph'
43
+ import { AtUri } from '@atproto/syntax'
44
+ import { parseThreadGate } from './util'
42
45
 
43
46
  export class FeedViews {
44
47
  constructor(
@@ -59,8 +62,11 @@ export class FeedViews {
59
62
  formatFeedGeneratorView(
60
63
  info: FeedGenInfo,
61
64
  profiles: ActorInfoMap,
62
- ): GeneratorView {
65
+ ): GeneratorView | undefined {
63
66
  const profile = profiles[info.creator]
67
+ if (!profile) {
68
+ return undefined
69
+ }
64
70
  return {
65
71
  uri: info.uri,
66
72
  cid: info.cid,
@@ -91,8 +97,8 @@ export class FeedViews {
91
97
  formatFeed(
92
98
  items: FeedRow[],
93
99
  state: FeedHydrationState,
100
+ viewer: string | null,
94
101
  opts?: {
95
- viewer?: string | null
96
102
  usePostViewUnion?: boolean
97
103
  },
98
104
  ): FeedViewPost[] {
@@ -101,7 +107,7 @@ export class FeedViews {
101
107
  const actors = this.services.actor.views.profileBasicPresentation(
102
108
  Object.keys(profiles),
103
109
  state,
104
- opts,
110
+ viewer,
105
111
  )
106
112
  const feed: FeedViewPost[] = []
107
113
  for (const item of items) {
@@ -114,6 +120,7 @@ export class FeedViews {
114
120
  embeds,
115
121
  labels,
116
122
  lists,
123
+ viewer,
117
124
  )
118
125
  // skip over not found & blocked posts
119
126
  if (!post || blocks[post.uri]?.reply) {
@@ -149,6 +156,7 @@ export class FeedViews {
149
156
  labels,
150
157
  lists,
151
158
  blocks,
159
+ viewer,
152
160
  opts,
153
161
  )
154
162
  const replyRoot = this.formatMaybePostView(
@@ -160,6 +168,7 @@ export class FeedViews {
160
168
  labels,
161
169
  lists,
162
170
  blocks,
171
+ viewer,
163
172
  opts,
164
173
  )
165
174
  if (replyRoot && replyParent) {
@@ -182,6 +191,7 @@ export class FeedViews {
182
191
  embeds: PostEmbedViews,
183
192
  labels: Labels,
184
193
  lists: ListInfoMap,
194
+ viewer: string | null,
185
195
  ): PostView | undefined {
186
196
  const post = posts[uri]
187
197
  const gate = threadgates[uri]
@@ -207,6 +217,14 @@ export class FeedViews {
207
217
  ? {
208
218
  repost: post.requesterRepost ?? undefined,
209
219
  like: post.requesterLike ?? undefined,
220
+ replyDisabled: this.userReplyDisabled(
221
+ uri,
222
+ actors,
223
+ posts,
224
+ threadgates,
225
+ lists,
226
+ viewer,
227
+ ),
210
228
  }
211
229
  : undefined,
212
230
  labels: [...postLabels, ...postSelfLabels],
@@ -217,6 +235,50 @@ export class FeedViews {
217
235
  }
218
236
  }
219
237
 
238
+ userReplyDisabled(
239
+ uri: string,
240
+ actors: ActorInfoMap,
241
+ posts: PostInfoMap,
242
+ threadgates: ThreadgateInfoMap,
243
+ lists: ListInfoMap,
244
+ viewer: string | null,
245
+ ): boolean | undefined {
246
+ if (viewer === null) {
247
+ return undefined
248
+ } else if (posts[uri]?.violatesThreadGate) {
249
+ return true
250
+ }
251
+
252
+ const rootUriStr: string =
253
+ posts[uri]?.record?.['reply']?.['root']?.['uri'] ?? uri
254
+ const gate = threadgates[rootUriStr]?.record
255
+ if (!gate) {
256
+ return undefined
257
+ }
258
+ const rootPost = posts[rootUriStr]?.record as PostRecord | undefined
259
+ const ownerDid = new AtUri(rootUriStr).hostname
260
+
261
+ const {
262
+ canReply,
263
+ allowFollowing,
264
+ allowListUris = [],
265
+ } = parseThreadGate(viewer, ownerDid, rootPost ?? null, gate ?? null)
266
+
267
+ if (canReply) {
268
+ return false
269
+ }
270
+ if (allowFollowing && actors[ownerDid]?.viewer?.followedBy) {
271
+ return false
272
+ }
273
+ for (const listUri of allowListUris) {
274
+ const list = lists[listUri]
275
+ if (list?.viewerInList) {
276
+ return false
277
+ }
278
+ }
279
+ return true
280
+ }
281
+
220
282
  formatMaybePostView(
221
283
  uri: string,
222
284
  actors: ActorInfoMap,
@@ -226,6 +288,7 @@ export class FeedViews {
226
288
  labels: Labels,
227
289
  lists: ListInfoMap,
228
290
  blocks: PostBlocksMap,
291
+ viewer: string | null,
229
292
  opts?: {
230
293
  usePostViewUnion?: boolean
231
294
  },
@@ -238,6 +301,7 @@ export class FeedViews {
238
301
  embeds,
239
302
  labels,
240
303
  lists,
304
+ viewer,
241
305
  )
242
306
  if (!post) {
243
307
  if (!opts?.usePostViewUnion) return
@@ -4,6 +4,10 @@ import { ImageUriBuilder } from '../../image/uri'
4
4
  import { valuesList } from '../../db/util'
5
5
  import { ListInfo } from './types'
6
6
  import { ActorInfoMap } from '../actor'
7
+ import {
8
+ ListView,
9
+ ListViewBasic,
10
+ } from '../../lexicon/types/app/bsky/graph/defs'
7
11
 
8
12
  export * from './types'
9
13
 
@@ -91,6 +95,12 @@ export class GraphService {
91
95
  .whereRef('list_block.subjectUri', '=', ref('list.uri'))
92
96
  .select('list_block.uri')
93
97
  .as('viewerListBlockUri'),
98
+ this.db.db
99
+ .selectFrom('list_item')
100
+ .whereRef('list_item.listUri', '=', ref('list.uri'))
101
+ .where('list_item.subjectDid', '=', viewer ?? '')
102
+ .select('list_item.uri')
103
+ .as('viewerInList'),
94
104
  ])
95
105
  }
96
106
 
@@ -99,7 +109,11 @@ export class GraphService {
99
109
  .selectFrom('list_item')
100
110
  .innerJoin('actor as subject', 'subject.did', 'list_item.subjectDid')
101
111
  .selectAll('subject')
102
- .select(['list_item.cid as cid', 'list_item.sortAt as sortAt'])
112
+ .select([
113
+ 'list_item.uri as uri',
114
+ 'list_item.cid as cid',
115
+ 'list_item.sortAt as sortAt',
116
+ ])
103
117
  }
104
118
 
105
119
  async getBlockAndMuteState(
@@ -229,7 +243,10 @@ export class GraphService {
229
243
  )
230
244
  }
231
245
 
232
- formatListView(list: ListInfo, profiles: ActorInfoMap) {
246
+ formatListView(list: ListInfo, profiles: ActorInfoMap): ListView | undefined {
247
+ if (!profiles[list.creator]) {
248
+ return undefined
249
+ }
233
250
  return {
234
251
  ...this.formatListViewBasic(list),
235
252
  creator: profiles[list.creator],
@@ -237,10 +254,11 @@ export class GraphService {
237
254
  descriptionFacets: list.descriptionFacets
238
255
  ? JSON.parse(list.descriptionFacets)
239
256
  : undefined,
257
+ indexedAt: list.sortAt,
240
258
  }
241
259
  }
242
260
 
243
- formatListViewBasic(list: ListInfo) {
261
+ formatListViewBasic(list: ListInfo): ListViewBasic {
244
262
  return {
245
263
  uri: list.uri,
246
264
  cid: list.cid,
@@ -4,6 +4,7 @@ import { List } from '../../db/tables/list'
4
4
  export type ListInfo = Selectable<List> & {
5
5
  viewerMuted: string | null
6
6
  viewerListBlockUri: string | null
7
+ viewerInList: string | null
7
8
  }
8
9
 
9
10
  export type ListInfoMap = Record<string, ListInfo>
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as Block from '../../../lexicon/types/app/bsky/graph/block'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -27,7 +26,7 @@ const insertFn = async (
27
26
  cid: cid.toString(),
28
27
  creator: uri.host,
29
28
  subjectDid: obj.subject,
30
- createdAt: toSimplifiedISOSafe(obj.createdAt),
29
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
31
30
  indexedAt: timestamp,
32
31
  })
33
32
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as FeedGenerator from '../../../lexicon/types/app/bsky/feed/generator'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -33,7 +32,7 @@ const insertFn = async (
33
32
  ? JSON.stringify(obj.descriptionFacets)
34
33
  : undefined,
35
34
  avatarCid: obj.avatar?.ref.toString(),
36
- createdAt: toSimplifiedISOSafe(obj.createdAt),
35
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
37
36
  indexedAt: timestamp,
38
37
  })
39
38
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as Follow from '../../../lexicon/types/app/bsky/graph/follow'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -28,7 +27,7 @@ const insertFn = async (
28
27
  cid: cid.toString(),
29
28
  creator: uri.host,
30
29
  subjectDid: obj.subject,
31
- createdAt: toSimplifiedISOSafe(obj.createdAt),
30
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
32
31
  indexedAt: timestamp,
33
32
  })
34
33
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as Like from '../../../lexicon/types/app/bsky/feed/like'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -29,7 +28,7 @@ const insertFn = async (
29
28
  creator: uri.host,
30
29
  subject: obj.subject.uri,
31
30
  subjectCid: obj.subject.cid,
32
- createdAt: toSimplifiedISOSafe(obj.createdAt),
31
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
33
32
  indexedAt: timestamp,
34
33
  })
35
34
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as ListBlock from '../../../lexicon/types/app/bsky/graph/listblock'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -27,7 +26,7 @@ const insertFn = async (
27
26
  cid: cid.toString(),
28
27
  creator: uri.host,
29
28
  subjectUri: obj.subject,
30
- createdAt: toSimplifiedISOSafe(obj.createdAt),
29
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
31
30
  indexedAt: timestamp,
32
31
  })
33
32
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as ListItem from '../../../lexicon/types/app/bsky/graph/listitem'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -35,7 +34,7 @@ const insertFn = async (
35
34
  creator: uri.host,
36
35
  subjectDid: obj.subject,
37
36
  listUri: obj.list,
38
- createdAt: toSimplifiedISOSafe(obj.createdAt),
37
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
39
38
  indexedAt: timestamp,
40
39
  })
41
40
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { Selectable } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as List from '../../../lexicon/types/app/bsky/graph/list'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -33,7 +32,7 @@ const insertFn = async (
33
32
  ? JSON.stringify(obj.descriptionFacets)
34
33
  : undefined,
35
34
  avatarCid: obj.avatar?.ref.toString(),
36
- createdAt: toSimplifiedISOSafe(obj.createdAt),
35
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
37
36
  indexedAt: timestamp,
38
37
  })
39
38
  .onConflict((oc) => oc.doNothing())
@@ -1,7 +1,6 @@
1
1
  import { Insertable, Selectable, sql } from 'kysely'
2
2
  import { CID } from 'multiformats/cid'
3
- import { AtUri } from '@atproto/syntax'
4
- import { toSimplifiedISOSafe } from '@atproto/common'
3
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
5
4
  import { jsonStringToLex } from '@atproto/lexicon'
6
5
  import {
7
6
  Record as PostRecord,
@@ -68,7 +67,7 @@ const insertFn = async (
68
67
  cid: cid.toString(),
69
68
  creator: uri.host,
70
69
  text: obj.text,
71
- createdAt: toSimplifiedISOSafe(obj.createdAt),
70
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
72
71
  replyRoot: obj.reply?.root?.uri || null,
73
72
  replyRootCid: obj.reply?.root?.cid || null,
74
73
  replyParent: obj.reply?.parent?.uri || null,
@@ -420,7 +419,7 @@ async function validateReply(
420
419
  const violatesThreadGate = await feedutil.violatesThreadGate(
421
420
  db,
422
421
  creator,
423
- new AtUri(reply.root.uri).host,
422
+ new AtUri(reply.root.uri).hostname,
424
423
  replyRefs.root?.record ?? null,
425
424
  replyRefs.gate?.record ?? null,
426
425
  )
@@ -1,7 +1,6 @@
1
1
  import { Selectable } from 'kysely'
2
2
  import { CID } from 'multiformats/cid'
3
- import { AtUri } from '@atproto/syntax'
4
- import { toSimplifiedISOSafe } from '@atproto/common'
3
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
5
4
  import * as Repost from '../../../lexicon/types/app/bsky/feed/repost'
6
5
  import * as lex from '../../../lexicon/lexicons'
7
6
  import { DatabaseSchema, DatabaseSchemaType } from '../../../db/database-schema'
@@ -27,7 +26,7 @@ const insertFn = async (
27
26
  creator: uri.host,
28
27
  subject: obj.subject.uri,
29
28
  subjectCid: obj.subject.cid,
30
- createdAt: toSimplifiedISOSafe(obj.createdAt),
29
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
31
30
  indexedAt: timestamp,
32
31
  }
33
32
  const [inserted] = await Promise.all([
@@ -1,6 +1,5 @@
1
- import { AtUri } from '@atproto/syntax'
1
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
2
2
  import { InvalidRequestError } from '@atproto/xrpc-server'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
4
3
  import { CID } from 'multiformats/cid'
5
4
  import * as Threadgate from '../../../lexicon/types/app/bsky/feed/threadgate'
6
5
  import * as lex from '../../../lexicon/lexicons'
@@ -33,7 +32,7 @@ const insertFn = async (
33
32
  cid: cid.toString(),
34
33
  creator: uri.host,
35
34
  postUri: obj.post,
36
- createdAt: toSimplifiedISOSafe(obj.createdAt),
35
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
37
36
  indexedAt: timestamp,
38
37
  })
39
38
  .onConflict((oc) => oc.doNothing())
@@ -1,6 +1,5 @@
1
1
  import { sql } from 'kysely'
2
- import { AtUri } from '@atproto/syntax'
3
- import { toSimplifiedISOSafe } from '@atproto/common'
2
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
3
  import { Database } from '../../db'
5
4
  import { Label, isSelfLabels } from '../../lexicon/types/com/atproto/label/defs'
6
5
  import { ids } from '../../lexicon/lexicons'
@@ -166,7 +165,7 @@ export function getSelfLabels(details: {
166
165
  const src = new AtUri(uri).host // record creator
167
166
  const cts =
168
167
  typeof record.createdAt === 'string'
169
- ? toSimplifiedISOSafe(record.createdAt)
168
+ ? normalizeDatetimeAlways(record.createdAt)
170
169
  : new Date(0).toISOString()
171
170
  return record.labels.values.map(({ val }) => {
172
171
  return { src, uri, cid, val, cts, neg: false }