@atproto/bsky 0.0.185 → 0.0.186

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 (36) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +4 -0
  3. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
  4. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +101 -0
  5. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/api/index.js +2 -0
  8. package/dist/api/index.js.map +1 -1
  9. package/dist/lexicon/index.d.ts +4 -0
  10. package/dist/lexicon/index.d.ts.map +1 -1
  11. package/dist/lexicon/index.js +8 -0
  12. package/dist/lexicon/index.js.map +1 -1
  13. package/dist/lexicon/lexicons.d.ts +158 -0
  14. package/dist/lexicon/lexicons.d.ts.map +1 -1
  15. package/dist/lexicon/lexicons.js +81 -0
  16. package/dist/lexicon/lexicons.js.map +1 -1
  17. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +22 -0
  18. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
  19. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +7 -0
  20. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
  21. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts +23 -0
  22. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts.map +1 -0
  23. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js +7 -0
  24. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js.map +1 -0
  25. package/dist/util.d.ts.map +1 -1
  26. package/dist/util.js +3 -1
  27. package/dist/util.js.map +1 -1
  28. package/package.json +6 -6
  29. package/src/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +152 -0
  30. package/src/api/index.ts +2 -0
  31. package/src/lexicon/index.ts +26 -0
  32. package/src/lexicon/lexicons.ts +85 -0
  33. package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +40 -0
  34. package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts +41 -0
  35. package/src/util.ts +3 -1
  36. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,22 @@
1
+ import type * as AppBskyGraphDefs from '../graph/defs.js';
2
+ export type QueryParams = {
3
+ limit: number;
4
+ };
5
+ export type InputSchema = undefined;
6
+ export interface OutputSchema {
7
+ starterPacks: AppBskyGraphDefs.StarterPackView[];
8
+ }
9
+ export type HandlerInput = void;
10
+ export interface HandlerSuccess {
11
+ encoding: 'application/json';
12
+ body: OutputSchema;
13
+ headers?: {
14
+ [key: string]: string;
15
+ };
16
+ }
17
+ export interface HandlerError {
18
+ status: number;
19
+ message?: string;
20
+ }
21
+ export type HandlerOutput = HandlerError | HandlerSuccess;
22
+ //# sourceMappingURL=getOnboardingSuggestedStarterPacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOnboardingSuggestedStarterPacks.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,KAAK,gBAAgB,MAAM,kBAAkB,CAAA;AAMzD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,gBAAgB,CAAC,eAAe,EAAE,CAAA;CACjD;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,CAAA;AAE/B,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,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lexicons_1 = require("../../../../lexicons");
4
+ const util_1 = require("../../../../util");
5
+ const is$typed = util_1.is$typed, validate = lexicons_1.validate;
6
+ const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks';
7
+ //# sourceMappingURL=getOnboardingSuggestedStarterPacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOnboardingSuggestedStarterPacks.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts"],"names":[],"mappings":";;AAKA,mDAA4D;AAC5D,2CAIyB;AAGzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,uDAAuD,CAAA"}
@@ -0,0 +1,23 @@
1
+ export type QueryParams = {
2
+ /** DID of the account making the request (not included for public/unauthenticated queries). */
3
+ viewer?: string;
4
+ limit: number;
5
+ };
6
+ export type InputSchema = undefined;
7
+ export interface OutputSchema {
8
+ starterPacks: string[];
9
+ }
10
+ export type HandlerInput = void;
11
+ export interface HandlerSuccess {
12
+ encoding: 'application/json';
13
+ body: OutputSchema;
14
+ headers?: {
15
+ [key: string]: string;
16
+ };
17
+ }
18
+ export interface HandlerError {
19
+ status: number;
20
+ message?: string;
21
+ }
22
+ export type HandlerOutput = HandlerError | HandlerSuccess;
23
+ //# sourceMappingURL=getOnboardingSuggestedStarterPacksSkeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOnboardingSuggestedStarterPacksSkeleton.d.ts","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,WAAW,GAAG;IACxB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,CAAA;AAE/B,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,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lexicons_1 = require("../../../../lexicons");
4
+ const util_1 = require("../../../../util");
5
+ const is$typed = util_1.is$typed, validate = lexicons_1.validate;
6
+ const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton';
7
+ //# sourceMappingURL=getOnboardingSuggestedStarterPacksSkeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOnboardingSuggestedStarterPacksSkeleton.js","sourceRoot":"","sources":["../../../../../../src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts"],"names":[],"mappings":";;AAKA,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,+DAA+D,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,GAAG,SAAS,KACzB,cAAc,GAAG,IAoBnB,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,cAKrD,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,QAAQ,cAAc,KAAG,MAK5D,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,GAAG,SAAS,KACzB,cAAc,GAAG,IAsBnB,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,cAKrD,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,QAAQ,cAAc,KAAG,MAK5D,CAAA"}
package/dist/util.js CHANGED
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatLabelerHeader = exports.defaultLabelerHeader = exports.parseLabelerHeader = void 0;
4
4
  const structured_headers_1 = require("structured-headers");
5
5
  const parseLabelerHeader = (header) => {
6
- if (!header)
6
+ // An empty header is valid, so we shouldn't return null
7
+ // https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
8
+ if (header === undefined)
7
9
  return null;
8
10
  const labelerDids = new Set();
9
11
  const redactDids = new Set();
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;AAAA,2DAA8C;AAOvC,MAAM,kBAAkB,GAAG,CAChC,MAA0B,EACH,EAAE;IACzB,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IACpC,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,MAAM,CAAC,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAA;QACb,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;QAC/C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC;QACtB,MAAM,EAAE,UAAU;KACnB,CAAA;AACH,CAAC,CAAA;AAtBY,QAAA,kBAAkB,sBAsB9B;AAEM,MAAM,oBAAoB,GAAG,CAAC,IAAc,EAAkB,EAAE;IACrE,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC;KACtB,CAAA;AACH,CAAC,CAAA;AALY,QAAA,oBAAoB,wBAKhC;AAEM,MAAM,mBAAmB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAC/C,CAAA;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC,CAAA;AALY,QAAA,mBAAmB,uBAK/B"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;AAAA,2DAA8C;AAOvC,MAAM,kBAAkB,GAAG,CAChC,MAA0B,EACH,EAAE;IACzB,wDAAwD;IACxD,4DAA4D;IAC5D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACrC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IACpC,MAAM,MAAM,GAAG,IAAA,8BAAS,EAAC,MAAM,CAAC,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAA;QACb,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;QAC/C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC;QACtB,MAAM,EAAE,UAAU;KACnB,CAAA;AACH,CAAC,CAAA;AAxBY,QAAA,kBAAkB,sBAwB9B;AAEM,MAAM,oBAAoB,GAAG,CAAC,IAAc,EAAkB,EAAE;IACrE,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC;KACtB,CAAA;AACH,CAAC,CAAA;AALY,QAAA,oBAAoB,wBAKhC;AAEM,MAAM,mBAAmB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAC/C,CAAA;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC,CAAA;AALY,QAAA,mBAAmB,uBAK/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/bsky",
3
- "version": "0.0.185",
3
+ "version": "0.0.186",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of app.bsky App View (Bluesky API)",
6
6
  "keywords": [
@@ -53,14 +53,14 @@
53
53
  "zod": "3.23.8",
54
54
  "@atproto-labs/fetch-node": "0.1.10",
55
55
  "@atproto-labs/xrpc-utils": "0.0.22",
56
- "@atproto/api": "^0.16.10",
56
+ "@atproto/api": "^0.16.11",
57
57
  "@atproto/common": "^0.4.12",
58
58
  "@atproto/crypto": "^0.4.4",
59
59
  "@atproto/did": "^0.2.0",
60
60
  "@atproto/identity": "^0.4.9",
61
61
  "@atproto/lexicon": "^0.5.1",
62
- "@atproto/repo": "^0.8.9",
63
- "@atproto/sync": "^0.1.34",
62
+ "@atproto/repo": "^0.8.10",
63
+ "@atproto/sync": "^0.1.35",
64
64
  "@atproto/syntax": "^0.4.1",
65
65
  "@atproto/xrpc-server": "^0.9.5"
66
66
  },
@@ -77,9 +77,9 @@
77
77
  "jest": "^28.1.2",
78
78
  "ts-node": "^10.8.2",
79
79
  "typescript": "^5.6.3",
80
- "@atproto/api": "^0.16.10",
80
+ "@atproto/api": "^0.16.11",
81
81
  "@atproto/lex-cli": "^0.9.5",
82
- "@atproto/pds": "^0.4.181",
82
+ "@atproto/pds": "^0.4.182",
83
83
  "@atproto/xrpc": "^0.7.5"
84
84
  },
85
85
  "scripts": {
@@ -0,0 +1,152 @@
1
+ import AtpAgent, { AtUri } from '@atproto/api'
2
+ import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'
3
+ import { InternalServerError } from '@atproto/xrpc-server'
4
+ import { AppContext } from '../../../../context'
5
+ import {
6
+ HydrateCtx,
7
+ Hydrator,
8
+ mergeManyStates,
9
+ } from '../../../../hydration/hydrator'
10
+ import { Server } from '../../../../lexicon'
11
+ import { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/getTrendingTopics'
12
+ import {
13
+ HydrationFnInput,
14
+ PresentationFnInput,
15
+ RulesFnInput,
16
+ SkeletonFnInput,
17
+ createPipeline,
18
+ } from '../../../../pipeline'
19
+ import { Views } from '../../../../views'
20
+
21
+ export default function (server: Server, ctx: AppContext) {
22
+ const getOnboardingSuggestedStarterPacks = createPipeline(
23
+ skeleton,
24
+ hydration,
25
+ noBlocks,
26
+ presentation,
27
+ )
28
+ server.app.bsky.unspecced.getOnboardingSuggestedStarterPacks({
29
+ auth: ctx.authVerifier.standardOptional,
30
+ handler: async ({ auth, params, req }) => {
31
+ const viewer = auth.credentials.iss
32
+ const labelers = ctx.reqLabelers(req)
33
+ const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })
34
+ const headers = noUndefinedVals({
35
+ 'accept-language': req.headers['accept-language'],
36
+ 'x-bsky-topics': Array.isArray(req.headers['x-bsky-topics'])
37
+ ? req.headers['x-bsky-topics'].join(',')
38
+ : req.headers['x-bsky-topics'],
39
+ })
40
+ const { ...result } = await getOnboardingSuggestedStarterPacks(
41
+ {
42
+ ...params,
43
+ viewer: viewer ?? undefined,
44
+ hydrateCtx: hydrateCtx.copy({ viewer }),
45
+ headers,
46
+ },
47
+ ctx,
48
+ )
49
+ return {
50
+ encoding: 'application/json',
51
+ body: result,
52
+ }
53
+ },
54
+ })
55
+ }
56
+
57
+ const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
58
+ const { params, ctx } = input
59
+ if (ctx.topicsAgent) {
60
+ const res =
61
+ await ctx.topicsAgent.app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton(
62
+ {
63
+ limit: params.limit,
64
+ viewer: params.viewer,
65
+ },
66
+ {
67
+ headers: params.headers,
68
+ },
69
+ )
70
+
71
+ return res.data
72
+ } else {
73
+ throw new InternalServerError('Topics agent not available')
74
+ }
75
+ }
76
+
77
+ const hydration = async (
78
+ input: HydrationFnInput<Context, Params, SkeletonState>,
79
+ ) => {
80
+ const { ctx, params, skeleton } = input
81
+ let dids: string[] = []
82
+ for (const uri of skeleton.starterPacks) {
83
+ let aturi: AtUri | undefined
84
+ try {
85
+ aturi = new AtUri(uri)
86
+ } catch {
87
+ continue
88
+ }
89
+ dids.push(aturi.hostname)
90
+ }
91
+ dids = dedupeStrs(dids)
92
+ const pairs: Map<string, string[]> = new Map()
93
+ if (params.viewer) {
94
+ pairs.set(params.viewer, dids)
95
+ }
96
+ const [starterPacksState, bidirectionalBlocks] = await Promise.all([
97
+ ctx.hydrator.hydrateStarterPacks(skeleton.starterPacks, params.hydrateCtx),
98
+ ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),
99
+ ])
100
+
101
+ return mergeManyStates(starterPacksState, { bidirectionalBlocks })
102
+ }
103
+
104
+ const noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {
105
+ const { skeleton, params, hydration } = input
106
+
107
+ if (!params.viewer) {
108
+ return skeleton
109
+ }
110
+
111
+ const blocks = hydration.bidirectionalBlocks?.get(params.viewer)
112
+ const filteredSkeleton: SkeletonState = {
113
+ starterPacks: skeleton.starterPacks.filter((uri) => {
114
+ let aturi: AtUri | undefined
115
+ try {
116
+ aturi = new AtUri(uri)
117
+ } catch {
118
+ return false
119
+ }
120
+ return !blocks?.get(aturi.hostname)
121
+ }),
122
+ }
123
+
124
+ return filteredSkeleton
125
+ }
126
+
127
+ const presentation = (
128
+ input: PresentationFnInput<Context, Params, SkeletonState>,
129
+ ) => {
130
+ const { ctx, skeleton, hydration } = input
131
+
132
+ return {
133
+ starterPacks: mapDefined(skeleton.starterPacks, (uri) =>
134
+ ctx.views.starterPack(uri, hydration),
135
+ ),
136
+ }
137
+ }
138
+
139
+ type Context = {
140
+ hydrator: Hydrator
141
+ views: Views
142
+ topicsAgent: AtpAgent | undefined
143
+ }
144
+
145
+ type Params = QueryParams & {
146
+ hydrateCtx: HydrateCtx & { viewer: string | null }
147
+ headers: Record<string, string>
148
+ }
149
+
150
+ type SkeletonState = {
151
+ starterPacks: string[]
152
+ }
package/src/api/index.ts CHANGED
@@ -58,6 +58,7 @@ import registerPush from './app/bsky/notification/registerPush'
58
58
  import updateSeen from './app/bsky/notification/updateSeen'
59
59
  import getAgeAssuranceState from './app/bsky/unspecced/getAgeAssuranceState'
60
60
  import getConfig from './app/bsky/unspecced/getConfig'
61
+ import getOnboardingSuggestedStarterPacks from './app/bsky/unspecced/getOnboardingSuggestedStarterPacks'
61
62
  import getPopularFeedGenerators from './app/bsky/unspecced/getPopularFeedGenerators'
62
63
  import getPostThreadOtherV2 from './app/bsky/unspecced/getPostThreadOtherV2'
63
64
  import getPostThreadV2 from './app/bsky/unspecced/getPostThreadV2'
@@ -133,6 +134,7 @@ export default function (server: Server, ctx: AppContext) {
133
134
  getSuggestedFollowsByActor(server, ctx)
134
135
  getTrendingTopics(server, ctx)
135
136
  getTrends(server, ctx)
137
+ getOnboardingSuggestedStarterPacks(server, ctx)
136
138
  getSuggestedStarterPacks(server, ctx)
137
139
  getSuggestedUsers(server, ctx)
138
140
  getUnspeccedSuggestedFeeds(server, ctx)
@@ -74,6 +74,8 @@ import * as AppBskyNotificationUnregisterPush from './types/app/bsky/notificatio
74
74
  import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
75
75
  import * as AppBskyUnspeccedGetAgeAssuranceState from './types/app/bsky/unspecced/getAgeAssuranceState.js'
76
76
  import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
77
+ import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js'
78
+ import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js'
77
79
  import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators.js'
78
80
  import * as AppBskyUnspeccedGetPostThreadOtherV2 from './types/app/bsky/unspecced/getPostThreadOtherV2.js'
79
81
  import * as AppBskyUnspeccedGetPostThreadV2 from './types/app/bsky/unspecced/getPostThreadV2.js'
@@ -1132,6 +1134,30 @@ export class AppBskyUnspeccedNS {
1132
1134
  return this._server.xrpc.method(nsid, cfg)
1133
1135
  }
1134
1136
 
1137
+ getOnboardingSuggestedStarterPacks<A extends Auth = void>(
1138
+ cfg: MethodConfigOrHandler<
1139
+ A,
1140
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.QueryParams,
1141
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.HandlerInput,
1142
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.HandlerOutput
1143
+ >,
1144
+ ) {
1145
+ const nsid = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks' // @ts-ignore
1146
+ return this._server.xrpc.method(nsid, cfg)
1147
+ }
1148
+
1149
+ getOnboardingSuggestedStarterPacksSkeleton<A extends Auth = void>(
1150
+ cfg: MethodConfigOrHandler<
1151
+ A,
1152
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.QueryParams,
1153
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.HandlerInput,
1154
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.HandlerOutput
1155
+ >,
1156
+ ) {
1157
+ const nsid = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton' // @ts-ignore
1158
+ return this._server.xrpc.method(nsid, cfg)
1159
+ }
1160
+
1135
1161
  getPopularFeedGenerators<A extends Auth = void>(
1136
1162
  cfg: MethodConfigOrHandler<
1137
1163
  A,
@@ -6628,6 +6628,87 @@ export const schemaDict = {
6628
6628
  },
6629
6629
  },
6630
6630
  },
6631
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks: {
6632
+ lexicon: 1,
6633
+ id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
6634
+ defs: {
6635
+ main: {
6636
+ type: 'query',
6637
+ description: 'Get a list of suggested starterpacks for onboarding',
6638
+ parameters: {
6639
+ type: 'params',
6640
+ properties: {
6641
+ limit: {
6642
+ type: 'integer',
6643
+ minimum: 1,
6644
+ maximum: 25,
6645
+ default: 10,
6646
+ },
6647
+ },
6648
+ },
6649
+ output: {
6650
+ encoding: 'application/json',
6651
+ schema: {
6652
+ type: 'object',
6653
+ required: ['starterPacks'],
6654
+ properties: {
6655
+ starterPacks: {
6656
+ type: 'array',
6657
+ items: {
6658
+ type: 'ref',
6659
+ ref: 'lex:app.bsky.graph.defs#starterPackView',
6660
+ },
6661
+ },
6662
+ },
6663
+ },
6664
+ },
6665
+ },
6666
+ },
6667
+ },
6668
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton: {
6669
+ lexicon: 1,
6670
+ id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
6671
+ defs: {
6672
+ main: {
6673
+ type: 'query',
6674
+ description:
6675
+ 'Get a skeleton of suggested starterpacks for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
6676
+ parameters: {
6677
+ type: 'params',
6678
+ properties: {
6679
+ viewer: {
6680
+ type: 'string',
6681
+ format: 'did',
6682
+ description:
6683
+ 'DID of the account making the request (not included for public/unauthenticated queries).',
6684
+ },
6685
+ limit: {
6686
+ type: 'integer',
6687
+ minimum: 1,
6688
+ maximum: 25,
6689
+ default: 10,
6690
+ },
6691
+ },
6692
+ },
6693
+ output: {
6694
+ encoding: 'application/json',
6695
+ schema: {
6696
+ type: 'object',
6697
+ required: ['starterPacks'],
6698
+ properties: {
6699
+ starterPacks: {
6700
+ type: 'array',
6701
+ items: {
6702
+ type: 'string',
6703
+ format: 'at-uri',
6704
+ },
6705
+ },
6706
+ },
6707
+ },
6708
+ },
6709
+ },
6710
+ },
6711
+ },
6631
6712
  AppBskyUnspeccedGetPopularFeedGenerators: {
6632
6713
  lexicon: 1,
6633
6714
  id: 'app.bsky.unspecced.getPopularFeedGenerators',
@@ -13979,6 +14060,10 @@ export const ids = {
13979
14060
  AppBskyUnspeccedGetAgeAssuranceState:
13980
14061
  'app.bsky.unspecced.getAgeAssuranceState',
13981
14062
  AppBskyUnspeccedGetConfig: 'app.bsky.unspecced.getConfig',
14063
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks:
14064
+ 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
14065
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton:
14066
+ 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
13982
14067
  AppBskyUnspeccedGetPopularFeedGenerators:
13983
14068
  'app.bsky.unspecced.getPopularFeedGenerators',
13984
14069
  AppBskyUnspeccedGetPostThreadOtherV2:
@@ -0,0 +1,40 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+ import type * as AppBskyGraphDefs from '../graph/defs.js'
13
+
14
+ const is$typed = _is$typed,
15
+ validate = _validate
16
+ const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks'
17
+
18
+ export type QueryParams = {
19
+ limit: number
20
+ }
21
+ export type InputSchema = undefined
22
+
23
+ export interface OutputSchema {
24
+ starterPacks: AppBskyGraphDefs.StarterPackView[]
25
+ }
26
+
27
+ export type HandlerInput = void
28
+
29
+ export interface HandlerSuccess {
30
+ encoding: 'application/json'
31
+ body: OutputSchema
32
+ headers?: { [key: string]: string }
33
+ }
34
+
35
+ export interface HandlerError {
36
+ status: number
37
+ message?: string
38
+ }
39
+
40
+ export type HandlerOutput = HandlerError | HandlerSuccess
@@ -0,0 +1,41 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { type ValidationResult, BlobRef } from '@atproto/lexicon'
5
+ import { CID } from 'multiformats/cid'
6
+ import { validate as _validate } from '../../../../lexicons'
7
+ import {
8
+ type $Typed,
9
+ is$typed as _is$typed,
10
+ type OmitKey,
11
+ } from '../../../../util'
12
+
13
+ const is$typed = _is$typed,
14
+ validate = _validate
15
+ const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton'
16
+
17
+ export type QueryParams = {
18
+ /** DID of the account making the request (not included for public/unauthenticated queries). */
19
+ viewer?: string
20
+ limit: number
21
+ }
22
+ export type InputSchema = undefined
23
+
24
+ export interface OutputSchema {
25
+ starterPacks: string[]
26
+ }
27
+
28
+ export type HandlerInput = void
29
+
30
+ export interface HandlerSuccess {
31
+ encoding: 'application/json'
32
+ body: OutputSchema
33
+ headers?: { [key: string]: string }
34
+ }
35
+
36
+ export interface HandlerError {
37
+ status: number
38
+ message?: string
39
+ }
40
+
41
+ export type HandlerOutput = HandlerError | HandlerSuccess
package/src/util.ts CHANGED
@@ -8,7 +8,9 @@ export type ParsedLabelers = {
8
8
  export const parseLabelerHeader = (
9
9
  header: string | undefined,
10
10
  ): ParsedLabelers | null => {
11
- if (!header) return null
11
+ // An empty header is valid, so we shouldn't return null
12
+ // https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
13
+ if (header === undefined) return null
12
14
  const labelerDids = new Set<string>()
13
15
  const redactDids = new Set<string>()
14
16
  const parsed = parseList(header)