@atproto/bsky 0.0.25 → 0.0.27

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 (81) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/buf.gen.yaml +12 -0
  3. package/dist/api/app/bsky/graph/getRelationships.d.ts +3 -0
  4. package/dist/api/app/bsky/unspecced/getTaggedSuggestions.d.ts +3 -0
  5. package/dist/bsync.d.ts +8 -0
  6. package/dist/config.d.ts +20 -0
  7. package/dist/context.d.ts +6 -3
  8. package/dist/courier.d.ts +8 -0
  9. package/dist/db/database-schema.d.ts +2 -1
  10. package/dist/db/index.js +15 -1
  11. package/dist/db/index.js.map +3 -3
  12. package/dist/db/migrations/20240124T023719200Z-tagged-suggestions.d.ts +3 -0
  13. package/dist/db/migrations/index.d.ts +1 -0
  14. package/dist/db/tables/tagged-suggestion.d.ts +9 -0
  15. package/dist/index.js +48246 -16828
  16. package/dist/index.js.map +3 -3
  17. package/dist/indexer/config.d.ts +8 -0
  18. package/dist/indexer/context.d.ts +3 -0
  19. package/dist/ingester/config.d.ts +8 -0
  20. package/dist/ingester/context.d.ts +3 -0
  21. package/dist/ingester/mute-subscription.d.ts +22 -0
  22. package/dist/lexicon/index.d.ts +4 -0
  23. package/dist/lexicon/lexicons.d.ts +153 -0
  24. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +7 -1
  25. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +15 -0
  26. package/dist/lexicon/types/app/bsky/graph/getRelationships.d.ts +38 -0
  27. package/dist/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.d.ts +39 -0
  28. package/dist/notifications.d.ts +27 -16
  29. package/dist/proto/bsync_connect.d.ts +25 -0
  30. package/dist/proto/bsync_pb.d.ts +90 -0
  31. package/dist/proto/courier_connect.d.ts +25 -0
  32. package/dist/proto/courier_pb.d.ts +91 -0
  33. package/dist/services/actor/index.d.ts +2 -2
  34. package/dist/services/indexing/index.d.ts +2 -2
  35. package/dist/services/util/post.d.ts +6 -6
  36. package/dist/util/retry.d.ts +2 -0
  37. package/package.json +15 -7
  38. package/proto/courier.proto +56 -0
  39. package/src/api/app/bsky/graph/getRelationships.ts +71 -0
  40. package/src/api/app/bsky/graph/muteActor.ts +32 -5
  41. package/src/api/app/bsky/graph/muteActorList.ts +32 -5
  42. package/src/api/app/bsky/graph/unmuteActor.ts +32 -5
  43. package/src/api/app/bsky/graph/unmuteActorList.ts +32 -5
  44. package/src/api/app/bsky/notification/registerPush.ts +42 -8
  45. package/src/api/app/bsky/unspecced/getTaggedSuggestions.ts +21 -0
  46. package/src/api/index.ts +4 -0
  47. package/src/bsync.ts +41 -0
  48. package/src/config.ts +79 -0
  49. package/src/context.ts +12 -6
  50. package/src/courier.ts +41 -0
  51. package/src/db/database-schema.ts +2 -0
  52. package/src/db/migrations/20240124T023719200Z-tagged-suggestions.ts +15 -0
  53. package/src/db/migrations/index.ts +1 -0
  54. package/src/db/tables/tagged-suggestion.ts +11 -0
  55. package/src/index.ts +26 -3
  56. package/src/indexer/config.ts +36 -0
  57. package/src/indexer/context.ts +6 -0
  58. package/src/indexer/index.ts +27 -3
  59. package/src/ingester/config.ts +34 -0
  60. package/src/ingester/context.ts +6 -0
  61. package/src/ingester/index.ts +18 -0
  62. package/src/ingester/mute-subscription.ts +213 -0
  63. package/src/lexicon/index.ts +24 -0
  64. package/src/lexicon/lexicons.ts +167 -0
  65. package/src/lexicon/types/app/bsky/actor/defs.ts +19 -0
  66. package/src/lexicon/types/app/bsky/graph/defs.ts +41 -0
  67. package/src/lexicon/types/app/bsky/graph/getRelationships.ts +53 -0
  68. package/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts +65 -0
  69. package/src/notifications.ts +165 -149
  70. package/src/proto/bsync_connect.ts +54 -0
  71. package/src/proto/bsync_pb.ts +459 -0
  72. package/src/proto/courier_connect.ts +50 -0
  73. package/src/proto/courier_pb.ts +473 -0
  74. package/src/services/actor/index.ts +17 -2
  75. package/src/services/indexing/processor.ts +1 -1
  76. package/src/util/retry.ts +12 -0
  77. package/tests/notification-server.test.ts +59 -19
  78. package/tests/subscription/mutes.test.ts +170 -0
  79. package/tests/views/__snapshots__/follows.test.ts.snap +28 -0
  80. package/tests/views/follows.test.ts +10 -0
  81. package/tests/views/suggestions.test.ts +22 -0
@@ -19,6 +19,10 @@ export interface IndexerConfigValues {
19
19
  fuzzyFalsePositiveB64?: string;
20
20
  labelerKeywords: Record<string, string>;
21
21
  moderationPushUrl: string;
22
+ courierUrl?: string;
23
+ courierApiKey?: string;
24
+ courierHttpVersion?: '1.1' | '2';
25
+ courierIgnoreBadTls?: boolean;
22
26
  indexerConcurrency?: number;
23
27
  indexerPartitionIds: number[];
24
28
  indexerPartitionBatchSize?: number;
@@ -45,6 +49,10 @@ export declare class IndexerConfig {
45
49
  get didCacheMaxTTL(): number;
46
50
  get handleResolveNameservers(): string[] | undefined;
47
51
  get moderationPushUrl(): string;
52
+ get courierUrl(): string | undefined;
53
+ get courierApiKey(): string | undefined;
54
+ get courierHttpVersion(): "2" | "1.1" | undefined;
55
+ get courierIgnoreBadTls(): boolean | undefined;
48
56
  get hiveApiKey(): string | undefined;
49
57
  get abyssEndpoint(): string | undefined;
50
58
  get abyssPassword(): string | undefined;
@@ -6,6 +6,7 @@ import { BackgroundQueue } from '../background';
6
6
  import DidSqlCache from '../did-cache';
7
7
  import { Redis } from '../redis';
8
8
  import { AutoModerator } from '../auto-moderator';
9
+ import { NotificationServer } from '../notifications';
9
10
  export declare class IndexerContext {
10
11
  private opts;
11
12
  constructor(opts: {
@@ -18,6 +19,7 @@ export declare class IndexerContext {
18
19
  didCache: DidSqlCache;
19
20
  backgroundQueue: BackgroundQueue;
20
21
  autoMod: AutoModerator;
22
+ notifServer?: NotificationServer;
21
23
  });
22
24
  get db(): PrimaryDatabase;
23
25
  get redis(): Redis;
@@ -28,5 +30,6 @@ export declare class IndexerContext {
28
30
  get didCache(): DidSqlCache;
29
31
  get backgroundQueue(): BackgroundQueue;
30
32
  get autoMod(): AutoModerator;
33
+ get notifServer(): NotificationServer | undefined;
31
34
  }
32
35
  export default IndexerContext;
@@ -8,6 +8,10 @@ export interface IngesterConfigValues {
8
8
  redisPassword?: string;
9
9
  repoProvider: string;
10
10
  labelProvider?: string;
11
+ bsyncUrl?: string;
12
+ bsyncApiKey?: string;
13
+ bsyncHttpVersion?: '1.1' | '2';
14
+ bsyncIgnoreBadTls?: boolean;
11
15
  ingesterPartitionCount: number;
12
16
  ingesterNamespace?: string;
13
17
  ingesterSubLockId?: number;
@@ -28,6 +32,10 @@ export declare class IngesterConfig {
28
32
  get redisPassword(): string | undefined;
29
33
  get repoProvider(): string;
30
34
  get labelProvider(): string | undefined;
35
+ get bsyncUrl(): string | undefined;
36
+ get bsyncApiKey(): string | undefined;
37
+ get bsyncHttpVersion(): "2" | "1.1" | undefined;
38
+ get bsyncIgnoreBadTls(): boolean | undefined;
31
39
  get ingesterPartitionCount(): number;
32
40
  get ingesterMaxItems(): number | undefined;
33
41
  get ingesterCheckItemsEveryN(): number | undefined;
@@ -2,6 +2,7 @@ import { PrimaryDatabase } from '../db';
2
2
  import { Redis } from '../redis';
3
3
  import { IngesterConfig } from './config';
4
4
  import { LabelSubscription } from './label-subscription';
5
+ import { MuteSubscription } from './mute-subscription';
5
6
  export declare class IngesterContext {
6
7
  private opts;
7
8
  constructor(opts: {
@@ -9,10 +10,12 @@ export declare class IngesterContext {
9
10
  redis: Redis;
10
11
  cfg: IngesterConfig;
11
12
  labelSubscription?: LabelSubscription;
13
+ muteSubscription?: MuteSubscription;
12
14
  });
13
15
  get db(): PrimaryDatabase;
14
16
  get redis(): Redis;
15
17
  get cfg(): IngesterConfig;
16
18
  get labelSubscription(): LabelSubscription | undefined;
19
+ get muteSubscription(): MuteSubscription | undefined;
17
20
  }
18
21
  export default IngesterContext;
@@ -0,0 +1,22 @@
1
+ import { PrimaryDatabase } from '../db';
2
+ import { Redis } from '../redis';
3
+ import { BsyncClient } from '../bsync';
4
+ import { MuteOperation } from '../proto/bsync_pb';
5
+ export declare class MuteSubscription {
6
+ db: PrimaryDatabase;
7
+ redis: Redis;
8
+ bsyncClient: BsyncClient;
9
+ ac: AbortController;
10
+ running: Promise<void> | undefined;
11
+ cursor: string | null;
12
+ constructor(db: PrimaryDatabase, redis: Redis, bsyncClient: BsyncClient);
13
+ start(): Promise<void>;
14
+ private run;
15
+ handleAddOp(op: MuteOperation, createdAt: Date): Promise<void>;
16
+ handleRemoveOp(op: MuteOperation): Promise<void>;
17
+ handleClearOp(op: MuteOperation): Promise<void>;
18
+ getCursor(): Promise<string | null>;
19
+ setCursor(cursor: string): Promise<void>;
20
+ destroy(): Promise<void>;
21
+ get destroyed(): boolean;
22
+ }
@@ -104,6 +104,7 @@ import * as AppBskyGraphGetListBlocks from './types/app/bsky/graph/getListBlocks
104
104
  import * as AppBskyGraphGetListMutes from './types/app/bsky/graph/getListMutes';
105
105
  import * as AppBskyGraphGetLists from './types/app/bsky/graph/getLists';
106
106
  import * as AppBskyGraphGetMutes from './types/app/bsky/graph/getMutes';
107
+ import * as AppBskyGraphGetRelationships from './types/app/bsky/graph/getRelationships';
107
108
  import * as AppBskyGraphGetSuggestedFollowsByActor from './types/app/bsky/graph/getSuggestedFollowsByActor';
108
109
  import * as AppBskyGraphMuteActor from './types/app/bsky/graph/muteActor';
109
110
  import * as AppBskyGraphMuteActorList from './types/app/bsky/graph/muteActorList';
@@ -114,6 +115,7 @@ import * as AppBskyNotificationListNotifications from './types/app/bsky/notifica
114
115
  import * as AppBskyNotificationRegisterPush from './types/app/bsky/notification/registerPush';
115
116
  import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen';
116
117
  import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators';
118
+ import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions';
117
119
  import * as AppBskyUnspeccedGetTimelineSkeleton from './types/app/bsky/unspecced/getTimelineSkeleton';
118
120
  import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton';
119
121
  import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton';
@@ -327,6 +329,7 @@ export declare class AppBskyGraphNS {
327
329
  getListMutes<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphGetListMutes.Handler<ExtractAuth<AV>>, AppBskyGraphGetListMutes.HandlerReqCtx<ExtractAuth<AV>>>): void;
328
330
  getLists<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphGetLists.Handler<ExtractAuth<AV>>, AppBskyGraphGetLists.HandlerReqCtx<ExtractAuth<AV>>>): void;
329
331
  getMutes<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphGetMutes.Handler<ExtractAuth<AV>>, AppBskyGraphGetMutes.HandlerReqCtx<ExtractAuth<AV>>>): void;
332
+ getRelationships<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphGetRelationships.Handler<ExtractAuth<AV>>, AppBskyGraphGetRelationships.HandlerReqCtx<ExtractAuth<AV>>>): void;
330
333
  getSuggestedFollowsByActor<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphGetSuggestedFollowsByActor.Handler<ExtractAuth<AV>>, AppBskyGraphGetSuggestedFollowsByActor.HandlerReqCtx<ExtractAuth<AV>>>): void;
331
334
  muteActor<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphMuteActor.Handler<ExtractAuth<AV>>, AppBskyGraphMuteActor.HandlerReqCtx<ExtractAuth<AV>>>): void;
332
335
  muteActorList<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyGraphMuteActorList.Handler<ExtractAuth<AV>>, AppBskyGraphMuteActorList.HandlerReqCtx<ExtractAuth<AV>>>): void;
@@ -349,6 +352,7 @@ export declare class AppBskyUnspeccedNS {
349
352
  _server: Server;
350
353
  constructor(server: Server);
351
354
  getPopularFeedGenerators<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyUnspeccedGetPopularFeedGenerators.Handler<ExtractAuth<AV>>, AppBskyUnspeccedGetPopularFeedGenerators.HandlerReqCtx<ExtractAuth<AV>>>): void;
355
+ getTaggedSuggestions<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyUnspeccedGetTaggedSuggestions.Handler<ExtractAuth<AV>>, AppBskyUnspeccedGetTaggedSuggestions.HandlerReqCtx<ExtractAuth<AV>>>): void;
352
356
  getTimelineSkeleton<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyUnspeccedGetTimelineSkeleton.Handler<ExtractAuth<AV>>, AppBskyUnspeccedGetTimelineSkeleton.HandlerReqCtx<ExtractAuth<AV>>>): void;
353
357
  searchActorsSkeleton<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyUnspeccedSearchActorsSkeleton.Handler<ExtractAuth<AV>>, AppBskyUnspeccedSearchActorsSkeleton.HandlerReqCtx<ExtractAuth<AV>>>): void;
354
358
  searchPostsSkeleton<AV extends AuthVerifier>(cfg: ConfigOf<AV, AppBskyUnspeccedSearchPostsSkeleton.Handler<ExtractAuth<AV>>, AppBskyUnspeccedSearchPostsSkeleton.HandlerReqCtx<ExtractAuth<AV>>>): void;
@@ -4344,6 +4344,22 @@ export declare const schemaDict: {
4344
4344
  };
4345
4345
  };
4346
4346
  };
4347
+ interestsPref: {
4348
+ type: string;
4349
+ required: string[];
4350
+ properties: {
4351
+ tags: {
4352
+ type: string;
4353
+ maxLength: number;
4354
+ items: {
4355
+ type: string;
4356
+ maxLength: number;
4357
+ maxGraphemes: number;
4358
+ };
4359
+ description: string;
4360
+ };
4361
+ };
4362
+ };
4347
4363
  };
4348
4364
  };
4349
4365
  AppBskyActorGetPreferences: {
@@ -6461,6 +6477,42 @@ export declare const schemaDict: {
6461
6477
  };
6462
6478
  };
6463
6479
  };
6480
+ notFoundActor: {
6481
+ type: string;
6482
+ description: string;
6483
+ required: string[];
6484
+ properties: {
6485
+ actor: {
6486
+ type: string;
6487
+ format: string;
6488
+ };
6489
+ notFound: {
6490
+ type: string;
6491
+ const: boolean;
6492
+ };
6493
+ };
6494
+ };
6495
+ relationship: {
6496
+ type: string;
6497
+ description: string;
6498
+ required: string[];
6499
+ properties: {
6500
+ did: {
6501
+ type: string;
6502
+ format: string;
6503
+ };
6504
+ following: {
6505
+ type: string;
6506
+ format: string;
6507
+ description: string;
6508
+ };
6509
+ followedBy: {
6510
+ type: string;
6511
+ format: string;
6512
+ description: string;
6513
+ };
6514
+ };
6515
+ };
6464
6516
  };
6465
6517
  };
6466
6518
  AppBskyGraphFollow: {
@@ -6864,6 +6916,58 @@ export declare const schemaDict: {
6864
6916
  };
6865
6917
  };
6866
6918
  };
6919
+ AppBskyGraphGetRelationships: {
6920
+ lexicon: number;
6921
+ id: string;
6922
+ defs: {
6923
+ main: {
6924
+ type: string;
6925
+ description: string;
6926
+ parameters: {
6927
+ type: string;
6928
+ required: string[];
6929
+ properties: {
6930
+ actor: {
6931
+ type: string;
6932
+ format: string;
6933
+ };
6934
+ others: {
6935
+ type: string;
6936
+ maxLength: number;
6937
+ items: {
6938
+ type: string;
6939
+ format: string;
6940
+ };
6941
+ };
6942
+ };
6943
+ };
6944
+ output: {
6945
+ encoding: string;
6946
+ schema: {
6947
+ type: string;
6948
+ required: string[];
6949
+ properties: {
6950
+ actor: {
6951
+ type: string;
6952
+ format: string;
6953
+ };
6954
+ relationships: {
6955
+ type: string;
6956
+ items: {
6957
+ type: string;
6958
+ refs: string[];
6959
+ };
6960
+ };
6961
+ };
6962
+ };
6963
+ };
6964
+ errors: {
6965
+ name: string;
6966
+ description: string;
6967
+ }[];
6968
+ };
6969
+ };
6970
+ };
6867
6971
  AppBskyGraphGetSuggestedFollowsByActor: {
6868
6972
  lexicon: number;
6869
6973
  id: string;
@@ -7423,6 +7527,53 @@ export declare const schemaDict: {
7423
7527
  };
7424
7528
  };
7425
7529
  };
7530
+ AppBskyUnspeccedGetTaggedSuggestions: {
7531
+ lexicon: number;
7532
+ id: string;
7533
+ defs: {
7534
+ main: {
7535
+ type: string;
7536
+ description: string;
7537
+ parameters: {
7538
+ type: string;
7539
+ properties: {};
7540
+ };
7541
+ output: {
7542
+ encoding: string;
7543
+ schema: {
7544
+ type: string;
7545
+ required: string[];
7546
+ properties: {
7547
+ suggestions: {
7548
+ type: string;
7549
+ items: {
7550
+ type: string;
7551
+ ref: string;
7552
+ };
7553
+ };
7554
+ };
7555
+ };
7556
+ };
7557
+ };
7558
+ suggestion: {
7559
+ type: string;
7560
+ required: string[];
7561
+ properties: {
7562
+ tag: {
7563
+ type: string;
7564
+ };
7565
+ subjectType: {
7566
+ type: string;
7567
+ knownValues: string[];
7568
+ };
7569
+ subject: {
7570
+ type: string;
7571
+ format: string;
7572
+ };
7573
+ };
7574
+ };
7575
+ };
7576
+ };
7426
7577
  AppBskyUnspeccedGetTimelineSkeleton: {
7427
7578
  lexicon: number;
7428
7579
  id: string;
@@ -7714,6 +7865,7 @@ export declare const ids: {
7714
7865
  AppBskyGraphGetListMutes: string;
7715
7866
  AppBskyGraphGetLists: string;
7716
7867
  AppBskyGraphGetMutes: string;
7868
+ AppBskyGraphGetRelationships: string;
7717
7869
  AppBskyGraphGetSuggestedFollowsByActor: string;
7718
7870
  AppBskyGraphList: string;
7719
7871
  AppBskyGraphListblock: string;
@@ -7729,6 +7881,7 @@ export declare const ids: {
7729
7881
  AppBskyRichtextFacet: string;
7730
7882
  AppBskyUnspeccedDefs: string;
7731
7883
  AppBskyUnspeccedGetPopularFeedGenerators: string;
7884
+ AppBskyUnspeccedGetTaggedSuggestions: string;
7732
7885
  AppBskyUnspeccedGetTimelineSkeleton: string;
7733
7886
  AppBskyUnspeccedSearchActorsSkeleton: string;
7734
7887
  AppBskyUnspeccedSearchPostsSkeleton: string;
@@ -54,7 +54,7 @@ export interface ViewerState {
54
54
  }
55
55
  export declare function isViewerState(v: unknown): v is ViewerState;
56
56
  export declare function validateViewerState(v: unknown): ValidationResult;
57
- export type Preferences = (AdultContentPref | ContentLabelPref | SavedFeedsPref | PersonalDetailsPref | FeedViewPref | ThreadViewPref | {
57
+ export type Preferences = (AdultContentPref | ContentLabelPref | SavedFeedsPref | PersonalDetailsPref | FeedViewPref | ThreadViewPref | InterestsPref | {
58
58
  $type: string;
59
59
  [k: string]: unknown;
60
60
  })[];
@@ -102,3 +102,9 @@ export interface ThreadViewPref {
102
102
  }
103
103
  export declare function isThreadViewPref(v: unknown): v is ThreadViewPref;
104
104
  export declare function validateThreadViewPref(v: unknown): ValidationResult;
105
+ export interface InterestsPref {
106
+ tags: string[];
107
+ [k: string]: unknown;
108
+ }
109
+ export declare function isInterestsPref(v: unknown): v is InterestsPref;
110
+ export declare function validateInterestsPref(v: unknown): ValidationResult;
@@ -45,3 +45,18 @@ export interface ListViewerState {
45
45
  }
46
46
  export declare function isListViewerState(v: unknown): v is ListViewerState;
47
47
  export declare function validateListViewerState(v: unknown): ValidationResult;
48
+ export interface NotFoundActor {
49
+ actor: string;
50
+ notFound: true;
51
+ [k: string]: unknown;
52
+ }
53
+ export declare function isNotFoundActor(v: unknown): v is NotFoundActor;
54
+ export declare function validateNotFoundActor(v: unknown): ValidationResult;
55
+ export interface Relationship {
56
+ did: string;
57
+ following?: string;
58
+ followedBy?: string;
59
+ [k: string]: unknown;
60
+ }
61
+ export declare function isRelationship(v: unknown): v is Relationship;
62
+ export declare function validateRelationship(v: unknown): ValidationResult;
@@ -0,0 +1,38 @@
1
+ import express from 'express';
2
+ import { HandlerAuth } from '@atproto/xrpc-server';
3
+ import * as AppBskyGraphDefs from './defs';
4
+ export interface QueryParams {
5
+ actor: string;
6
+ others?: string[];
7
+ }
8
+ export type InputSchema = undefined;
9
+ export interface OutputSchema {
10
+ actor?: string;
11
+ relationships: (AppBskyGraphDefs.Relationship | AppBskyGraphDefs.NotFoundActor | {
12
+ $type: string;
13
+ [k: string]: unknown;
14
+ })[];
15
+ [k: string]: unknown;
16
+ }
17
+ export type HandlerInput = undefined;
18
+ export interface HandlerSuccess {
19
+ encoding: 'application/json';
20
+ body: OutputSchema;
21
+ headers?: {
22
+ [key: string]: string;
23
+ };
24
+ }
25
+ export interface HandlerError {
26
+ status: number;
27
+ message?: string;
28
+ error?: 'ActorNotFound';
29
+ }
30
+ export type HandlerOutput = HandlerError | HandlerSuccess;
31
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
32
+ auth: HA;
33
+ params: QueryParams;
34
+ input: HandlerInput;
35
+ req: express.Request;
36
+ res: express.Response;
37
+ };
38
+ export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
@@ -0,0 +1,39 @@
1
+ import express from 'express';
2
+ import { ValidationResult } from '@atproto/lexicon';
3
+ import { HandlerAuth } from '@atproto/xrpc-server';
4
+ export interface QueryParams {
5
+ }
6
+ export type InputSchema = undefined;
7
+ export interface OutputSchema {
8
+ suggestions: Suggestion[];
9
+ [k: string]: unknown;
10
+ }
11
+ export type HandlerInput = undefined;
12
+ export interface HandlerSuccess {
13
+ encoding: 'application/json';
14
+ body: OutputSchema;
15
+ headers?: {
16
+ [key: string]: string;
17
+ };
18
+ }
19
+ export interface HandlerError {
20
+ status: number;
21
+ message?: string;
22
+ }
23
+ export type HandlerOutput = HandlerError | HandlerSuccess;
24
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
25
+ auth: HA;
26
+ params: QueryParams;
27
+ input: HandlerInput;
28
+ req: express.Request;
29
+ res: express.Response;
30
+ };
31
+ export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
32
+ export interface Suggestion {
33
+ tag: string;
34
+ subjectType: 'actor' | 'feed' | (string & {});
35
+ subject: string;
36
+ [k: string]: unknown;
37
+ }
38
+ export declare function isSuggestion(v: unknown): v is Suggestion;
39
+ export declare function validateSuggestion(v: unknown): ValidationResult;
@@ -2,8 +2,10 @@ import { Insertable } from 'kysely';
2
2
  import Database from './db/primary';
3
3
  import { Notification } from './db/tables/notification';
4
4
  import { NotificationPushToken as PushToken } from './db/tables/notification-push-token';
5
+ import { Notification as CourierNotification } from './proto/courier_pb';
6
+ import { CourierClient } from './courier';
5
7
  export type Platform = 'ios' | 'android' | 'web';
6
- type PushNotification = {
8
+ type GorushNotification = {
7
9
  tokens: string[];
8
10
  platform: 1 | 2;
9
11
  title: string;
@@ -15,28 +17,37 @@ type PushNotification = {
15
17
  collapse_id?: string;
16
18
  collapse_key?: string;
17
19
  };
18
- type InsertableNotif = Insertable<Notification>;
19
- type NotifDisplay = {
20
+ type NotifRow = Insertable<Notification>;
21
+ type NotifView = {
20
22
  key: string;
21
23
  rateLimit: boolean;
22
24
  title: string;
23
25
  body: string;
24
- notif: InsertableNotif;
26
+ notif: NotifRow;
25
27
  };
26
- export declare class NotificationServer {
28
+ export declare abstract class NotificationServer<N = unknown> {
27
29
  db: Database;
28
- pushEndpoint?: string | undefined;
30
+ constructor(db: Database);
31
+ abstract prepareNotifications(notifs: NotifRow[]): Promise<N[]>;
32
+ abstract processNotifications(prepared: N[]): Promise<void>;
33
+ getNotificationViews(notifs: NotifRow[]): Promise<NotifView[]>;
34
+ private findBlocksAndMutes;
35
+ }
36
+ export declare class GorushNotificationServer extends NotificationServer<GorushNotification> {
37
+ db: Database;
38
+ pushEndpoint: string;
29
39
  private rateLimiter;
30
- constructor(db: Database, pushEndpoint?: string | undefined);
40
+ constructor(db: Database, pushEndpoint: string);
41
+ prepareNotifications(notifs: NotifRow[]): Promise<GorushNotification[]>;
31
42
  getTokensByDid(dids: string[]): Promise<Record<string, PushToken[]>>;
32
- prepareNotifsToSend(notifications: InsertableNotif[]): Promise<PushNotification[]>;
33
- processNotifications(notifs: PushNotification[]): Promise<void>;
34
- private sendPushNotifications;
35
- registerDeviceForPushNotifications(did: string, token: string, platform: Platform, appId: string): Promise<void>;
36
- getNotificationDisplayAttributes(notifs: InsertableNotif[]): Promise<NotifDisplay[]>;
37
- findBlocksAndMutes(notifs: InsertableNotif[]): Promise<{
38
- author: string;
39
- receiver: string;
40
- }[]>;
43
+ processNotifications(prepared: GorushNotification[]): Promise<void>;
44
+ private sendToGorush;
45
+ }
46
+ export declare class CourierNotificationServer extends NotificationServer<CourierNotification> {
47
+ db: Database;
48
+ courierClient: CourierClient;
49
+ constructor(db: Database, courierClient: CourierClient);
50
+ prepareNotifications(notifs: NotifRow[]): Promise<CourierNotification[]>;
51
+ processNotifications(prepared: CourierNotification[]): Promise<void>;
41
52
  }
42
53
  export {};
@@ -0,0 +1,25 @@
1
+ import { AddMuteOperationRequest, AddMuteOperationResponse, PingRequest, PingResponse, ScanMuteOperationsRequest, ScanMuteOperationsResponse } from './bsync_pb.ts';
2
+ import { MethodKind } from '@bufbuild/protobuf';
3
+ export declare const Service: {
4
+ readonly typeName: "bsync.Service";
5
+ readonly methods: {
6
+ readonly addMuteOperation: {
7
+ readonly name: "AddMuteOperation";
8
+ readonly I: typeof AddMuteOperationRequest;
9
+ readonly O: typeof AddMuteOperationResponse;
10
+ readonly kind: MethodKind.Unary;
11
+ };
12
+ readonly scanMuteOperations: {
13
+ readonly name: "ScanMuteOperations";
14
+ readonly I: typeof ScanMuteOperationsRequest;
15
+ readonly O: typeof ScanMuteOperationsResponse;
16
+ readonly kind: MethodKind.Unary;
17
+ };
18
+ readonly ping: {
19
+ readonly name: "Ping";
20
+ readonly I: typeof PingRequest;
21
+ readonly O: typeof PingResponse;
22
+ readonly kind: MethodKind.Unary;
23
+ };
24
+ };
25
+ };
@@ -0,0 +1,90 @@
1
+ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from '@bufbuild/protobuf';
2
+ import { Message, proto3 } from '@bufbuild/protobuf';
3
+ export declare class MuteOperation extends Message<MuteOperation> {
4
+ id: string;
5
+ type: MuteOperation_Type;
6
+ actorDid: string;
7
+ subject: string;
8
+ constructor(data?: PartialMessage<MuteOperation>);
9
+ static readonly runtime: typeof proto3;
10
+ static readonly typeName = "bsync.MuteOperation";
11
+ static readonly fields: FieldList;
12
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): MuteOperation;
13
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): MuteOperation;
14
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): MuteOperation;
15
+ static equals(a: MuteOperation | PlainMessage<MuteOperation> | undefined, b: MuteOperation | PlainMessage<MuteOperation> | undefined): boolean;
16
+ }
17
+ export declare enum MuteOperation_Type {
18
+ UNSPECIFIED = 0,
19
+ ADD = 1,
20
+ REMOVE = 2,
21
+ CLEAR = 3
22
+ }
23
+ export declare class AddMuteOperationRequest extends Message<AddMuteOperationRequest> {
24
+ type: MuteOperation_Type;
25
+ actorDid: string;
26
+ subject: string;
27
+ constructor(data?: PartialMessage<AddMuteOperationRequest>);
28
+ static readonly runtime: typeof proto3;
29
+ static readonly typeName = "bsync.AddMuteOperationRequest";
30
+ static readonly fields: FieldList;
31
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddMuteOperationRequest;
32
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddMuteOperationRequest;
33
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddMuteOperationRequest;
34
+ static equals(a: AddMuteOperationRequest | PlainMessage<AddMuteOperationRequest> | undefined, b: AddMuteOperationRequest | PlainMessage<AddMuteOperationRequest> | undefined): boolean;
35
+ }
36
+ export declare class AddMuteOperationResponse extends Message<AddMuteOperationResponse> {
37
+ operation?: MuteOperation;
38
+ constructor(data?: PartialMessage<AddMuteOperationResponse>);
39
+ static readonly runtime: typeof proto3;
40
+ static readonly typeName = "bsync.AddMuteOperationResponse";
41
+ static readonly fields: FieldList;
42
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AddMuteOperationResponse;
43
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AddMuteOperationResponse;
44
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AddMuteOperationResponse;
45
+ static equals(a: AddMuteOperationResponse | PlainMessage<AddMuteOperationResponse> | undefined, b: AddMuteOperationResponse | PlainMessage<AddMuteOperationResponse> | undefined): boolean;
46
+ }
47
+ export declare class ScanMuteOperationsRequest extends Message<ScanMuteOperationsRequest> {
48
+ cursor: string;
49
+ limit: number;
50
+ constructor(data?: PartialMessage<ScanMuteOperationsRequest>);
51
+ static readonly runtime: typeof proto3;
52
+ static readonly typeName = "bsync.ScanMuteOperationsRequest";
53
+ static readonly fields: FieldList;
54
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ScanMuteOperationsRequest;
55
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ScanMuteOperationsRequest;
56
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ScanMuteOperationsRequest;
57
+ static equals(a: ScanMuteOperationsRequest | PlainMessage<ScanMuteOperationsRequest> | undefined, b: ScanMuteOperationsRequest | PlainMessage<ScanMuteOperationsRequest> | undefined): boolean;
58
+ }
59
+ export declare class ScanMuteOperationsResponse extends Message<ScanMuteOperationsResponse> {
60
+ operations: MuteOperation[];
61
+ cursor: string;
62
+ constructor(data?: PartialMessage<ScanMuteOperationsResponse>);
63
+ static readonly runtime: typeof proto3;
64
+ static readonly typeName = "bsync.ScanMuteOperationsResponse";
65
+ static readonly fields: FieldList;
66
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ScanMuteOperationsResponse;
67
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ScanMuteOperationsResponse;
68
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ScanMuteOperationsResponse;
69
+ static equals(a: ScanMuteOperationsResponse | PlainMessage<ScanMuteOperationsResponse> | undefined, b: ScanMuteOperationsResponse | PlainMessage<ScanMuteOperationsResponse> | undefined): boolean;
70
+ }
71
+ export declare class PingRequest extends Message<PingRequest> {
72
+ constructor(data?: PartialMessage<PingRequest>);
73
+ static readonly runtime: typeof proto3;
74
+ static readonly typeName = "bsync.PingRequest";
75
+ static readonly fields: FieldList;
76
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PingRequest;
77
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PingRequest;
78
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PingRequest;
79
+ static equals(a: PingRequest | PlainMessage<PingRequest> | undefined, b: PingRequest | PlainMessage<PingRequest> | undefined): boolean;
80
+ }
81
+ export declare class PingResponse extends Message<PingResponse> {
82
+ constructor(data?: PartialMessage<PingResponse>);
83
+ static readonly runtime: typeof proto3;
84
+ static readonly typeName = "bsync.PingResponse";
85
+ static readonly fields: FieldList;
86
+ static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PingResponse;
87
+ static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): PingResponse;
88
+ static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): PingResponse;
89
+ static equals(a: PingResponse | PlainMessage<PingResponse> | undefined, b: PingResponse | PlainMessage<PingResponse> | undefined): boolean;
90
+ }
@@ -0,0 +1,25 @@
1
+ import { PingRequest, PingResponse, PushNotificationsRequest, PushNotificationsResponse, RegisterDeviceTokenRequest, RegisterDeviceTokenResponse } from './courier_pb.ts';
2
+ import { MethodKind } from '@bufbuild/protobuf';
3
+ export declare const Service: {
4
+ readonly typeName: "courier.Service";
5
+ readonly methods: {
6
+ readonly ping: {
7
+ readonly name: "Ping";
8
+ readonly I: typeof PingRequest;
9
+ readonly O: typeof PingResponse;
10
+ readonly kind: MethodKind.Unary;
11
+ };
12
+ readonly pushNotifications: {
13
+ readonly name: "PushNotifications";
14
+ readonly I: typeof PushNotificationsRequest;
15
+ readonly O: typeof PushNotificationsResponse;
16
+ readonly kind: MethodKind.Unary;
17
+ };
18
+ readonly registerDeviceToken: {
19
+ readonly name: "RegisterDeviceToken";
20
+ readonly I: typeof RegisterDeviceTokenRequest;
21
+ readonly O: typeof RegisterDeviceTokenResponse;
22
+ readonly kind: MethodKind.Unary;
23
+ };
24
+ };
25
+ };