@atproto/ozone 0.2.4 → 0.2.6

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 (217) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +2 -0
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/label/queryLabels.d.ts.map +1 -1
  6. package/dist/api/label/queryLabels.js +13 -21
  7. package/dist/api/label/queryLabels.js.map +1 -1
  8. package/dist/api/report/queryActivities.d.ts +4 -0
  9. package/dist/api/report/queryActivities.d.ts.map +1 -0
  10. package/dist/api/report/queryActivities.js +36 -0
  11. package/dist/api/report/queryActivities.js.map +1 -0
  12. package/dist/assignment/index.d.ts.map +1 -1
  13. package/dist/assignment/index.js +9 -12
  14. package/dist/assignment/index.js.map +1 -1
  15. package/dist/background.d.ts +5 -3
  16. package/dist/background.d.ts.map +1 -1
  17. package/dist/background.js +13 -4
  18. package/dist/background.js.map +1 -1
  19. package/dist/context.js +1 -1
  20. package/dist/context.js.map +1 -1
  21. package/dist/daemon/context.js +1 -1
  22. package/dist/daemon/context.js.map +1 -1
  23. package/dist/daemon/event-pusher.d.ts +7 -1
  24. package/dist/daemon/event-pusher.d.ts.map +1 -1
  25. package/dist/daemon/verification-listener.d.ts +1 -1
  26. package/dist/daemon/verification-listener.d.ts.map +1 -1
  27. package/dist/daemon/verification-listener.js +10 -4
  28. package/dist/daemon/verification-listener.js.map +1 -1
  29. package/dist/db/index.d.ts +4 -5
  30. package/dist/db/index.d.ts.map +1 -1
  31. package/dist/db/index.js +2 -1
  32. package/dist/db/index.js.map +1 -1
  33. package/dist/db/migrations/20241220T144630860Z-stats-materialized-views.d.ts +1 -2
  34. package/dist/db/migrations/20241220T144630860Z-stats-materialized-views.d.ts.map +1 -1
  35. package/dist/db/migrations/20241220T144630860Z-stats-materialized-views.js.map +1 -1
  36. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.d.ts +1 -2
  37. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.d.ts.map +1 -1
  38. package/dist/db/migrations/20250718T150931000Z-update-appeal-reason-stats.js.map +1 -1
  39. package/dist/db/migrations/20260602T120000000Z-add-report-activity-created-index.d.ts +4 -0
  40. package/dist/db/migrations/20260602T120000000Z-add-report-activity-created-index.d.ts.map +1 -0
  41. package/dist/db/migrations/20260602T120000000Z-add-report-activity-created-index.js +15 -0
  42. package/dist/db/migrations/20260602T120000000Z-add-report-activity-created-index.js.map +1 -0
  43. package/dist/db/migrations/index.d.ts +1 -0
  44. package/dist/db/migrations/index.d.ts.map +1 -1
  45. package/dist/db/migrations/index.js +1 -0
  46. package/dist/db/migrations/index.js.map +1 -1
  47. package/dist/db/migrations/provider.d.ts +2 -1
  48. package/dist/db/migrations/provider.d.ts.map +1 -1
  49. package/dist/db/migrations/provider.js.map +1 -1
  50. package/dist/db/pagination.d.ts +4 -3
  51. package/dist/db/pagination.d.ts.map +1 -1
  52. package/dist/db/pagination.js +4 -4
  53. package/dist/db/pagination.js.map +1 -1
  54. package/dist/db/types.d.ts +1 -1
  55. package/dist/db/types.d.ts.map +1 -1
  56. package/dist/db/types.js.map +1 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +23 -13
  59. package/dist/index.js.map +1 -1
  60. package/dist/jetstream/service.d.ts +1 -1
  61. package/dist/jetstream/service.d.ts.map +1 -1
  62. package/dist/jetstream/service.js +3 -1
  63. package/dist/jetstream/service.js.map +1 -1
  64. package/dist/lexicon/index.d.ts +11 -0
  65. package/dist/lexicon/index.d.ts.map +1 -1
  66. package/dist/lexicon/index.js +18 -0
  67. package/dist/lexicon/index.js.map +1 -1
  68. package/dist/lexicon/lexicons.d.ts +338 -0
  69. package/dist/lexicon/lexicons.d.ts.map +1 -1
  70. package/dist/lexicon/lexicons.js +173 -0
  71. package/dist/lexicon/lexicons.js.map +1 -1
  72. package/dist/lexicon/types/app/bsky/notification/defs.d.ts +1 -0
  73. package/dist/lexicon/types/app/bsky/notification/defs.d.ts.map +1 -1
  74. package/dist/lexicon/types/app/bsky/notification/defs.js.map +1 -1
  75. package/dist/lexicon/types/chat/bsky/notification/defs.d.ts +19 -0
  76. package/dist/lexicon/types/chat/bsky/notification/defs.d.ts.map +1 -0
  77. package/dist/lexicon/types/chat/bsky/notification/defs.js +19 -0
  78. package/dist/lexicon/types/chat/bsky/notification/defs.js.map +1 -0
  79. package/dist/lexicon/types/chat/bsky/notification/getPreferences.d.ts +20 -0
  80. package/dist/lexicon/types/chat/bsky/notification/getPreferences.d.ts.map +1 -0
  81. package/dist/lexicon/types/chat/bsky/notification/getPreferences.js +5 -0
  82. package/dist/lexicon/types/chat/bsky/notification/getPreferences.js.map +1 -0
  83. package/dist/lexicon/types/chat/bsky/notification/putPreferences.d.ts +26 -0
  84. package/dist/lexicon/types/chat/bsky/notification/putPreferences.d.ts.map +1 -0
  85. package/dist/lexicon/types/chat/bsky/notification/putPreferences.js +5 -0
  86. package/dist/lexicon/types/chat/bsky/notification/putPreferences.js.map +1 -0
  87. package/dist/lexicon/types/tools/ozone/report/defs.d.ts +1 -0
  88. package/dist/lexicon/types/tools/ozone/report/defs.d.ts.map +1 -1
  89. package/dist/lexicon/types/tools/ozone/report/defs.js.map +1 -1
  90. package/dist/lexicon/types/tools/ozone/report/queryActivities.d.ts +32 -0
  91. package/dist/lexicon/types/tools/ozone/report/queryActivities.d.ts.map +1 -0
  92. package/dist/lexicon/types/tools/ozone/report/queryActivities.js +5 -0
  93. package/dist/lexicon/types/tools/ozone/report/queryActivities.js.map +1 -0
  94. package/dist/mod-service/index.d.ts.map +1 -1
  95. package/dist/mod-service/index.js +28 -52
  96. package/dist/mod-service/index.js.map +1 -1
  97. package/dist/mod-service/report.d.ts +1 -0
  98. package/dist/mod-service/report.d.ts.map +1 -1
  99. package/dist/mod-service/report.js +16 -0
  100. package/dist/mod-service/report.js.map +1 -1
  101. package/dist/mod-service/status.d.ts +23 -128
  102. package/dist/mod-service/status.d.ts.map +1 -1
  103. package/dist/mod-service/views.js +7 -11
  104. package/dist/mod-service/views.js.map +1 -1
  105. package/dist/queue/service.js +1 -3
  106. package/dist/queue/service.js.map +1 -1
  107. package/dist/report/activity.d.ts +31 -2
  108. package/dist/report/activity.d.ts.map +1 -1
  109. package/dist/report/activity.js +27 -1
  110. package/dist/report/activity.js.map +1 -1
  111. package/dist/report/stats.d.ts.map +1 -1
  112. package/dist/report/stats.js.map +1 -1
  113. package/dist/scheduled-action/service.d.ts.map +1 -1
  114. package/dist/scheduled-action/service.js +16 -20
  115. package/dist/scheduled-action/service.js.map +1 -1
  116. package/dist/set/service.d.ts +10 -1
  117. package/dist/set/service.d.ts.map +1 -1
  118. package/dist/set/service.js +5 -2
  119. package/dist/set/service.js.map +1 -1
  120. package/dist/team/index.d.ts.map +1 -1
  121. package/dist/team/index.js +5 -4
  122. package/dist/team/index.js.map +1 -1
  123. package/dist/verification/issuer.d.ts +13 -3
  124. package/dist/verification/issuer.d.ts.map +1 -1
  125. package/dist/verification/service.d.ts +13 -1
  126. package/dist/verification/service.d.ts.map +1 -1
  127. package/dist/verification/service.js +1 -1
  128. package/dist/verification/service.js.map +1 -1
  129. package/package.json +12 -11
  130. package/src/api/index.ts +2 -0
  131. package/src/api/label/queryLabels.ts +11 -14
  132. package/src/api/report/queryActivities.ts +64 -0
  133. package/src/assignment/index.ts +15 -18
  134. package/src/background.ts +19 -4
  135. package/src/context.ts +1 -1
  136. package/src/daemon/context.ts +1 -1
  137. package/src/daemon/verification-listener.ts +9 -4
  138. package/src/db/index.ts +1 -1
  139. package/src/db/migrations/20241220T144630860Z-stats-materialized-views.ts +1 -2
  140. package/src/db/migrations/20250718T150931000Z-update-appeal-reason-stats.ts +1 -2
  141. package/src/db/migrations/20260602T120000000Z-add-report-activity-created-index.ts +17 -0
  142. package/src/db/migrations/index.ts +1 -0
  143. package/src/db/migrations/provider.ts +2 -1
  144. package/src/db/pagination.ts +18 -18
  145. package/src/db/types.ts +3 -1
  146. package/src/index.ts +25 -15
  147. package/src/jetstream/service.ts +3 -1
  148. package/src/mod-service/index.ts +78 -71
  149. package/src/mod-service/report.ts +24 -3
  150. package/src/mod-service/views.ts +16 -16
  151. package/src/queue/service.ts +5 -5
  152. package/src/report/activity.ts +47 -0
  153. package/src/report/stats.ts +5 -3
  154. package/src/scheduled-action/service.ts +22 -20
  155. package/src/set/service.ts +17 -14
  156. package/src/team/index.ts +6 -5
  157. package/src/verification/service.ts +2 -2
  158. package/tests/3p-labeler.test.ts +2 -2
  159. package/tests/_util.ts +8 -25
  160. package/tests/account-strikes.test.ts +1 -1
  161. package/tests/ack-all-subjects-of-account.test.ts +1 -1
  162. package/tests/age-assurance.test.ts +1 -1
  163. package/tests/blob-divert.test.ts +1 -1
  164. package/tests/communication-templates.test.ts +1 -1
  165. package/tests/content-tagger.test.ts +1 -1
  166. package/tests/db.test.ts +1 -1
  167. package/tests/expiring-label.test.ts +1 -1
  168. package/tests/expiring-tags.test.ts +1 -1
  169. package/tests/get-account-timeline.test.ts +1 -1
  170. package/tests/get-config.test.ts +1 -1
  171. package/tests/get-lists.test.ts +2 -1
  172. package/tests/get-profiles.test.ts +1 -1
  173. package/tests/get-record.test.ts +1 -1
  174. package/tests/get-records.test.ts +1 -1
  175. package/tests/get-repo.test.ts +1 -1
  176. package/tests/get-report.test.ts +1 -1
  177. package/tests/get-reporter-stats.test.ts +1 -1
  178. package/tests/get-repos.test.ts +1 -1
  179. package/tests/get-starter-pack.test.ts +1 -1
  180. package/tests/get-subjects.test.ts +1 -1
  181. package/tests/mod-tool.test.ts +1 -1
  182. package/tests/moderation-appeals.test.ts +1 -1
  183. package/tests/moderation-events.test.ts +1 -1
  184. package/tests/moderation-status-tags.test.ts +1 -1
  185. package/tests/moderation-statuses.test.ts +1 -1
  186. package/tests/moderation.test.ts +1 -1
  187. package/tests/protected-tags.test.ts +1 -1
  188. package/tests/query-labels.test.ts +1 -1
  189. package/tests/query-reports.test.ts +1 -1
  190. package/tests/queue-assignment.test.ts +1 -1
  191. package/tests/queue-router.test.ts +1 -1
  192. package/tests/queues.test.ts +1 -1
  193. package/tests/record-and-account-events.test.ts +1 -1
  194. package/tests/repo-search.test.ts +2 -2
  195. package/tests/report-action.test.ts +1 -1
  196. package/tests/report-activity.test.ts +145 -1
  197. package/tests/report-assignment.test.ts +1 -1
  198. package/tests/report-muting.test.ts +1 -1
  199. package/tests/report-reason.test.ts +1 -1
  200. package/tests/report-reassign-queue.test.ts +1 -1
  201. package/tests/report-routing.test.ts +1 -1
  202. package/tests/report-stats.test.ts +1 -1
  203. package/tests/revoke-account-credentials.test.ts +1 -1
  204. package/tests/safelink.test.ts +1 -1
  205. package/tests/scheduled-action-processor.test.ts +1 -1
  206. package/tests/scheduled-action.test.ts +1 -1
  207. package/tests/sequencer.test.ts +1 -1
  208. package/tests/server.test.ts +9 -12
  209. package/tests/sets.test.ts +1 -1
  210. package/tests/settings.test.ts +1 -1
  211. package/tests/strike-expiry-processor.test.ts +1 -1
  212. package/tests/subject-priority-score.test.ts +1 -1
  213. package/tests/takedown.test.ts +1 -1
  214. package/tests/team.test.ts +1 -1
  215. package/tests/verification-listener.test.ts +40 -13
  216. package/tests/verification.test.ts +1 -1
  217. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,5 +1,8 @@
1
1
  import { InvalidRequestError } from '@atproto/xrpc-server'
2
2
  import { Database } from '../db/index.js'
3
+ import { TimeIdKeyset, paginate } from '../db/pagination.js'
4
+ import { ReportView } from '../lexicon/types/tools/ozone/report/defs.js'
5
+ import { QueryParams as QueryActivitiesParams } from '../lexicon/types/tools/ozone/report/queryActivities.js'
3
6
  import { Member } from '../lexicon/types/tools/ozone/team/defs.js'
4
7
  import {
5
8
  AlreadyInTargetState,
@@ -190,6 +193,48 @@ export async function listReportActivities(
190
193
  return { activities, cursor: nextCursor }
191
194
  }
192
195
 
196
+ export async function queryReportActivities(
197
+ db: Database,
198
+ params: QueryActivitiesParams,
199
+ ) {
200
+ const {
201
+ activityTypes,
202
+ createdAfter,
203
+ createdBefore,
204
+ sortDirection,
205
+ limit,
206
+ cursor,
207
+ } = params
208
+ const { ref } = db.db.dynamic
209
+
210
+ let builder = db.db.selectFrom('report_activity').selectAll()
211
+
212
+ if (activityTypes && activityTypes.length > 0) {
213
+ builder = builder.where('activityType', 'in', activityTypes)
214
+ }
215
+ if (createdAfter) {
216
+ builder = builder.where('createdAt', '>=', createdAfter)
217
+ }
218
+ if (createdBefore) {
219
+ builder = builder.where('createdAt', '<=', createdBefore)
220
+ }
221
+
222
+ const keyset = new TimeIdKeyset(
223
+ ref('report_activity.createdAt'),
224
+ ref('report_activity.id'),
225
+ )
226
+ const paginatedBuilder = paginate(builder, {
227
+ limit,
228
+ cursor,
229
+ keyset,
230
+ direction: sortDirection,
231
+ tryIndex: true,
232
+ })
233
+
234
+ const activities = await paginatedBuilder.execute()
235
+ return { activities, cursor: keyset.packFromResult(activities) }
236
+ }
237
+
193
238
  function buildActivityObject(
194
239
  activityType: string,
195
240
  previousStatus: string | null,
@@ -215,6 +260,7 @@ export function formatActivityView(
215
260
  createdAt: string
216
261
  },
217
262
  memberViews?: Map<string, Member>,
263
+ reportViews?: Map<number, ReportView>,
218
264
  ) {
219
265
  return {
220
266
  id: activity.id,
@@ -229,6 +275,7 @@ export function formatActivityView(
229
275
  isAutomated: activity.isAutomated,
230
276
  createdBy: activity.createdBy,
231
277
  moderator: memberViews?.get(activity.createdBy),
278
+ report: reportViews?.get(activity.reportId),
232
279
  createdAt: activity.createdAt,
233
280
  }
234
281
  }
@@ -672,7 +672,7 @@ export class ReportStatsService {
672
672
  del =
673
673
  r.reportTypes !== null
674
674
  ? del.where(
675
- sql`"reportTypes"::jsonb = ${jsonb(r.reportTypes)}::jsonb`,
675
+ sql<boolean>`"reportTypes"::jsonb = ${jsonb(r.reportTypes)}::jsonb`,
676
676
  )
677
677
  : del.where('reportTypes', 'is', null)
678
678
  await del.execute()
@@ -720,7 +720,7 @@ export class ReportStatsService {
720
720
  }
721
721
  if (group.reportTypes !== null) {
722
722
  qb = qb.where(
723
- sql`"reportTypes"::jsonb = ${jsonb(group.reportTypes)}::jsonb`,
723
+ sql<boolean>`"reportTypes"::jsonb = ${jsonb(group.reportTypes)}::jsonb`,
724
724
  )
725
725
  } else {
726
726
  qb = qb.where('reportTypes', 'is', null)
@@ -786,7 +786,9 @@ export class ReportStatsService {
786
786
  qb = qb.where('moderatorDid', 'is', null)
787
787
  }
788
788
  if (reportTypes !== null) {
789
- qb = qb.where(sql`"reportTypes"::jsonb = ${jsonb(reportTypes)}::jsonb`)
789
+ qb = qb.where(
790
+ sql<boolean>`"reportTypes"::jsonb = ${jsonb(reportTypes)}::jsonb`,
791
+ )
790
792
  } else {
791
793
  qb = qb.where('reportTypes', 'is', null)
792
794
  }
@@ -151,24 +151,25 @@ export class ScheduledActionService {
151
151
  }
152
152
 
153
153
  if (startTime) {
154
- query = query.where((qb) => {
155
- return qb
156
- .orWhere('executeAt', '>=', startTime.toISOString())
157
- .orWhere('executeAfter', '>=', startTime.toISOString())
158
- })
154
+ query = query.where((eb) =>
155
+ eb.or([
156
+ eb('executeAt', '>=', startTime.toISOString()),
157
+ eb('executeAfter', '>=', startTime.toISOString()),
158
+ ]),
159
+ )
159
160
  }
160
161
 
161
162
  if (endTime) {
162
- query = query.where((qb) => {
163
- return qb
164
- .orWhere('executeAt', '<=', endTime.toISOString())
165
- .orWhere('executeUntil', '<=', endTime.toISOString())
166
- .orWhere((sqb) => {
167
- return sqb
168
- .where('executeUntil', 'is', null)
169
- .where('executeAfter', '<=', endTime.toISOString())
170
- })
171
- })
163
+ query = query.where((eb) =>
164
+ eb.or([
165
+ eb('executeAt', '<=', endTime.toISOString()),
166
+ eb('executeUntil', '<=', endTime.toISOString()),
167
+ eb.and([
168
+ eb('executeUntil', 'is', null),
169
+ eb('executeAfter', '<=', endTime.toISOString()),
170
+ ]),
171
+ ]),
172
+ )
172
173
  }
173
174
 
174
175
  if (cursor) {
@@ -235,11 +236,12 @@ export class ScheduledActionService {
235
236
  .selectFrom('scheduled_action')
236
237
  .selectAll()
237
238
  .where('status', '=', 'pending')
238
- .where((qb) => {
239
- return qb
240
- .orWhere('executeAfter', '<=', now.toISOString())
241
- .orWhere('executeAt', '<=', now.toISOString())
242
- })
239
+ .where((eb) =>
240
+ eb.or([
241
+ eb('executeAfter', '<=', now.toISOString()),
242
+ eb('executeAt', '<=', now.toISOString()),
243
+ ]),
244
+ )
243
245
  .execute()
244
246
  }
245
247
 
@@ -1,4 +1,4 @@
1
- import { Selectable } from 'kysely'
1
+ import { NotNull, Selectable } from 'kysely'
2
2
  import { Database } from '../db/index.js'
3
3
  import { TimeIdKeyset, paginate } from '../db/pagination.js'
4
4
  import { SetDetail } from '../db/schema/ozone_set.js'
@@ -14,19 +14,22 @@ export class SetService {
14
14
  }
15
15
 
16
16
  buildQueryForSetWithSize() {
17
- return this.db.db.selectFrom('set_detail as s').select([
18
- 's.id',
19
- 's.name',
20
- 's.description',
21
- 's.createdAt',
22
- 's.updatedAt',
23
- (eb) =>
24
- eb
25
- .selectFrom('set_value')
26
- .select((e) => e.fn.count<number>('setId').as('count'))
27
- .whereRef('setId', '=', 's.id')
28
- .as('setSize'),
29
- ])
17
+ return this.db.db
18
+ .selectFrom('set_detail as s')
19
+ .select([
20
+ 's.id',
21
+ 's.name',
22
+ 's.description',
23
+ 's.createdAt',
24
+ 's.updatedAt',
25
+ (eb) =>
26
+ eb
27
+ .selectFrom('set_value')
28
+ .select((e) => e.fn.count<number>('setId').as('count'))
29
+ .whereRef('setId', '=', 's.id')
30
+ .as('setSize'),
31
+ ])
32
+ .$narrowType<{ setSize: NotNull }>()
30
33
  }
31
34
 
32
35
  async query({
package/src/team/index.ts CHANGED
@@ -67,10 +67,11 @@ export class TeamService {
67
67
  builder = builder.where('disabled', disabled ? 'is' : 'is not', true)
68
68
  }
69
69
  if (q) {
70
- builder = builder.where((qb) =>
71
- qb
72
- .orWhere('handle', 'ilike', `%${q}%`)
73
- .orWhere('displayName', 'ilike', `%${q}%`),
70
+ builder = builder.where((eb) =>
71
+ eb.or([
72
+ eb('handle', 'ilike', `%${q}%`),
73
+ eb('displayName', 'ilike', `%${q}%`),
74
+ ]),
74
75
  )
75
76
  }
76
77
 
@@ -245,7 +246,7 @@ export class TeamService {
245
246
  .selectFrom('member')
246
247
  .select(['did'])
247
248
  .limit(25)
248
- .if(!!lastDid, (q) => q.where('did', '>', lastDid))
249
+ .$if(!!lastDid, (q) => q.where('did', '>', lastDid))
249
250
  .orderBy('did', 'asc')
250
251
  .execute()
251
252
 
@@ -197,8 +197,8 @@ export class VerificationService {
197
197
  .updateTable('firehose_cursor')
198
198
  .set({ cursor })
199
199
  .where('service', '=', 'verification')
200
- .where((qb) =>
201
- qb.where('cursor', '<', cursor).orWhere('cursor', 'is', null),
200
+ .where((eb) =>
201
+ eb.or([eb('cursor', '<', cursor), eb('cursor', 'is', null)]),
202
202
  )
203
203
  .returningAll()
204
204
  .executeTakeFirst()
@@ -53,8 +53,8 @@ describe('labels from 3p labelers', () => {
53
53
  })
54
54
 
55
55
  afterAll(async () => {
56
- await network.close()
57
- await thirdPartyLabeler.close()
56
+ await network?.close()
57
+ await thirdPartyLabeler?.close()
58
58
  })
59
59
 
60
60
  const getPostSubject = () => ({
package/tests/_util.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { Server } from 'node:http'
1
+ import { RequestListener, createServer } from 'node:http'
2
2
  import { AddressInfo } from 'node:net'
3
- import { type Express } from 'express'
3
+ // eslint-disable-next-line import/default
4
+ import httpTerminator from 'http-terminator'
4
5
  import { CID } from 'multiformats/cid'
5
6
  import { lexToJson } from '@atproto/lexicon'
6
7
  import { AtUri } from '@atproto/syntax'
@@ -215,19 +216,11 @@ export const stripViewerFromThread = <T extends ThreadViewPost>(
215
216
  return thread
216
217
  }
217
218
 
218
- export async function startServer(app: Express) {
219
- return new Promise<{
220
- origin: string
221
- server: Server
222
- stop: () => Promise<void>
223
- }>((resolve, reject) => {
219
+ export async function startServer(listener: RequestListener) {
220
+ return new Promise<AsyncDisposable & { port: number }>((resolve, reject) => {
224
221
  const onListen = () => {
225
222
  const port = (server.address() as AddressInfo).port
226
- resolve({
227
- server,
228
- origin: `http://localhost:${port}`,
229
- stop: () => stopServer(server),
230
- })
223
+ resolve({ port, [Symbol.asyncDispose]: () => terminator.terminate() })
231
224
  cleanup()
232
225
  }
233
226
  const onError = (err: Error) => {
@@ -239,21 +232,11 @@ export async function startServer(app: Express) {
239
232
  server.removeListener('error', onError)
240
233
  }
241
234
 
242
- const server = app
235
+ const server = createServer(listener)
243
236
  .listen(0)
244
237
  .once('listening', onListen)
245
238
  .once('error', onError)
246
- })
247
- }
248
239
 
249
- export async function stopServer(server: Server) {
250
- return new Promise<void>((resolve, reject) => {
251
- server.close((err) => {
252
- if (err) {
253
- reject(err)
254
- } else {
255
- resolve()
256
- }
257
- })
240
+ const terminator = httpTerminator.createHttpTerminator({ server })
258
241
  })
259
242
  }
@@ -65,7 +65,7 @@ describe('account-strikes', () => {
65
65
  })
66
66
 
67
67
  afterAll(async () => {
68
- await network.close()
68
+ await network?.close()
69
69
  })
70
70
 
71
71
  it('tracks strikes and exposes them through queryStatuses and queryEvents', async () => {
@@ -93,7 +93,7 @@ describe('acknowledge all subjects of account', () => {
93
93
  })
94
94
 
95
95
  afterAll(async () => {
96
- await network.close()
96
+ await network?.close()
97
97
  })
98
98
 
99
99
  it('acknowledges all open/escalated review subjects with takedown.', async () => {
@@ -22,7 +22,7 @@ describe('age assurance events', () => {
22
22
  })
23
23
 
24
24
  afterAll(async () => {
25
- await network.close()
25
+ await network?.close()
26
26
  })
27
27
 
28
28
  it('handles age assurance events from user', async () => {
@@ -30,7 +30,7 @@ describe('blob divert', () => {
30
30
  })
31
31
 
32
32
  afterAll(async () => {
33
- await network.close()
33
+ await network?.close()
34
34
  })
35
35
 
36
36
  const mockReportServiceResponse = (succeeds: boolean) => {
@@ -18,7 +18,7 @@ describe('communication-templates', () => {
18
18
  })
19
19
 
20
20
  afterAll(async () => {
21
- await network.close()
21
+ await network?.close()
22
22
  })
23
23
 
24
24
  const templateOne = {
@@ -23,7 +23,7 @@ describe('moderation subject content tagging', () => {
23
23
  })
24
24
 
25
25
  afterAll(async () => {
26
- await network.close()
26
+ await network?.close()
27
27
  })
28
28
 
29
29
  const getStatus = async (subject: string) => {
package/tests/db.test.ts CHANGED
@@ -15,7 +15,7 @@ describe('db', () => {
15
15
  })
16
16
 
17
17
  afterAll(async () => {
18
- await network.close()
18
+ await network?.close()
19
19
  })
20
20
 
21
21
  it('handles client errors without crashing.', async () => {
@@ -25,7 +25,7 @@ describe('expiring label', () => {
25
25
  })
26
26
 
27
27
  afterAll(async () => {
28
- await network.close()
28
+ await network?.close()
29
29
  })
30
30
 
31
31
  const emitExpiringLabel = async (did: string) =>
@@ -23,7 +23,7 @@ describe('expiring tags', () => {
23
23
  })
24
24
 
25
25
  afterAll(async () => {
26
- await network.close()
26
+ await network?.close()
27
27
  })
28
28
 
29
29
  const emitTagEvent = (
@@ -62,7 +62,7 @@ describe('account timeline', () => {
62
62
  })
63
63
 
64
64
  afterAll(async () => {
65
- await network.close()
65
+ await network?.close()
66
66
  })
67
67
 
68
68
  it('Returns entire timeline of events for a given account', async () => {
@@ -19,7 +19,7 @@ describe('get-config', () => {
19
19
  })
20
20
 
21
21
  afterAll(async () => {
22
- await network.close()
22
+ await network?.close()
23
23
  })
24
24
 
25
25
  const getConfig = async (role: 'moderator' | 'admin' | 'triage') => {
@@ -35,8 +35,9 @@ describe('admin get lists', () => {
35
35
  })
36
36
 
37
37
  afterAll(async () => {
38
+ // @TODO figure out why we even need this in afterAll ?
38
39
  AtpAgent.configure({ appLabelers: [BSKY_LABELER_DID] })
39
- await network.close()
40
+ await network?.close()
40
41
  })
41
42
 
42
43
  const getAlicesList = async () => {
@@ -26,7 +26,7 @@ describe('get profiles through ozone', () => {
26
26
  })
27
27
 
28
28
  afterAll(async () => {
29
- await network.close()
29
+ await network?.close()
30
30
  })
31
31
 
32
32
  it('allows getting profiles by dids for takendown accounts.', async () => {
@@ -38,7 +38,7 @@ describe('admin get record view', () => {
38
38
  })
39
39
 
40
40
  afterAll(async () => {
41
- await network.close()
41
+ await network?.close()
42
42
  })
43
43
 
44
44
  beforeAll(async () => {
@@ -37,7 +37,7 @@ describe('admin get records view', () => {
37
37
  })
38
38
 
39
39
  afterAll(async () => {
40
- await network.close()
40
+ await network?.close()
41
41
  })
42
42
 
43
43
  beforeAll(async () => {
@@ -43,7 +43,7 @@ describe('admin get repo view', () => {
43
43
  })
44
44
 
45
45
  afterAll(async () => {
46
- await network.close()
46
+ await network?.close()
47
47
  })
48
48
 
49
49
  beforeAll(async () => {
@@ -29,7 +29,7 @@ describe('ozone-get-report', () => {
29
29
  })
30
30
 
31
31
  afterAll(async () => {
32
- await network.close()
32
+ await network?.close()
33
33
  })
34
34
 
35
35
  it('returns a single report by id', async () => {
@@ -28,7 +28,7 @@ describe('reporter-stats', () => {
28
28
  })
29
29
 
30
30
  afterAll(async () => {
31
- await network.close()
31
+ await network?.close()
32
32
  })
33
33
 
34
34
  const getReporterStats = async (
@@ -43,7 +43,7 @@ describe('admin get multiple repos', () => {
43
43
  })
44
44
 
45
45
  afterAll(async () => {
46
- await network.close()
46
+ await network?.close()
47
47
  })
48
48
 
49
49
  beforeAll(async () => {
@@ -30,7 +30,7 @@ describe('admin get starter pack view', () => {
30
30
  })
31
31
 
32
32
  afterAll(async () => {
33
- await network.close()
33
+ await network?.close()
34
34
  })
35
35
 
36
36
  beforeAll(async () => {
@@ -37,7 +37,7 @@ describe('admin get multiple subjects with all relevant details', () => {
37
37
  })
38
38
 
39
39
  afterAll(async () => {
40
- await network.close()
40
+ await network?.close()
41
41
  })
42
42
 
43
43
  beforeAll(async () => {
@@ -21,7 +21,7 @@ describe('mod-tool tracking', () => {
21
21
  })
22
22
 
23
23
  afterAll(async () => {
24
- await network.close()
24
+ await network?.close()
25
25
  })
26
26
 
27
27
  it('stores and returns modTool with name and meta metadata', async () => {
@@ -30,7 +30,7 @@ describe('moderation-appeals', () => {
30
30
  })
31
31
 
32
32
  afterAll(async () => {
33
- await network.close()
33
+ await network?.close()
34
34
  })
35
35
 
36
36
  const assertSubjectStatus = async (
@@ -75,7 +75,7 @@ describe('moderation-events', () => {
75
75
  })
76
76
 
77
77
  afterAll(async () => {
78
- await network.close()
78
+ await network?.close()
79
79
  })
80
80
 
81
81
  describe('query events', () => {
@@ -24,7 +24,7 @@ describe('moderation-status-tags', () => {
24
24
  })
25
25
 
26
26
  afterAll(async () => {
27
- await network.close()
27
+ await network?.close()
28
28
  })
29
29
 
30
30
  describe('manage tags on subject status', () => {
@@ -80,7 +80,7 @@ describe('moderation-statuses', () => {
80
80
  })
81
81
 
82
82
  afterAll(async () => {
83
- await network.close()
83
+ await network?.close()
84
84
  })
85
85
 
86
86
  describe('query statuses', () => {
@@ -81,7 +81,7 @@ describe('moderation', () => {
81
81
  })
82
82
 
83
83
  afterAll(async () => {
84
- await network.close()
84
+ await network?.close()
85
85
  })
86
86
 
87
87
  describe('reporting', () => {
@@ -30,7 +30,7 @@ describe('protected-tags', () => {
30
30
  })
31
31
 
32
32
  afterAll(async () => {
33
- await network.close()
33
+ await network?.close()
34
34
  })
35
35
 
36
36
  describe('Settings management', () => {
@@ -70,7 +70,7 @@ describe('ozone query labels', () => {
70
70
  })
71
71
 
72
72
  afterAll(async () => {
73
- await network.close()
73
+ await network?.close()
74
74
  })
75
75
 
76
76
  it('returns all labels', async () => {
@@ -91,7 +91,7 @@ describe('query-reports', () => {
91
91
  })
92
92
 
93
93
  afterAll(async () => {
94
- await network.close()
94
+ await network?.close()
95
95
  })
96
96
 
97
97
  describe('queryReports', () => {
@@ -106,7 +106,7 @@ describe('queue', () => {
106
106
  })
107
107
 
108
108
  afterAll(async () => {
109
- await network.close()
109
+ await network?.close()
110
110
  })
111
111
 
112
112
  it('get active assignments', async () => {
@@ -91,7 +91,7 @@ describe('queue-router', () => {
91
91
  })
92
92
 
93
93
  afterAll(async () => {
94
- await network.close()
94
+ await network?.close()
95
95
  })
96
96
 
97
97
  it('inserts report rows with no queue assignment when no queues are configured', async () => {
@@ -109,7 +109,7 @@ describe('ozone-queues', () => {
109
109
  })
110
110
 
111
111
  afterAll(async () => {
112
- await network.close()
112
+ await network?.close()
113
113
  })
114
114
 
115
115
  describe('createQueue', () => {
@@ -32,7 +32,7 @@ describe('record and account events on moderation subjects', () => {
32
32
  })
33
33
 
34
34
  afterAll(async () => {
35
- await network.close()
35
+ await network?.close()
36
36
  })
37
37
 
38
38
  const getSubjectStatus = async (