@atproto/pds 0.4.76 → 0.4.78

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 (42) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/api/com/atproto/server/activateAccount.d.ts.map +1 -1
  3. package/dist/api/com/atproto/server/activateAccount.js +3 -8
  4. package/dist/api/com/atproto/server/activateAccount.js.map +1 -1
  5. package/dist/api/com/atproto/server/deactivateAccount.d.ts.map +1 -1
  6. package/dist/api/com/atproto/server/deactivateAccount.js +3 -8
  7. package/dist/api/com/atproto/server/deactivateAccount.js.map +1 -1
  8. package/dist/lexicon/index.d.ts +4 -2
  9. package/dist/lexicon/index.d.ts.map +1 -1
  10. package/dist/lexicon/index.js +4 -0
  11. package/dist/lexicon/index.js.map +1 -1
  12. package/dist/lexicon/lexicons.d.ts +138 -0
  13. package/dist/lexicon/lexicons.d.ts.map +1 -1
  14. package/dist/lexicon/lexicons.js +70 -0
  15. package/dist/lexicon/lexicons.js.map +1 -1
  16. package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +9 -0
  17. package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts.map +1 -1
  18. package/dist/lexicon/types/app/bsky/unspecced/defs.js +10 -0
  19. package/dist/lexicon/types/app/bsky/unspecced/defs.js.map +1 -1
  20. package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.d.ts +39 -0
  21. package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -0
  22. package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.js +3 -0
  23. package/dist/lexicon/types/app/bsky/unspecced/getTrendingTopics.js.map +1 -0
  24. package/package.json +5 -5
  25. package/src/api/com/atproto/server/activateAccount.ts +3 -11
  26. package/src/api/com/atproto/server/deactivateAccount.ts +3 -10
  27. package/src/lexicon/index.ts +14 -2
  28. package/src/lexicon/lexicons.ts +72 -0
  29. package/src/lexicon/types/app/bsky/unspecced/defs.ts +20 -0
  30. package/src/lexicon/types/app/bsky/unspecced/getTrendingTopics.ts +49 -0
  31. package/tests/account-deactivation.test.ts +1 -1
  32. package/tests/account-migration.test.ts +3 -3
  33. package/tests/blob-deletes.test.ts +8 -8
  34. package/tests/crud.test.ts +4 -12
  35. package/tests/file-uploads.test.ts +5 -11
  36. package/tests/moderation.test.ts +1 -1
  37. package/tests/proxied/__snapshots__/admin.test.ts.snap +32 -7
  38. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +4 -4
  39. package/tests/proxied/__snapshots__/views.test.ts.snap +32 -32
  40. package/tests/proxied/read-after-write.test.ts +2 -2
  41. package/tests/seeds/basic.ts +3 -3
  42. package/tsconfig.build.tsbuildinfo +1 -1
@@ -20,4 +20,13 @@ export interface SkeletonSearchStarterPack {
20
20
  }
21
21
  export declare function isSkeletonSearchStarterPack(v: unknown): v is SkeletonSearchStarterPack;
22
22
  export declare function validateSkeletonSearchStarterPack(v: unknown): ValidationResult;
23
+ export interface TrendingTopic {
24
+ topic: string;
25
+ displayName?: string;
26
+ description?: string;
27
+ link: string;
28
+ [k: string]: unknown;
29
+ }
30
+ export declare function isTrendingTopic(v: unknown): v is TrendingTopic;
31
+ export declare function validateTrendingTopic(v: unknown): ValidationResult;
23
32
  //# sourceMappingURL=defs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAK5D,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAMxE;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAEvE;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,mBAAmB,CAM1E;AAED,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAExE;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,2BAA2B,CACzC,CAAC,EAAE,OAAO,GACT,CAAC,IAAI,yBAAyB,CAMhC;AAED,wBAAgB,iCAAiC,CAC/C,CAAC,EAAE,OAAO,GACT,gBAAgB,CAKlB"}
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAW,MAAM,kBAAkB,CAAA;AAK5D,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAMxE;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAEvE;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,mBAAmB,CAM1E;AAED,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAExE;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,2BAA2B,CACzC,CAAC,EAAE,OAAO,GACT,CAAC,IAAI,yBAAyB,CAMhC;AAED,wBAAgB,iCAAiC,CAC/C,CAAC,EAAE,OAAO,GACT,gBAAgB,CAKlB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,aAAa,CAM9D;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAElE"}
@@ -6,6 +6,8 @@ exports.isSkeletonSearchActor = isSkeletonSearchActor;
6
6
  exports.validateSkeletonSearchActor = validateSkeletonSearchActor;
7
7
  exports.isSkeletonSearchStarterPack = isSkeletonSearchStarterPack;
8
8
  exports.validateSkeletonSearchStarterPack = validateSkeletonSearchStarterPack;
9
+ exports.isTrendingTopic = isTrendingTopic;
10
+ exports.validateTrendingTopic = validateTrendingTopic;
9
11
  const lexicons_1 = require("../../../../lexicons");
10
12
  const util_1 = require("../../../../util");
11
13
  function isSkeletonSearchPost(v) {
@@ -32,4 +34,12 @@ function isSkeletonSearchStarterPack(v) {
32
34
  function validateSkeletonSearchStarterPack(v) {
33
35
  return lexicons_1.lexicons.validate('app.bsky.unspecced.defs#skeletonSearchStarterPack', v);
34
36
  }
37
+ function isTrendingTopic(v) {
38
+ return ((0, util_1.isObj)(v) &&
39
+ (0, util_1.hasProp)(v, '$type') &&
40
+ v.$type === 'app.bsky.unspecced.defs#trendingTopic');
41
+ }
42
+ function validateTrendingTopic(v) {
43
+ return lexicons_1.lexicons.validate('app.bsky.unspecced.defs#trendingTopic', v);
44
+ }
35
45
  //# sourceMappingURL=defs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defs.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/defs.ts"],"names":[],"mappings":";;AAaA,oDAMC;AAED,gEAEC;AAOD,sDAMC;AAED,kEAEC;AAOD,kEAQC;AAED,8EAOC;AA5DD,mDAA+C;AAC/C,2CAAiD;AAQjD,SAAgB,oBAAoB,CAAC,CAAU;IAC7C,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,4CAA4C,CACzD,CAAA;AACH,CAAC;AAED,SAAgB,0BAA0B,CAAC,CAAU;IACnD,OAAO,mBAAQ,CAAC,QAAQ,CAAC,4CAA4C,EAAE,CAAC,CAAC,CAAA;AAC3E,CAAC;AAOD,SAAgB,qBAAqB,CAAC,CAAU;IAC9C,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,6CAA6C,CAC1D,CAAA;AACH,CAAC;AAED,SAAgB,2BAA2B,CAAC,CAAU;IACpD,OAAO,mBAAQ,CAAC,QAAQ,CAAC,6CAA6C,EAAE,CAAC,CAAC,CAAA;AAC5E,CAAC;AAOD,SAAgB,2BAA2B,CACzC,CAAU;IAEV,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,mDAAmD,CAChE,CAAA;AACH,CAAC;AAED,SAAgB,iCAAiC,CAC/C,CAAU;IAEV,OAAO,mBAAQ,CAAC,QAAQ,CACtB,mDAAmD,EACnD,CAAC,CACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"defs.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/defs.ts"],"names":[],"mappings":";;AAaA,oDAMC;AAED,gEAEC;AAOD,sDAMC;AAED,kEAEC;AAOD,kEAQC;AAED,8EAOC;AAUD,0CAMC;AAED,sDAEC;AAhFD,mDAA+C;AAC/C,2CAAiD;AAQjD,SAAgB,oBAAoB,CAAC,CAAU;IAC7C,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,4CAA4C,CACzD,CAAA;AACH,CAAC;AAED,SAAgB,0BAA0B,CAAC,CAAU;IACnD,OAAO,mBAAQ,CAAC,QAAQ,CAAC,4CAA4C,EAAE,CAAC,CAAC,CAAA;AAC3E,CAAC;AAOD,SAAgB,qBAAqB,CAAC,CAAU;IAC9C,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,6CAA6C,CAC1D,CAAA;AACH,CAAC;AAED,SAAgB,2BAA2B,CAAC,CAAU;IACpD,OAAO,mBAAQ,CAAC,QAAQ,CAAC,6CAA6C,EAAE,CAAC,CAAC,CAAA;AAC5E,CAAC;AAOD,SAAgB,2BAA2B,CACzC,CAAU;IAEV,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,mDAAmD,CAChE,CAAA;AACH,CAAC;AAED,SAAgB,iCAAiC,CAC/C,CAAU;IAEV,OAAO,mBAAQ,CAAC,QAAQ,CACtB,mDAAmD,EACnD,CAAC,CACF,CAAA;AACH,CAAC;AAUD,SAAgB,eAAe,CAAC,CAAU;IACxC,OAAO,CACL,IAAA,YAAK,EAAC,CAAC,CAAC;QACR,IAAA,cAAO,EAAC,CAAC,EAAE,OAAO,CAAC;QACnB,CAAC,CAAC,KAAK,KAAK,uCAAuC,CACpD,CAAA;AACH,CAAC;AAED,SAAgB,qBAAqB,CAAC,CAAU;IAC9C,OAAO,mBAAQ,CAAC,QAAQ,CAAC,uCAAuC,EAAE,CAAC,CAAC,CAAA;AACtE,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express';
5
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
6
+ import * as AppBskyUnspeccedDefs from './defs';
7
+ export interface QueryParams {
8
+ /** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */
9
+ viewer?: string;
10
+ limit: number;
11
+ }
12
+ export type InputSchema = undefined;
13
+ export interface OutputSchema {
14
+ topics: AppBskyUnspeccedDefs.TrendingTopic[];
15
+ suggested: AppBskyUnspeccedDefs.TrendingTopic[];
16
+ [k: string]: unknown;
17
+ }
18
+ export type HandlerInput = undefined;
19
+ export interface HandlerSuccess {
20
+ encoding: 'application/json';
21
+ body: OutputSchema;
22
+ headers?: {
23
+ [key: string]: string;
24
+ };
25
+ }
26
+ export interface HandlerError {
27
+ status: number;
28
+ message?: string;
29
+ }
30
+ export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
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;
39
+ //# sourceMappingURL=getTrendingTopics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTrendingTopics.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getTrendingTopics.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,OAAO,MAAM,SAAS,CAAA;AAK7B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACtE,OAAO,KAAK,oBAAoB,MAAM,QAAQ,CAAA;AAE9C,MAAM,WAAW,WAAW;IAC1B,2IAA2I;IAC3I,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,oBAAoB,CAAC,aAAa,EAAE,CAAA;IAC5C,SAAS,EAAE,oBAAoB,CAAC,aAAa,EAAE,CAAA;IAC/C,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,cAAc,GAAG,kBAAkB,CAAA;AAC9E,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI;IAC1D,IAAI,EAAE,EAAE,CAAA;IACR,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,YAAY,CAAA;IACnB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAA;IACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAA;CACtB,CAAA;AACD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,WAAW,GAAG,KAAK,IAAI,CACpD,GAAG,EAAE,aAAa,CAAC,EAAE,CAAC,KACnB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=getTrendingTopics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTrendingTopics.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getTrendingTopics.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/pds",
3
- "version": "0.4.76",
3
+ "version": "0.4.78",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of atproto Personal Data Server (PDS)",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  "undici": "^6.19.8",
47
47
  "zod": "^3.23.8",
48
48
  "@atproto-labs/fetch-node": "0.1.4",
49
- "@atproto/api": "^0.13.20",
49
+ "@atproto/api": "^0.13.22",
50
50
  "@atproto/aws": "^0.2.10",
51
51
  "@atproto/common": "^0.4.5",
52
52
  "@atproto/crypto": "^0.4.2",
@@ -75,9 +75,9 @@
75
75
  "ts-node": "^10.8.2",
76
76
  "typescript": "^5.6.3",
77
77
  "ws": "^8.12.0",
78
- "@atproto/api": "^0.13.20",
79
- "@atproto/bsky": "^0.0.98",
80
- "@atproto/lex-cli": "^0.5.3",
78
+ "@atproto/api": "^0.13.22",
79
+ "@atproto/bsky": "^0.0.100",
80
+ "@atproto/lex-cli": "^0.5.4",
81
81
  "@atproto/oauth-client-browser-example": "0.0.0"
82
82
  },
83
83
  "scripts": {
@@ -1,29 +1,21 @@
1
- import assert from 'node:assert'
2
-
3
1
  import { CidSet } from '@atproto/repo'
4
2
  import { INVALID_HANDLE } from '@atproto/syntax'
5
3
  import { InvalidRequestError } from '@atproto/xrpc-server'
6
4
 
7
5
  import AppContext from '../../../../context'
8
6
  import { Server } from '../../../../lexicon'
9
- import { ids } from '../../../../lexicon/lexicons'
10
7
  import { assertValidDidDocumentForService } from './util'
8
+ import { authPassthru } from '../../../proxy'
11
9
 
12
10
  export default function (server: Server, ctx: AppContext) {
13
11
  server.com.atproto.server.activateAccount({
14
12
  auth: ctx.authVerifier.accessFull(),
15
- handler: async ({ auth }) => {
13
+ handler: async ({ req, auth }) => {
16
14
  // in the case of entryway, the full flow is activateAccount (PDS) -> activateAccount (Entryway) -> updateSubjectStatus(PDS)
17
15
  if (ctx.entrywayAgent) {
18
- assert(ctx.cfg.entryway)
19
-
20
16
  await ctx.entrywayAgent.com.atproto.server.activateAccount(
21
17
  undefined,
22
- await ctx.serviceAuthHeaders(
23
- auth.credentials.did,
24
- ctx.cfg.entryway.did,
25
- ids.ComAtprotoServerActivateAccount,
26
- ),
18
+ authPassthru(req),
27
19
  )
28
20
  return
29
21
  }
@@ -1,23 +1,16 @@
1
- import assert from 'node:assert'
2
-
3
1
  import AppContext from '../../../../context'
4
2
  import { Server } from '../../../../lexicon'
5
- import { ids } from '../../../../lexicon/lexicons'
3
+ import { authPassthru } from '../../../proxy'
6
4
 
7
5
  export default function (server: Server, ctx: AppContext) {
8
6
  server.com.atproto.server.deactivateAccount({
9
7
  auth: ctx.authVerifier.accessFull(),
10
- handler: async ({ auth, input }) => {
8
+ handler: async ({ req, auth, input }) => {
11
9
  // in the case of entryway, the full flow is deactivateAccount (PDS) -> deactivateAccount (Entryway) -> updateSubjectStatus(PDS)
12
10
  if (ctx.entrywayAgent) {
13
- assert(ctx.cfg.entryway)
14
11
  await ctx.entrywayAgent.com.atproto.server.deactivateAccount(
15
12
  input.body,
16
- await ctx.serviceAuthHeaders(
17
- auth.credentials.did,
18
- ctx.cfg.entryway.did,
19
- ids.ComAtprotoServerDeactivateAccount,
20
- ),
13
+ authPassthru(req),
21
14
  )
22
15
  return
23
16
  }
@@ -140,6 +140,7 @@ import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig
140
140
  import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators'
141
141
  import * as AppBskyUnspeccedGetSuggestionsSkeleton from './types/app/bsky/unspecced/getSuggestionsSkeleton'
142
142
  import * as AppBskyUnspeccedGetTaggedSuggestions from './types/app/bsky/unspecced/getTaggedSuggestions'
143
+ import * as AppBskyUnspeccedGetTrendingTopics from './types/app/bsky/unspecced/getTrendingTopics'
143
144
  import * as AppBskyUnspeccedSearchActorsSkeleton from './types/app/bsky/unspecced/searchActorsSkeleton'
144
145
  import * as AppBskyUnspeccedSearchPostsSkeleton from './types/app/bsky/unspecced/searchPostsSkeleton'
145
146
  import * as AppBskyUnspeccedSearchStarterPacksSkeleton from './types/app/bsky/unspecced/searchStarterPacksSkeleton'
@@ -1896,6 +1897,17 @@ export class AppBskyUnspeccedNS {
1896
1897
  return this._server.xrpc.method(nsid, cfg)
1897
1898
  }
1898
1899
 
1900
+ getTrendingTopics<AV extends AuthVerifier>(
1901
+ cfg: ConfigOf<
1902
+ AV,
1903
+ AppBskyUnspeccedGetTrendingTopics.Handler<ExtractAuth<AV>>,
1904
+ AppBskyUnspeccedGetTrendingTopics.HandlerReqCtx<ExtractAuth<AV>>
1905
+ >,
1906
+ ) {
1907
+ const nsid = 'app.bsky.unspecced.getTrendingTopics' // @ts-ignore
1908
+ return this._server.xrpc.method(nsid, cfg)
1909
+ }
1910
+
1899
1911
  searchActorsSkeleton<AV extends AuthVerifier>(
1900
1912
  cfg: ConfigOf<
1901
1913
  AV,
@@ -2626,13 +2638,13 @@ export class ToolsOzoneTeamNS {
2626
2638
 
2627
2639
  type SharedRateLimitOpts<T> = {
2628
2640
  name: string
2629
- calcKey?: (ctx: T) => string
2641
+ calcKey?: (ctx: T) => string | null
2630
2642
  calcPoints?: (ctx: T) => number
2631
2643
  }
2632
2644
  type RouteRateLimitOpts<T> = {
2633
2645
  durationMs: number
2634
2646
  points: number
2635
- calcKey?: (ctx: T) => string
2647
+ calcKey?: (ctx: T) => string | null
2636
2648
  calcPoints?: (ctx: T) => number
2637
2649
  }
2638
2650
  type HandlerOpts = { blobLimit?: number }
@@ -9257,6 +9257,24 @@ export const schemaDict = {
9257
9257
  },
9258
9258
  },
9259
9259
  },
9260
+ trendingTopic: {
9261
+ type: 'object',
9262
+ required: ['topic', 'link'],
9263
+ properties: {
9264
+ topic: {
9265
+ type: 'string',
9266
+ },
9267
+ displayName: {
9268
+ type: 'string',
9269
+ },
9270
+ description: {
9271
+ type: 'string',
9272
+ },
9273
+ link: {
9274
+ type: 'string',
9275
+ },
9276
+ },
9277
+ },
9260
9278
  },
9261
9279
  },
9262
9280
  AppBskyUnspeccedGetConfig: {
@@ -9437,6 +9455,56 @@ export const schemaDict = {
9437
9455
  },
9438
9456
  },
9439
9457
  },
9458
+ AppBskyUnspeccedGetTrendingTopics: {
9459
+ lexicon: 1,
9460
+ id: 'app.bsky.unspecced.getTrendingTopics',
9461
+ defs: {
9462
+ main: {
9463
+ type: 'query',
9464
+ description: 'Get a list of trending topics',
9465
+ parameters: {
9466
+ type: 'params',
9467
+ properties: {
9468
+ viewer: {
9469
+ type: 'string',
9470
+ format: 'did',
9471
+ description:
9472
+ 'DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.',
9473
+ },
9474
+ limit: {
9475
+ type: 'integer',
9476
+ minimum: 1,
9477
+ maximum: 25,
9478
+ default: 10,
9479
+ },
9480
+ },
9481
+ },
9482
+ output: {
9483
+ encoding: 'application/json',
9484
+ schema: {
9485
+ type: 'object',
9486
+ required: ['topics', 'suggested'],
9487
+ properties: {
9488
+ topics: {
9489
+ type: 'array',
9490
+ items: {
9491
+ type: 'ref',
9492
+ ref: 'lex:app.bsky.unspecced.defs#trendingTopic',
9493
+ },
9494
+ },
9495
+ suggested: {
9496
+ type: 'array',
9497
+ items: {
9498
+ type: 'ref',
9499
+ ref: 'lex:app.bsky.unspecced.defs#trendingTopic',
9500
+ },
9501
+ },
9502
+ },
9503
+ },
9504
+ },
9505
+ },
9506
+ },
9507
+ },
9440
9508
  AppBskyUnspeccedSearchActorsSkeleton: {
9441
9509
  lexicon: 1,
9442
9510
  id: 'app.bsky.unspecced.searchActorsSkeleton',
@@ -12430,6 +12498,9 @@ export const schemaDict = {
12430
12498
  type: 'array',
12431
12499
  items: {
12432
12500
  type: 'string',
12501
+ maxLength: 25,
12502
+ description:
12503
+ 'Items in this array are applied with OR filters. To apply AND filter, put all tags in the same string and separate using && characters',
12433
12504
  },
12434
12505
  },
12435
12506
  excludeTags: {
@@ -13686,6 +13757,7 @@ export const ids = {
13686
13757
  'app.bsky.unspecced.getSuggestionsSkeleton',
13687
13758
  AppBskyUnspeccedGetTaggedSuggestions:
13688
13759
  'app.bsky.unspecced.getTaggedSuggestions',
13760
+ AppBskyUnspeccedGetTrendingTopics: 'app.bsky.unspecced.getTrendingTopics',
13689
13761
  AppBskyUnspeccedSearchActorsSkeleton:
13690
13762
  'app.bsky.unspecced.searchActorsSkeleton',
13691
13763
  AppBskyUnspeccedSearchPostsSkeleton: 'app.bsky.unspecced.searchPostsSkeleton',
@@ -63,3 +63,23 @@ export function validateSkeletonSearchStarterPack(
63
63
  v,
64
64
  )
65
65
  }
66
+
67
+ export interface TrendingTopic {
68
+ topic: string
69
+ displayName?: string
70
+ description?: string
71
+ link: string
72
+ [k: string]: unknown
73
+ }
74
+
75
+ export function isTrendingTopic(v: unknown): v is TrendingTopic {
76
+ return (
77
+ isObj(v) &&
78
+ hasProp(v, '$type') &&
79
+ v.$type === 'app.bsky.unspecced.defs#trendingTopic'
80
+ )
81
+ }
82
+
83
+ export function validateTrendingTopic(v: unknown): ValidationResult {
84
+ return lexicons.validate('app.bsky.unspecced.defs#trendingTopic', v)
85
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { lexicons } from '../../../../lexicons'
7
+ import { isObj, hasProp } from '../../../../util'
8
+ import { CID } from 'multiformats/cid'
9
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10
+ import * as AppBskyUnspeccedDefs from './defs'
11
+
12
+ export interface QueryParams {
13
+ /** DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking. */
14
+ viewer?: string
15
+ limit: number
16
+ }
17
+
18
+ export type InputSchema = undefined
19
+
20
+ export interface OutputSchema {
21
+ topics: AppBskyUnspeccedDefs.TrendingTopic[]
22
+ suggested: AppBskyUnspeccedDefs.TrendingTopic[]
23
+ [k: string]: unknown
24
+ }
25
+
26
+ export type HandlerInput = undefined
27
+
28
+ export interface HandlerSuccess {
29
+ encoding: 'application/json'
30
+ body: OutputSchema
31
+ headers?: { [key: string]: string }
32
+ }
33
+
34
+ export interface HandlerError {
35
+ status: number
36
+ message?: string
37
+ }
38
+
39
+ export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
40
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
41
+ auth: HA
42
+ params: QueryParams
43
+ input: HandlerInput
44
+ req: express.Request
45
+ res: express.Response
46
+ }
47
+ export type Handler<HA extends HandlerAuth = never> = (
48
+ ctx: HandlerReqCtx<HA>,
49
+ ) => Promise<HandlerOutput> | HandlerOutput
@@ -28,7 +28,7 @@ describe('account deactivation', () => {
28
28
 
29
29
  aliceAvatar = await sc.uploadFile(
30
30
  alice,
31
- '../dev-env/src/seed/img/key-portrait-small.jpg',
31
+ '../dev-env/assets/key-portrait-small.jpg',
32
32
  'image/jpeg',
33
33
  )
34
34
  await sc.updateProfile(alice, {
@@ -44,17 +44,17 @@ describe('account migration', () => {
44
44
  }
45
45
  const img1 = await sc.uploadFile(
46
46
  alice,
47
- '../dev-env/src/seed/img/at.png',
47
+ '../dev-env/assets/at.png',
48
48
  'image/png',
49
49
  )
50
50
  const img2 = await sc.uploadFile(
51
51
  alice,
52
- '../dev-env/src/seed/img/key-alt.jpg',
52
+ '../dev-env/assets/key-alt.jpg',
53
53
  'image/jpeg',
54
54
  )
55
55
  const img3 = await sc.uploadFile(
56
56
  alice,
57
- '../dev-env/src/seed/img/key-landscape-small.jpg',
57
+ '../dev-env/assets/key-landscape-small.jpg',
58
58
  'image/jpeg',
59
59
  )
60
60
 
@@ -48,7 +48,7 @@ describe('blob deletes', () => {
48
48
  it('deletes blob when record is deleted', async () => {
49
49
  const img = await sc.uploadFile(
50
50
  alice,
51
- '../dev-env/src/seed/img/key-portrait-small.jpg',
51
+ '../dev-env/assets/key-portrait-small.jpg',
52
52
  'image/jpeg',
53
53
  )
54
54
  const post = await sc.post(alice, 'test', undefined, [img])
@@ -65,12 +65,12 @@ describe('blob deletes', () => {
65
65
  it('deletes blob when blob-ref in record is updated', async () => {
66
66
  const img = await sc.uploadFile(
67
67
  alice,
68
- '../dev-env/src/seed/img/key-portrait-small.jpg',
68
+ '../dev-env/assets/key-portrait-small.jpg',
69
69
  'image/jpeg',
70
70
  )
71
71
  const img2 = await sc.uploadFile(
72
72
  alice,
73
- '../dev-env/src/seed/img/key-landscape-small.jpg',
73
+ '../dev-env/assets/key-landscape-small.jpg',
74
74
  'image/jpeg',
75
75
  )
76
76
  await updateProfile(sc, alice, img.image, img.image)
@@ -94,12 +94,12 @@ describe('blob deletes', () => {
94
94
  it('does not delete blob when blob-ref in record is not updated', async () => {
95
95
  const img = await sc.uploadFile(
96
96
  alice,
97
- '../dev-env/src/seed/img/key-portrait-small.jpg',
97
+ '../dev-env/assets/key-portrait-small.jpg',
98
98
  'image/jpeg',
99
99
  )
100
100
  const img2 = await sc.uploadFile(
101
101
  alice,
102
- '../dev-env/src/seed/img/key-landscape-small.jpg',
102
+ '../dev-env/assets/key-landscape-small.jpg',
103
103
  'image/jpeg',
104
104
  )
105
105
  await updateProfile(sc, alice, img.image, img.image)
@@ -120,7 +120,7 @@ describe('blob deletes', () => {
120
120
  it('does not delete blob when blob is reused by another record in same commit', async () => {
121
121
  const img = await sc.uploadFile(
122
122
  alice,
123
- '../dev-env/src/seed/img/key-portrait-small.jpg',
123
+ '../dev-env/assets/key-portrait-small.jpg',
124
124
  'image/jpeg',
125
125
  )
126
126
  const post = await sc.post(alice, 'post', undefined, [img])
@@ -167,12 +167,12 @@ describe('blob deletes', () => {
167
167
  it('does delete blob from user blob store if another user is using it', async () => {
168
168
  const imgAlice = await sc.uploadFile(
169
169
  alice,
170
- '../dev-env/src/seed/img/key-landscape-small.jpg',
170
+ '../dev-env/assets/key-landscape-small.jpg',
171
171
  'image/jpeg',
172
172
  )
173
173
  const imgBob = await sc.uploadFile(
174
174
  bob,
175
- '../dev-env/src/seed/img/key-landscape-small.jpg',
175
+ '../dev-env/assets/key-landscape-small.jpg',
176
176
  'image/jpeg',
177
177
  )
178
178
  const postAlice = await sc.post(alice, 'post', undefined, [imgAlice])
@@ -156,9 +156,7 @@ describe('crud operations', () => {
156
156
  })
157
157
 
158
158
  it('attaches images to a post', async () => {
159
- const file = await fs.readFile(
160
- '../dev-env/src/seed/img/key-landscape-small.jpg',
161
- )
159
+ const file = await fs.readFile('../dev-env/assets/key-landscape-small.jpg')
162
160
  const uploadedRes = await aliceAgent.api.com.atproto.repo.uploadBlob(file, {
163
161
  encoding: 'image/jpeg',
164
162
  })
@@ -516,9 +514,7 @@ describe('crud operations', () => {
516
514
  // @TODO remove after migrating legacy blobs
517
515
  it('updates a legacy blob ref when updating profile', async () => {
518
516
  const { repo } = bobAgent.api.com.atproto
519
- const file = await fs.readFile(
520
- '../dev-env/src/seed/img/key-portrait-small.jpg',
521
- )
517
+ const file = await fs.readFile('../dev-env/assets/key-portrait-small.jpg')
522
518
  const uploadedRes = await repo.uploadBlob(file, {
523
519
  encoding: 'image/jpeg',
524
520
  })
@@ -812,9 +808,7 @@ describe('crud operations', () => {
812
808
  })
813
809
 
814
810
  it('correctly associates images with unknown record types', async () => {
815
- const file = await fs.readFile(
816
- '../dev-env/src/seed/img/key-portrait-small.jpg',
817
- )
811
+ const file = await fs.readFile('../dev-env/assets/key-portrait-small.jpg')
818
812
  const uploadedRes = await aliceAgent.api.com.atproto.repo.uploadBlob(
819
813
  file,
820
814
  {
@@ -867,9 +861,7 @@ describe('crud operations', () => {
867
861
  })
868
862
 
869
863
  it('enforces blob ref format even when unvalidated', async () => {
870
- const file = await fs.readFile(
871
- '../dev-env/src/seed/img/key-portrait-small.jpg',
872
- )
864
+ const file = await fs.readFile('../dev-env/assets/key-portrait-small.jpg')
873
865
  const uploadedRes = await aliceAgent.api.com.atproto.repo.uploadBlob(
874
866
  file,
875
867
  {
@@ -72,9 +72,7 @@ describe('file uploads', () => {
72
72
  })
73
73
 
74
74
  it('uploads files', async () => {
75
- smallFile = await fs.readFile(
76
- '../dev-env/src/seed/img/key-portrait-small.jpg',
77
- )
75
+ smallFile = await fs.readFile('../dev-env/assets/key-portrait-small.jpg')
78
76
  const res = await agent.api.com.atproto.repo.uploadBlob(smallFile, {
79
77
  headers: sc.getHeaders(alice),
80
78
  encoding: 'image/jpeg',
@@ -130,7 +128,7 @@ describe('file uploads', () => {
130
128
  let largeFile: Uint8Array
131
129
 
132
130
  it('does not allow referencing a file that is outside blob constraints', async () => {
133
- largeFile = await fs.readFile('../dev-env/src/seed/img/hd-key.jpg')
131
+ largeFile = await fs.readFile('../dev-env/assets/hd-key.jpg')
134
132
  const res = await agent.api.com.atproto.repo.uploadBlob(largeFile, {
135
133
  headers: sc.getHeaders(alice),
136
134
  encoding: 'image/jpeg',
@@ -159,9 +157,7 @@ describe('file uploads', () => {
159
157
  })
160
158
 
161
159
  it('permits duplicate uploads of the same file', async () => {
162
- const file = await fs.readFile(
163
- '../dev-env/src/seed/img/key-landscape-small.jpg',
164
- )
160
+ const file = await fs.readFile('../dev-env/assets/key-landscape-small.jpg')
165
161
  const { data: uploadA } = await agent.api.com.atproto.repo.uploadBlob(
166
162
  file,
167
163
  {
@@ -225,9 +221,7 @@ describe('file uploads', () => {
225
221
  })
226
222
 
227
223
  it('corrects a bad mimetype', async () => {
228
- const file = await fs.readFile(
229
- '../dev-env/src/seed/img/key-landscape-large.jpg',
230
- )
224
+ const file = await fs.readFile('../dev-env/assets/key-landscape-large.jpg')
231
225
  const res = await agent.api.com.atproto.repo.uploadBlob(file, {
232
226
  headers: sc.getHeaders(alice),
233
227
  encoding: 'video/mp4',
@@ -245,7 +239,7 @@ describe('file uploads', () => {
245
239
  })
246
240
 
247
241
  it('handles pngs', async () => {
248
- const file = await fs.readFile('../dev-env/src/seed/img/at.png')
242
+ const file = await fs.readFile('../dev-env/assets/at.png')
249
243
  const res = await agent.api.com.atproto.repo.uploadBlob(file, {
250
244
  headers: sc.getHeaders(alice),
251
245
  encoding: 'image/png',
@@ -177,7 +177,7 @@ describe('moderation', () => {
177
177
  it('prevents blob from being reuploaded', async () => {
178
178
  const attempt = sc.uploadFile(
179
179
  sc.dids.carol,
180
- '../dev-env/src/seed/img/key-alt.jpg',
180
+ '../dev-env/assets/key-alt.jpg',
181
181
  'image/jpeg',
182
182
  )
183
183
  await expect(attempt).rejects.toThrow(