@atproto/ozone 0.0.2 → 0.0.5

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 (75) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/api/admin/listCommunicationTemplates.d.ts +3 -0
  3. package/dist/api/admin/updateCommunicationTemplate.d.ts +3 -0
  4. package/dist/communication-service/template.d.ts +18 -0
  5. package/dist/context.d.ts +3 -0
  6. package/dist/db/index.js +18 -1
  7. package/dist/db/index.js.map +3 -3
  8. package/dist/db/migrations/20240116T085607200Z-communication-template.d.ts +3 -0
  9. package/dist/db/migrations/index.d.ts +1 -0
  10. package/dist/db/schema/communication_template.d.ts +15 -0
  11. package/dist/db/schema/index.d.ts +2 -1
  12. package/dist/index.js +971 -240
  13. package/dist/index.js.map +3 -3
  14. package/dist/lexicon/index.d.ts +10 -0
  15. package/dist/lexicon/lexicons.d.ts +230 -0
  16. package/dist/lexicon/types/app/bsky/unspecced/{getPopular.d.ts → getTaggedSuggestions.d.ts} +10 -6
  17. package/dist/lexicon/types/{app/bsky/moderation/getService.d.ts → com/atproto/admin/createCommunicationTemplate.d.ts} +13 -5
  18. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +13 -0
  19. package/dist/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.d.ts +25 -0
  20. package/dist/lexicon/types/{app/bsky/moderation/getServices.d.ts → com/atproto/admin/listCommunicationTemplates.d.ts} +2 -3
  21. package/dist/lexicon/types/com/atproto/admin/updateCommunicationTemplate.d.ts +39 -0
  22. package/package.json +8 -8
  23. package/src/api/admin/createCommunicationTemplate.ts +37 -0
  24. package/src/api/admin/deleteCommunicationTemplate.ts +23 -0
  25. package/src/api/admin/listCommunicationTemplates.ts +31 -0
  26. package/src/api/admin/updateCommunicationTemplate.ts +40 -0
  27. package/src/api/index.ts +8 -0
  28. package/src/communication-service/template.ts +105 -0
  29. package/src/context.ts +12 -0
  30. package/src/db/migrations/20240116T085607200Z-communication-template.ts +23 -0
  31. package/src/db/migrations/index.ts +1 -0
  32. package/src/db/schema/communication_template.ts +18 -0
  33. package/src/db/schema/index.ts +3 -1
  34. package/src/lexicon/index.ts +60 -0
  35. package/src/lexicon/lexicons.ts +249 -0
  36. package/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts +65 -0
  37. package/src/lexicon/types/com/atproto/admin/createCommunicationTemplate.ts +54 -0
  38. package/src/lexicon/types/com/atproto/admin/defs.ts +35 -0
  39. package/src/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.ts +38 -0
  40. package/src/lexicon/types/com/atproto/admin/listCommunicationTemplates.ts +44 -0
  41. package/src/lexicon/types/com/atproto/admin/updateCommunicationTemplate.ts +57 -0
  42. package/tests/communication-templates.test.ts +131 -0
  43. package/dist/api/com/atproto/admin/emitModerationEvent.d.ts +0 -3
  44. package/dist/api/com/atproto/admin/getModerationEvent.d.ts +0 -3
  45. package/dist/api/com/atproto/admin/getRecord.d.ts +0 -3
  46. package/dist/api/com/atproto/admin/getRepo.d.ts +0 -3
  47. package/dist/api/com/atproto/admin/queryModerationEvents.d.ts +0 -3
  48. package/dist/api/com/atproto/admin/queryModerationStatuses.d.ts +0 -3
  49. package/dist/api/com/atproto/admin/searchRepos.d.ts +0 -3
  50. package/dist/api/com/atproto/admin/util.d.ts +0 -5
  51. package/dist/api/com/atproto/moderation/createReport.d.ts +0 -3
  52. package/dist/api/com/atproto/moderation/util.d.ts +0 -4
  53. package/dist/api/com/atproto/temp/fetchLabels.d.ts +0 -3
  54. package/dist/api/util.d.ts +0 -2
  55. package/dist/auth-verifier.d.ts +0 -47
  56. package/dist/config.d.ts +0 -42
  57. package/dist/daemon/config.d.ts +0 -23
  58. package/dist/lexicon/types/app/bsky/moderation/defs.d.ts +0 -49
  59. package/dist/lexicon/types/app/bsky/moderation/service.d.ts +0 -17
  60. package/dist/sequencer/index.d.ts +0 -2
  61. package/dist/sequencer/outbox.d.ts +0 -16
  62. package/dist/sequencer/sequencer.d.ts +0 -35
  63. package/dist/services/index.d.ts +0 -7
  64. package/dist/services/moderation/index.d.ts +0 -144
  65. package/dist/services/moderation/status.d.ts +0 -12
  66. package/dist/services/moderation/subject.d.ts +0 -60
  67. package/dist/services/moderation/types.d.ts +0 -19
  68. package/dist/services/moderation/views.d.ts +0 -42
  69. package/dist/services/types.d.ts +0 -2
  70. package/dist/util/date.d.ts +0 -1
  71. package/dist/util/debug.d.ts +0 -1
  72. package/dist/util/retry.d.ts +0 -3
  73. package/test.log +0 -0
  74. /package/dist/api/{label/queryLabels.d.ts → admin/createCommunicationTemplate.d.ts} +0 -0
  75. /package/dist/api/{label/subscribeLabels.d.ts → admin/deleteCommunicationTemplate.d.ts} +0 -0
@@ -0,0 +1,40 @@
1
+ import { AuthRequiredError, InvalidRequestError } from '@atproto/xrpc-server'
2
+ import { Server } from '../../lexicon'
3
+ import AppContext from '../../context'
4
+
5
+ export default function (server: Server, ctx: AppContext) {
6
+ server.com.atproto.admin.updateCommunicationTemplate({
7
+ auth: ctx.roleVerifier,
8
+ handler: async ({ input, auth }) => {
9
+ const access = auth.credentials
10
+ const db = ctx.db
11
+ const { id, updatedBy, ...template } = input.body
12
+
13
+ if (!access.admin) {
14
+ throw new AuthRequiredError(
15
+ 'Must be an admin to update a communication template',
16
+ )
17
+ }
18
+
19
+ // Once auth starts providing us with the caller's DID, we can get rid of this check
20
+ if (!updatedBy) {
21
+ throw new InvalidRequestError('updatedBy field is required')
22
+ }
23
+
24
+ if (!Object.keys(template).length) {
25
+ throw new InvalidRequestError('Missing update data in request body')
26
+ }
27
+
28
+ const communicationTemplate = ctx.communicationTemplateService(db)
29
+ const updatedTemplate = await communicationTemplate.update(Number(id), {
30
+ ...template,
31
+ lastUpdatedBy: updatedBy,
32
+ })
33
+
34
+ return {
35
+ encoding: 'application/json',
36
+ body: communicationTemplate.view(updatedTemplate),
37
+ }
38
+ },
39
+ })
40
+ }
package/src/api/index.ts CHANGED
@@ -9,6 +9,10 @@ import queryModerationStatuses from './admin/queryModerationStatuses'
9
9
  import queryModerationEvents from './admin/queryModerationEvents'
10
10
  import getModerationEvent from './admin/getModerationEvent'
11
11
  import fetchLabels from './temp/fetchLabels'
12
+ import createCommunicationTemplate from './admin/createCommunicationTemplate'
13
+ import updateCommunicationTemplate from './admin/updateCommunicationTemplate'
14
+ import deleteCommunicationTemplate from './admin/deleteCommunicationTemplate'
15
+ import listCommunicationTemplates from './admin/listCommunicationTemplates'
12
16
 
13
17
  export * as health from './health'
14
18
 
@@ -24,5 +28,9 @@ export default function (server: Server, ctx: AppContext) {
24
28
  queryModerationEvents(server, ctx)
25
29
  queryModerationStatuses(server, ctx)
26
30
  fetchLabels(server, ctx)
31
+ listCommunicationTemplates(server, ctx)
32
+ createCommunicationTemplate(server, ctx)
33
+ updateCommunicationTemplate(server, ctx)
34
+ deleteCommunicationTemplate(server, ctx)
27
35
  return server
28
36
  }
@@ -0,0 +1,105 @@
1
+ import Database from '../db'
2
+ import { Selectable } from 'kysely'
3
+ import { CommunicationTemplate } from '../db/schema/communication_template'
4
+ import { CommunicationTemplateView } from '../lexicon/types/com/atproto/admin/defs'
5
+
6
+ export type CommunicationTemplateServiceCreator = (
7
+ db: Database,
8
+ ) => CommunicationTemplateService
9
+
10
+ export class CommunicationTemplateService {
11
+ constructor(public db: Database) {}
12
+
13
+ static creator() {
14
+ return (db: Database) => new CommunicationTemplateService(db)
15
+ }
16
+
17
+ async list(): Promise<Selectable<CommunicationTemplate>[]> {
18
+ const list = await this.db.db
19
+ .selectFrom('communication_template')
20
+ .selectAll()
21
+ .execute()
22
+
23
+ return list
24
+ }
25
+
26
+ async create({
27
+ name,
28
+ contentMarkdown,
29
+ subject,
30
+ disabled,
31
+ updatedAt,
32
+ createdAt,
33
+ lastUpdatedBy,
34
+ }: Omit<
35
+ Selectable<CommunicationTemplate>,
36
+ 'id' | 'createdAt' | 'updatedAt'
37
+ > & {
38
+ createdAt?: Date
39
+ updatedAt?: Date
40
+ }): Promise<Selectable<CommunicationTemplate>> {
41
+ const newTemplate = await this.db.db
42
+ .insertInto('communication_template')
43
+ .values({
44
+ name,
45
+ contentMarkdown,
46
+ subject,
47
+ disabled,
48
+ lastUpdatedBy,
49
+ updatedAt: updatedAt || new Date(),
50
+ createdAt: createdAt || new Date(),
51
+ })
52
+ .returningAll()
53
+ .executeTakeFirstOrThrow()
54
+
55
+ return newTemplate
56
+ }
57
+
58
+ async update(
59
+ id: number,
60
+ {
61
+ name,
62
+ contentMarkdown,
63
+ subject,
64
+ disabled,
65
+ updatedAt,
66
+ lastUpdatedBy,
67
+ }: Partial<Omit<Selectable<CommunicationTemplate>, 'id' | 'createdAt'>>,
68
+ ): Promise<Selectable<CommunicationTemplate>> {
69
+ const updatedTemplate = await this.db.db
70
+ .updateTable('communication_template')
71
+ .where('id', '=', id)
72
+ .set({
73
+ name,
74
+ contentMarkdown,
75
+ subject,
76
+ disabled,
77
+ lastUpdatedBy,
78
+ updatedAt: updatedAt || new Date(),
79
+ })
80
+ .returningAll()
81
+ .executeTakeFirstOrThrow()
82
+
83
+ return updatedTemplate
84
+ }
85
+
86
+ async delete(id: number): Promise<void> {
87
+ await this.db.db
88
+ .deleteFrom('communication_template')
89
+ .where('id', '=', id)
90
+ .execute()
91
+ }
92
+
93
+ view(template: Selectable<CommunicationTemplate>): CommunicationTemplateView {
94
+ return {
95
+ id: `${template.id}`,
96
+ name: template.name,
97
+ contentMarkdown: template.contentMarkdown,
98
+ disabled: template.disabled,
99
+ subject: template.subject || undefined,
100
+ createdAt: template.createdAt.toISOString(),
101
+ updatedAt: template.updatedAt.toISOString(),
102
+ lastUpdatedBy: template.lastUpdatedBy,
103
+ }
104
+ }
105
+ }
package/src/context.ts CHANGED
@@ -10,11 +10,16 @@ import * as auth from './auth'
10
10
  import { BackgroundQueue } from './background'
11
11
  import assert from 'assert'
12
12
  import { EventPusher } from './daemon'
13
+ import {
14
+ CommunicationTemplateService,
15
+ CommunicationTemplateServiceCreator,
16
+ } from './communication-service/template'
13
17
 
14
18
  export type AppContextOptions = {
15
19
  db: Database
16
20
  cfg: OzoneConfig
17
21
  modService: ModerationServiceCreator
22
+ communicationTemplateService: CommunicationTemplateServiceCreator
18
23
  appviewAgent: AtpAgent
19
24
  pdsAgent: AtpAgent | undefined
20
25
  signingKey: Keypair
@@ -62,6 +67,8 @@ export class AppContext {
62
67
  appviewAuth,
63
68
  )
64
69
 
70
+ const communicationTemplateService = CommunicationTemplateService.creator()
71
+
65
72
  const idResolver = new IdResolver({
66
73
  plcUrl: cfg.identity.plcUrl,
67
74
  })
@@ -71,6 +78,7 @@ export class AppContext {
71
78
  db,
72
79
  cfg,
73
80
  modService,
81
+ communicationTemplateService,
74
82
  appviewAgent,
75
83
  pdsAgent,
76
84
  signingKey,
@@ -102,6 +110,10 @@ export class AppContext {
102
110
  return this.opts.modService
103
111
  }
104
112
 
113
+ get communicationTemplateService(): CommunicationTemplateServiceCreator {
114
+ return this.opts.communicationTemplateService
115
+ }
116
+
105
117
  get appviewAgent(): AtpAgent {
106
118
  return this.opts.appviewAgent
107
119
  }
@@ -0,0 +1,23 @@
1
+ import { Kysely } from 'kysely'
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await db.schema
5
+ .createTable('communication_template')
6
+ .addColumn('id', 'serial', (col) => col.primaryKey())
7
+ .addColumn('name', 'varchar', (col) => col.notNull())
8
+ .addColumn('contentMarkdown', 'varchar', (col) => col.notNull())
9
+ .addColumn('subject', 'varchar')
10
+ .addColumn('disabled', 'boolean', (col) => col.defaultTo(false).notNull())
11
+ .addColumn('createdAt', 'timestamptz')
12
+ .addColumn('updatedAt', 'timestamptz')
13
+ .addColumn('lastUpdatedBy', 'varchar', (col) => col.notNull())
14
+ .addUniqueConstraint('communication_template_unique_name', [
15
+ 'name',
16
+ 'disabled',
17
+ ])
18
+ .execute()
19
+ }
20
+
21
+ export async function down(db: Kysely<unknown>): Promise<void> {
22
+ await db.schema.dropTable('communication_template')
23
+ }
@@ -3,3 +3,4 @@
3
3
  // this with kysely's FileMigrationProvider, but it doesn't play nicely with the build process.
4
4
 
5
5
  export * as _20231219T205730722Z from './20231219T205730722Z-init'
6
+ export * as _20240116T085607200Z from './20240116T085607200Z-communication-template'
@@ -0,0 +1,18 @@
1
+ import { Generated, GeneratedAlways } from 'kysely'
2
+
3
+ export const communicationTemplateTableName = 'communication_template'
4
+
5
+ export interface CommunicationTemplate {
6
+ id: GeneratedAlways<number>
7
+ name: string
8
+ contentMarkdown: string
9
+ subject: string | null
10
+ disabled: Generated<boolean>
11
+ createdAt: Date
12
+ updatedAt: Date
13
+ lastUpdatedBy: string
14
+ }
15
+
16
+ export type PartialDB = {
17
+ [communicationTemplateTableName]: CommunicationTemplate
18
+ }
@@ -5,13 +5,15 @@ import * as repoPushEvent from './repo_push_event'
5
5
  import * as recordPushEvent from './record_push_event'
6
6
  import * as blobPushEvent from './blob_push_event'
7
7
  import * as label from './label'
8
+ import * as communicationTemplate from './communication_template'
8
9
 
9
10
  export type DatabaseSchemaType = modEvent.PartialDB &
10
11
  modSubjectStatus.PartialDB &
11
12
  label.PartialDB &
12
13
  repoPushEvent.PartialDB &
13
14
  recordPushEvent.PartialDB &
14
- blobPushEvent.PartialDB
15
+ blobPushEvent.PartialDB &
16
+ communicationTemplate.PartialDB
15
17
 
16
18
  export type DatabaseSchema = Kysely<DatabaseSchemaType>
17
19
 
@@ -9,7 +9,9 @@ import {
9
9
  StreamAuthVerifier,
10
10
  } from '@atproto/xrpc-server'
11
11
  import { schemas } from './lexicons'
12
+ import * as ComAtprotoAdminCreateCommunicationTemplate from './types/com/atproto/admin/createCommunicationTemplate'
12
13
  import * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount'
14
+ import * as ComAtprotoAdminDeleteCommunicationTemplate from './types/com/atproto/admin/deleteCommunicationTemplate'
13
15
  import * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites'
14
16
  import * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes'
15
17
  import * as ComAtprotoAdminEmitModerationEvent from './types/com/atproto/admin/emitModerationEvent'
@@ -21,12 +23,14 @@ import * as ComAtprotoAdminGetModerationEvent from './types/com/atproto/admin/ge
21
23
  import * as ComAtprotoAdminGetRecord from './types/com/atproto/admin/getRecord'
22
24
  import * as ComAtprotoAdminGetRepo from './types/com/atproto/admin/getRepo'
23
25
  import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus'
26
+ import * as ComAtprotoAdminListCommunicationTemplates from './types/com/atproto/admin/listCommunicationTemplates'
24
27
  import * as ComAtprotoAdminQueryModerationEvents from './types/com/atproto/admin/queryModerationEvents'
25
28
  import * as ComAtprotoAdminQueryModerationStatuses from './types/com/atproto/admin/queryModerationStatuses'
26
29
  import * as ComAtprotoAdminSearchRepos from './types/com/atproto/admin/searchRepos'
27
30
  import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail'
28
31
  import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail'
29
32
  import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle'
33
+ import * as ComAtprotoAdminUpdateCommunicationTemplate from './types/com/atproto/admin/updateCommunicationTemplate'
30
34
  import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus'
31
35
  import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle'
32
36
  import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle'
@@ -120,6 +124,7 @@ import * as AppBskyNotificationListNotifications from './types/app/bsky/notifica
120
124
  import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush'
121
125
  import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen'
122
126
  import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators'
127
+ import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions'
123
128
  import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton'
124
129
  import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton'
125
130
  import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton'
@@ -200,6 +205,17 @@ export class ComAtprotoAdminNS {
200
205
  this._server = server
201
206
  }
202
207
 
208
+ createCommunicationTemplate<AV extends AuthVerifier>(
209
+ cfg: ConfigOf<
210
+ AV,
211
+ ComAtprotoAdminCreateCommunicationTemplate.Handler<ExtractAuth<AV>>,
212
+ ComAtprotoAdminCreateCommunicationTemplate.HandlerReqCtx<ExtractAuth<AV>>
213
+ >,
214
+ ) {
215
+ const nsid = 'com.atproto.admin.createCommunicationTemplate' // @ts-ignore
216
+ return this._server.xrpc.method(nsid, cfg)
217
+ }
218
+
203
219
  deleteAccount<AV extends AuthVerifier>(
204
220
  cfg: ConfigOf<
205
221
  AV,
@@ -211,6 +227,17 @@ export class ComAtprotoAdminNS {
211
227
  return this._server.xrpc.method(nsid, cfg)
212
228
  }
213
229
 
230
+ deleteCommunicationTemplate<AV extends AuthVerifier>(
231
+ cfg: ConfigOf<
232
+ AV,
233
+ ComAtprotoAdminDeleteCommunicationTemplate.Handler<ExtractAuth<AV>>,
234
+ ComAtprotoAdminDeleteCommunicationTemplate.HandlerReqCtx<ExtractAuth<AV>>
235
+ >,
236
+ ) {
237
+ const nsid = 'com.atproto.admin.deleteCommunicationTemplate' // @ts-ignore
238
+ return this._server.xrpc.method(nsid, cfg)
239
+ }
240
+
214
241
  disableAccountInvites<AV extends AuthVerifier>(
215
242
  cfg: ConfigOf<
216
243
  AV,
@@ -332,6 +359,17 @@ export class ComAtprotoAdminNS {
332
359
  return this._server.xrpc.method(nsid, cfg)
333
360
  }
334
361
 
362
+ listCommunicationTemplates<AV extends AuthVerifier>(
363
+ cfg: ConfigOf<
364
+ AV,
365
+ ComAtprotoAdminListCommunicationTemplates.Handler<ExtractAuth<AV>>,
366
+ ComAtprotoAdminListCommunicationTemplates.HandlerReqCtx<ExtractAuth<AV>>
367
+ >,
368
+ ) {
369
+ const nsid = 'com.atproto.admin.listCommunicationTemplates' // @ts-ignore
370
+ return this._server.xrpc.method(nsid, cfg)
371
+ }
372
+
335
373
  queryModerationEvents<AV extends AuthVerifier>(
336
374
  cfg: ConfigOf<
337
375
  AV,
@@ -398,6 +436,17 @@ export class ComAtprotoAdminNS {
398
436
  return this._server.xrpc.method(nsid, cfg)
399
437
  }
400
438
 
439
+ updateCommunicationTemplate<AV extends AuthVerifier>(
440
+ cfg: ConfigOf<
441
+ AV,
442
+ ComAtprotoAdminUpdateCommunicationTemplate.Handler<ExtractAuth<AV>>,
443
+ ComAtprotoAdminUpdateCommunicationTemplate.HandlerReqCtx<ExtractAuth<AV>>
444
+ >,
445
+ ) {
446
+ const nsid = 'com.atproto.admin.updateCommunicationTemplate' // @ts-ignore
447
+ return this._server.xrpc.method(nsid, cfg)
448
+ }
449
+
401
450
  updateSubjectStatus<AV extends AuthVerifier>(
402
451
  cfg: ConfigOf<
403
452
  AV,
@@ -1565,6 +1614,17 @@ export class AppBskyUnspeccedNS {
1565
1614
  return this._server.xrpc.method(nsid, cfg)
1566
1615
  }
1567
1616
 
1617
+ getTaggedSuggestions<AV extends AuthVerifier>(
1618
+ cfg: ConfigOf<
1619
+ AV,
1620
+ AppBskyUnspeccedGetTaggedSuggestions.Handler<ExtractAuth<AV>>,
1621
+ AppBskyUnspeccedGetTaggedSuggestions.HandlerReqCtx<ExtractAuth<AV>>
1622
+ >,
1623
+ ) {
1624
+ const nsid = 'app.bsky.unspecced.getTaggedSuggestions' // @ts-ignore
1625
+ return this._server.xrpc.method(nsid, cfg)
1626
+ }
1627
+
1568
1628
  getTimelineSkeleton<AV extends AuthVerifier>(
1569
1629
  cfg: ConfigOf<
1570
1630
  AV,