@atproto/bsky 0.1.0 → 0.1.3

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 (101) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getSuggestions.js +9 -3
  4. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  5. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  6. package/dist/api/app/bsky/feed/getFeed.js +44 -15
  7. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  8. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
  9. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +7 -3
  10. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  11. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
  12. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +13 -4
  13. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
  14. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
  15. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +12 -4
  16. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
  17. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
  18. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +10 -3
  19. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
  20. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
  21. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +13 -4
  22. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
  23. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +18 -0
  24. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
  25. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +17 -0
  26. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
  27. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +18 -0
  28. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
  29. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +18 -0
  30. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
  31. package/dist/config.d.ts +8 -0
  32. package/dist/config.d.ts.map +1 -1
  33. package/dist/config.js +22 -0
  34. package/dist/config.js.map +1 -1
  35. package/dist/data-plane/server/routes/atmosphere.d.ts +5 -0
  36. package/dist/data-plane/server/routes/atmosphere.d.ts.map +1 -0
  37. package/dist/data-plane/server/routes/atmosphere.js +24 -0
  38. package/dist/data-plane/server/routes/atmosphere.js.map +1 -0
  39. package/dist/data-plane/server/routes/index.js +2 -2
  40. package/dist/data-plane/server/routes/index.js.map +1 -1
  41. package/dist/feature-gates/gates.d.ts +10 -0
  42. package/dist/feature-gates/gates.d.ts.map +1 -1
  43. package/dist/feature-gates/gates.js +10 -0
  44. package/dist/feature-gates/gates.js.map +1 -1
  45. package/dist/feature-gates/index.js +2 -2
  46. package/dist/feature-gates/index.js.map +1 -1
  47. package/dist/hydration/external.d.ts +65 -2
  48. package/dist/hydration/external.d.ts.map +1 -1
  49. package/dist/hydration/external.js +220 -29
  50. package/dist/hydration/external.js.map +1 -1
  51. package/dist/hydration/hydrator.d.ts.map +1 -1
  52. package/dist/hydration/hydrator.js +7 -7
  53. package/dist/hydration/hydrator.js.map +1 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +3 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts +2 -0
  58. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.d.ts.map +1 -1
  59. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js +1 -0
  60. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.defs.js.map +1 -1
  61. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
  62. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
  63. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js +1 -0
  64. package/dist/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.defs.js.map +1 -1
  65. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts +2 -0
  66. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.d.ts.map +1 -1
  67. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js +1 -0
  68. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeeds.defs.js.map +1 -1
  69. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts +2 -0
  70. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.d.ts.map +1 -1
  71. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js +1 -0
  72. package/dist/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.defs.js.map +1 -1
  73. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts +2 -0
  74. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.d.ts.map +1 -1
  75. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js +1 -0
  76. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.defs.js.map +1 -1
  77. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts +2 -0
  78. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.d.ts.map +1 -1
  79. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js +1 -0
  80. package/dist/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.defs.js.map +1 -1
  81. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts +17 -1
  82. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts.map +1 -1
  83. package/dist/lexicons/tools/ozone/report/defs.defs.js +10 -0
  84. package/dist/lexicons/tools/ozone/report/defs.defs.js.map +1 -1
  85. package/dist/proto/bsky_connect.d.ts +57 -21
  86. package/dist/proto/bsky_connect.d.ts.map +1 -1
  87. package/dist/proto/bsky_connect.js +57 -21
  88. package/dist/proto/bsky_connect.js.map +1 -1
  89. package/dist/proto/bsky_pb.d.ts +361 -72
  90. package/dist/proto/bsky_pb.d.ts.map +1 -1
  91. package/dist/proto/bsky_pb.js +529 -70
  92. package/dist/proto/bsky_pb.js.map +1 -1
  93. package/dist/util/standard-site.d.ts +0 -12
  94. package/dist/util/standard-site.d.ts.map +1 -1
  95. package/dist/util/standard-site.js +0 -14
  96. package/dist/util/standard-site.js.map +1 -1
  97. package/package.json +8 -8
  98. package/dist/data-plane/server/routes/site-standard.d.ts +0 -6
  99. package/dist/data-plane/server/routes/site-standard.d.ts.map +0 -1
  100. package/dist/data-plane/server/routes/site-standard.js +0 -9
  101. package/dist/data-plane/server/routes/site-standard.js.map +0 -1
package/dist/config.js CHANGED
@@ -56,8 +56,14 @@ export class ServerConfig {
56
56
  const irisUrl = process.env.BSKY_IRIS_URL || undefined;
57
57
  const irisServiceDid = process.env.BSKY_IRIS_SERVICE_DID || undefined;
58
58
  assert(irisServiceDid == null || isDidString(irisServiceDid));
59
+ const seemoreServiceDid = process.env.BSKY_SEEMORE_SERVICE_DID || undefined;
60
+ assert(seemoreServiceDid == null || isDidString(seemoreServiceDid));
61
+ const irisStagingServiceDid = process.env.BSKY_IRIS_STAGING_SERVICE_DID || undefined;
62
+ assert(irisStagingServiceDid == null || isDidString(irisStagingServiceDid));
59
63
  const trendingFeedDid = process.env.BSKY_TRENDING_FEED_DID || undefined;
60
64
  assert(trendingFeedDid == null || isDidString(trendingFeedDid));
65
+ const bskyFeedgenDids = new Set(envList(process.env.BSKY_FEEDGEN_DIDS).filter(isDidString));
66
+ const irisApiKey = process.env.BSKY_IRIS_API_KEY || undefined;
61
67
  const irisFeedUris = new Set(envList(process.env.BSKY_IRIS_FEED_URIS));
62
68
  const irisStagingUrl = process.env.BSKY_IRIS_STAGING_URL || undefined;
63
69
  const irisStagingFeedUris = new Set(envList(process.env.BSKY_IRIS_STAGING_FEED_URIS));
@@ -209,7 +215,11 @@ export class ServerConfig {
209
215
  topicsApiKey,
210
216
  irisUrl,
211
217
  irisServiceDid,
218
+ seemoreServiceDid,
219
+ irisStagingServiceDid,
212
220
  trendingFeedDid,
221
+ bskyFeedgenDids,
222
+ irisApiKey,
213
223
  irisFeedUris,
214
224
  irisStagingUrl,
215
225
  irisStagingFeedUris,
@@ -374,9 +384,21 @@ export class ServerConfig {
374
384
  get irisServiceDid() {
375
385
  return this.cfg.irisServiceDid;
376
386
  }
387
+ get seemoreServiceDid() {
388
+ return this.cfg.seemoreServiceDid;
389
+ }
390
+ get irisStagingServiceDid() {
391
+ return this.cfg.irisStagingServiceDid;
392
+ }
377
393
  get trendingFeedDid() {
378
394
  return this.cfg.trendingFeedDid;
379
395
  }
396
+ get bskyFeedgenDids() {
397
+ return this.cfg.bskyFeedgenDids;
398
+ }
399
+ get irisApiKey() {
400
+ return this.cfg.irisApiKey;
401
+ }
380
402
  get irisFeedUris() {
381
403
  return this.cfg.irisFeedUris;
382
404
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { SECOND, noUndefinedVals } from '@atproto/common'\nimport { type DidString, isDidString } from '@atproto/lex'\nimport { subLogger as log } from './logger.js'\n\ntype LiveNowConfig = {\n did: DidString\n domains: string[]\n}[]\n\nexport type NotificationsV2Algorithm = 'algoGravity' | 'algoLookback'\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: DidString\n alternateAudienceDids: DidString[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n searchTagsHideAll: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n irisUrl?: string\n irisServiceDid?: DidString\n trendingFeedDid?: DidString\n irisFeedUris?: Set<string> // `iris:feed:enable` gate to serve via iris instead of seeemore\n irisStagingUrl?: string\n irisStagingFeedUris?: Set<string> // serve via iris staging instead of the registered feed generator\n feedGenSkeletonTimeout: number\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: DidString\n adminPasswords: string[]\n labelsFromIssuerDids?: DidString[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n eventProxyTrackingEndpoint?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n notificationsV2Algorithm?: NotificationsV2Algorithm\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyConnectTimeout?: number\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n searchV2OverrideHeader?: string\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n assert(isDidString(serverDid))\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n assert(alternateAudienceDids.every(isDidString))\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n // Values 0 through 16\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const searchTagsHideAll = new Set(\n envList(process.env.BSKY_SEARCH_TAGS_HIDE_ALL),\n )\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const irisUrl = process.env.BSKY_IRIS_URL || undefined\n const irisServiceDid = process.env.BSKY_IRIS_SERVICE_DID || undefined\n assert(irisServiceDid == null || isDidString(irisServiceDid))\n const trendingFeedDid = process.env.BSKY_TRENDING_FEED_DID || undefined\n assert(trendingFeedDid == null || isDidString(trendingFeedDid))\n const irisFeedUris = new Set(envList(process.env.BSKY_IRIS_FEED_URIS))\n const irisStagingUrl = process.env.BSKY_IRIS_STAGING_URL || undefined\n const irisStagingFeedUris = new Set(\n envList(process.env.BSKY_IRIS_STAGING_FEED_URIS),\n )\n const feedGenSkeletonTimeout = process.env.BSKY_FEED_GEN_SKELETON_TIMEOUT\n ? parseInt(process.env.BSKY_FEED_GEN_SKELETON_TIMEOUT || '', 10)\n : 5 * SECOND\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n assert(labelsFromIssuerDids.every(isDidString))\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid != null && isDidString(modServiceDid))\n\n const eventProxyTrackingEndpoint =\n process.env.BSKY_EVENT_PROXY_TRACKING_ENDPOINT || undefined\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n const notificationsV2Algorithm =\n process.env.BSKY_NOTIFICATIONS_V2_ALGORITHM === 'algoLookback'\n ? 'algoLookback'\n : 'algoGravity'\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyConnectTimeout =\n parseInt(process.env.BSKY_PROXY_CONNECT_TIMEOUT || '', 10) || undefined\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n const searchV2OverrideHeader =\n process.env.BSKY_SEARCH_V2_OVERRIDE_HEADER || undefined\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n searchTagsHideAll,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n irisUrl,\n irisServiceDid,\n trendingFeedDid,\n irisFeedUris,\n irisStagingUrl,\n irisStagingFeedUris,\n feedGenSkeletonTimeout,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n eventProxyTrackingEndpoint,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n notificationsV2Algorithm,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyConnectTimeout,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n searchV2OverrideHeader,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get searchTagsHideAll() {\n return this.cfg.searchTagsHideAll\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get irisUrl() {\n return this.cfg.irisUrl\n }\n\n get irisServiceDid() {\n return this.cfg.irisServiceDid\n }\n\n get trendingFeedDid() {\n return this.cfg.trendingFeedDid\n }\n\n get irisFeedUris() {\n return this.cfg.irisFeedUris\n }\n\n get irisStagingUrl() {\n return this.cfg.irisStagingUrl\n }\n\n get irisStagingFeedUris() {\n return this.cfg.irisStagingFeedUris\n }\n\n get feedGenSkeletonTimeout() {\n return this.cfg.feedGenSkeletonTimeout\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return (this.cfg.labelsFromIssuerDids ?? []) as DidString[]\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get eventProxyTrackingEndpoint() {\n return this.cfg.eventProxyTrackingEndpoint\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get notificationsV2Algorithm(): NotificationsV2Algorithm {\n return this.cfg.notificationsV2Algorithm ?? 'algoGravity'\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyConnectTimeout(): number | undefined {\n return this.cfg.proxyConnectTimeout\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n\n get searchV2OverrideHeader() {\n return this.cfg.searchV2OverrideHeader\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n isDidString(item.did) &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { SECOND, noUndefinedVals } from '@atproto/common'\nimport { type DidString, isDidString } from '@atproto/lex'\nimport { subLogger as log } from './logger.js'\n\ntype LiveNowConfig = {\n did: DidString\n domains: string[]\n}[]\n\nexport type NotificationsV2Algorithm = 'algoGravity' | 'algoLookback'\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: DidString\n alternateAudienceDids: DidString[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n searchTagsHideAll: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n irisUrl?: string\n irisServiceDid?: DidString\n seemoreServiceDid?: DidString\n irisStagingServiceDid?: DidString\n trendingFeedDid?: DidString\n bskyFeedgenDids: Set<string>\n irisApiKey?: string\n irisFeedUris?: Set<string> // allowlist iris may serve instead of seeemore; whats-hot is gated by `iris:feed:enable`, other feeds by their per-rkey `iris:feed:<rkey>:enable` gate\n irisStagingUrl?: string\n irisStagingFeedUris?: Set<string> // serve via iris staging instead of the registered feed generator\n feedGenSkeletonTimeout: number\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: DidString\n adminPasswords: string[]\n labelsFromIssuerDids?: DidString[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n eventProxyTrackingEndpoint?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n notificationsV2Algorithm?: NotificationsV2Algorithm\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyConnectTimeout?: number\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n searchV2OverrideHeader?: string\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n assert(isDidString(serverDid))\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n assert(alternateAudienceDids.every(isDidString))\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n // Values 0 through 16\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const searchTagsHideAll = new Set(\n envList(process.env.BSKY_SEARCH_TAGS_HIDE_ALL),\n )\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const irisUrl = process.env.BSKY_IRIS_URL || undefined\n const irisServiceDid = process.env.BSKY_IRIS_SERVICE_DID || undefined\n assert(irisServiceDid == null || isDidString(irisServiceDid))\n const seemoreServiceDid = process.env.BSKY_SEEMORE_SERVICE_DID || undefined\n assert(seemoreServiceDid == null || isDidString(seemoreServiceDid))\n const irisStagingServiceDid =\n process.env.BSKY_IRIS_STAGING_SERVICE_DID || undefined\n assert(irisStagingServiceDid == null || isDidString(irisStagingServiceDid))\n const trendingFeedDid = process.env.BSKY_TRENDING_FEED_DID || undefined\n assert(trendingFeedDid == null || isDidString(trendingFeedDid))\n const bskyFeedgenDids = new Set(\n envList(process.env.BSKY_FEEDGEN_DIDS).filter(isDidString),\n )\n const irisApiKey = process.env.BSKY_IRIS_API_KEY || undefined\n const irisFeedUris = new Set(envList(process.env.BSKY_IRIS_FEED_URIS))\n const irisStagingUrl = process.env.BSKY_IRIS_STAGING_URL || undefined\n const irisStagingFeedUris = new Set(\n envList(process.env.BSKY_IRIS_STAGING_FEED_URIS),\n )\n const feedGenSkeletonTimeout = process.env.BSKY_FEED_GEN_SKELETON_TIMEOUT\n ? parseInt(process.env.BSKY_FEED_GEN_SKELETON_TIMEOUT || '', 10)\n : 5 * SECOND\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n assert(labelsFromIssuerDids.every(isDidString))\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid != null && isDidString(modServiceDid))\n\n const eventProxyTrackingEndpoint =\n process.env.BSKY_EVENT_PROXY_TRACKING_ENDPOINT || undefined\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n const notificationsV2Algorithm =\n process.env.BSKY_NOTIFICATIONS_V2_ALGORITHM === 'algoLookback'\n ? 'algoLookback'\n : 'algoGravity'\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyConnectTimeout =\n parseInt(process.env.BSKY_PROXY_CONNECT_TIMEOUT || '', 10) || undefined\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n const searchV2OverrideHeader =\n process.env.BSKY_SEARCH_V2_OVERRIDE_HEADER || undefined\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n searchTagsHideAll,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n irisUrl,\n irisServiceDid,\n seemoreServiceDid,\n irisStagingServiceDid,\n trendingFeedDid,\n bskyFeedgenDids,\n irisApiKey,\n irisFeedUris,\n irisStagingUrl,\n irisStagingFeedUris,\n feedGenSkeletonTimeout,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n eventProxyTrackingEndpoint,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n notificationsV2Algorithm,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyConnectTimeout,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n searchV2OverrideHeader,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get searchTagsHideAll() {\n return this.cfg.searchTagsHideAll\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get irisUrl() {\n return this.cfg.irisUrl\n }\n\n get irisServiceDid() {\n return this.cfg.irisServiceDid\n }\n\n get seemoreServiceDid() {\n return this.cfg.seemoreServiceDid\n }\n\n get irisStagingServiceDid() {\n return this.cfg.irisStagingServiceDid\n }\n\n get trendingFeedDid() {\n return this.cfg.trendingFeedDid\n }\n\n get bskyFeedgenDids() {\n return this.cfg.bskyFeedgenDids\n }\n\n get irisApiKey() {\n return this.cfg.irisApiKey\n }\n\n get irisFeedUris() {\n return this.cfg.irisFeedUris\n }\n\n get irisStagingUrl() {\n return this.cfg.irisStagingUrl\n }\n\n get irisStagingFeedUris() {\n return this.cfg.irisStagingFeedUris\n }\n\n get feedGenSkeletonTimeout() {\n return this.cfg.feedGenSkeletonTimeout\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return (this.cfg.labelsFromIssuerDids ?? []) as DidString[]\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get eventProxyTrackingEndpoint() {\n return this.cfg.eventProxyTrackingEndpoint\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get notificationsV2Algorithm(): NotificationsV2Algorithm {\n return this.cfg.notificationsV2Algorithm ?? 'algoGravity'\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyConnectTimeout(): number | undefined {\n return this.cfg.proxyConnectTimeout\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n\n get searchV2OverrideHeader() {\n return this.cfg.searchV2OverrideHeader\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n isDidString(item.did) &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { ServiceImpl } from '@connectrpc/connect';
2
+ import type { Service } from '../../../proto/bsky_connect.js';
3
+ /** Empty Atmosphere responses for the local dataplane. */
4
+ export declare function atmosphere(): Partial<ServiceImpl<typeof Service>>;
5
+ //# sourceMappingURL=atmosphere.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atmosphere.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/atmosphere.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAE7D,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC,CAqBjE"}
@@ -0,0 +1,24 @@
1
+ /** Empty Atmosphere responses for the local dataplane. */
2
+ export function atmosphere() {
3
+ return {
4
+ async getAtmosphereTimeline() {
5
+ return { items: [] };
6
+ },
7
+ async getRecordsByRef() {
8
+ return { results: [] };
9
+ },
10
+ async getRecordsByURI() {
11
+ return { results: [] };
12
+ },
13
+ async getAtmosphereBacklinkCounts() {
14
+ return { results: [] };
15
+ },
16
+ async getAtmosphereBacklinks() {
17
+ return { backlinks: [] };
18
+ },
19
+ async getAtmosphereBacklinksByActor() {
20
+ return { results: [], truncated: false };
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=atmosphere.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atmosphere.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/atmosphere.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,KAAK,CAAC,qBAAqB;YACzB,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QACtB,CAAC;QACD,KAAK,CAAC,eAAe;YACnB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,eAAe;YACnB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,2BAA2B;YAC/B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,sBAAsB;YAC1B,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAA;QAC1B,CAAC;QACD,KAAK,CAAC,6BAA6B;YACjC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;QAC1C,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import type { ServiceImpl } from '@connectrpc/connect'\nimport type { Service } from '../../../proto/bsky_connect.js'\n\n/** Empty Atmosphere responses for the local dataplane. */\nexport function atmosphere(): Partial<ServiceImpl<typeof Service>> {\n return {\n async getAtmosphereTimeline() {\n return { items: [] }\n },\n async getRecordsByRef() {\n return { results: [] }\n },\n async getRecordsByURI() {\n return { results: [] }\n },\n async getAtmosphereBacklinkCounts() {\n return { results: [] }\n },\n async getAtmosphereBacklinks() {\n return { backlinks: [] }\n },\n async getAtmosphereBacklinksByActor() {\n return { results: [], truncated: false }\n },\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { Service } from '../../../proto/bsky_connect.js';
2
2
  import activitySubscription from './activity-subscription.js';
3
+ import { atmosphere } from './atmosphere.js';
3
4
  import blocks from './blocks.js';
4
5
  import bookmarks from './bookmarks.js';
5
6
  import drafts from './drafts.js';
@@ -20,7 +21,6 @@ import records from './records.js';
20
21
  import relationships from './relationships.js';
21
22
  import reposts from './reposts.js';
22
23
  import search from './search.js';
23
- import siteStandard from './site-standard.js';
24
24
  import sitemap from './sitemap.js';
25
25
  import starterPacks from './starter-packs.js';
26
26
  import suggestions from './suggestions.js';
@@ -28,6 +28,7 @@ import sync from './sync.js';
28
28
  import threads from './threads.js';
29
29
  export default (db, idResolver) => (router) => router.service(Service, {
30
30
  ...activitySubscription(db),
31
+ ...atmosphere(),
31
32
  ...blocks(db),
32
33
  ...bookmarks(db),
33
34
  ...drafts(db),
@@ -49,7 +50,6 @@ export default (db, idResolver) => (router) => router.service(Service, {
49
50
  ...reposts(db),
50
51
  ...search(db),
51
52
  ...sitemap(),
52
- ...siteStandard(db),
53
53
  ...suggestions(db),
54
54
  ...sync(db),
55
55
  ...threads(db),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,oBAAoB,MAAM,4BAA4B,CAAA;AAC7D,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,SAAS,MAAM,gBAAgB,CAAA;AACtC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,QAAQ,MAAM,eAAe,CAAA;AACpC,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAC5C,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,aAAa,MAAM,oBAAoB,CAAA;AAC9C,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,WAAW,MAAM,kBAAkB,CAAA;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,eAAe,CAAC,EAAY,EAAE,UAAsB,EAAE,EAAE,CACtD,CAAC,MAAqB,EAAE,EAAE,CACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;IACtB,GAAG,oBAAoB,CAAC,EAAE,CAAC;IAC3B,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,SAAS,CAAC,EAAE,CAAC;IAChB,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,QAAQ,CAAC,EAAE,CAAC;IACf,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IAC3B,GAAG,YAAY,CAAC,EAAE,CAAC;IACnB,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,UAAU,CAAC,EAAE,CAAC;IACjB,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,aAAa,CAAC,EAAE,CAAC;IACpB,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,EAAE;IACZ,GAAG,YAAY,CAAC,EAAE,CAAC;IACnB,GAAG,WAAW,CAAC,EAAE,CAAC;IAClB,GAAG,IAAI,CAAC,EAAE,CAAC;IACX,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,YAAY,CAAC,EAAE,CAAC;IAEnB,KAAK,CAAC,IAAI;QACR,OAAO,EAAE,CAAA;IACX,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { ConnectRouter } from '@connectrpc/connect'\nimport type { IdResolver } from '@atproto/identity'\nimport { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport activitySubscription from './activity-subscription.js'\nimport blocks from './blocks.js'\nimport bookmarks from './bookmarks.js'\nimport drafts from './drafts.js'\nimport feedGens from './feed-gens.js'\nimport feeds from './feeds.js'\nimport follows from './follows.js'\nimport identity from './identity.js'\nimport interactions from './interactions.js'\nimport labels from './labels.js'\nimport likes from './likes.js'\nimport lists from './lists.js'\nimport moderation from './moderation.js'\nimport mutes from './mutes.js'\nimport notifs from './notifs.js'\nimport profile from './profile.js'\nimport quotes from './quotes.js'\nimport records from './records.js'\nimport relationships from './relationships.js'\nimport reposts from './reposts.js'\nimport search from './search.js'\nimport siteStandard from './site-standard.js'\nimport sitemap from './sitemap.js'\nimport starterPacks from './starter-packs.js'\nimport suggestions from './suggestions.js'\nimport sync from './sync.js'\nimport threads from './threads.js'\n\nexport default (db: Database, idResolver: IdResolver) =>\n (router: ConnectRouter) =>\n router.service(Service, {\n ...activitySubscription(db),\n ...blocks(db),\n ...bookmarks(db),\n ...drafts(db),\n ...feedGens(db),\n ...feeds(db),\n ...follows(db),\n ...identity(db, idResolver),\n ...interactions(db),\n ...labels(db),\n ...likes(db),\n ...lists(db),\n ...moderation(db),\n ...mutes(db),\n ...notifs(db),\n ...profile(db),\n ...quotes(db),\n ...records(db),\n ...relationships(db),\n ...reposts(db),\n ...search(db),\n ...sitemap(),\n ...siteStandard(db),\n ...suggestions(db),\n ...sync(db),\n ...threads(db),\n ...starterPacks(db),\n\n async ping() {\n return {}\n },\n })\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/data-plane/server/routes/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,oBAAoB,MAAM,4BAA4B,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,SAAS,MAAM,gBAAgB,CAAA;AACtC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,QAAQ,MAAM,eAAe,CAAA;AACpC,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAC5C,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,UAAU,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,aAAa,MAAM,oBAAoB,CAAA;AAC9C,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,WAAW,MAAM,kBAAkB,CAAA;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,eAAe,CAAC,EAAY,EAAE,UAAsB,EAAE,EAAE,CACtD,CAAC,MAAqB,EAAE,EAAE,CACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;IACtB,GAAG,oBAAoB,CAAC,EAAE,CAAC;IAC3B,GAAG,UAAU,EAAE;IACf,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,SAAS,CAAC,EAAE,CAAC;IAChB,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,QAAQ,CAAC,EAAE,CAAC;IACf,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IAC3B,GAAG,YAAY,CAAC,EAAE,CAAC;IACnB,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,UAAU,CAAC,EAAE,CAAC;IACjB,GAAG,KAAK,CAAC,EAAE,CAAC;IACZ,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,aAAa,CAAC,EAAE,CAAC;IACpB,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,MAAM,CAAC,EAAE,CAAC;IACb,GAAG,OAAO,EAAE;IACZ,GAAG,WAAW,CAAC,EAAE,CAAC;IAClB,GAAG,IAAI,CAAC,EAAE,CAAC;IACX,GAAG,OAAO,CAAC,EAAE,CAAC;IACd,GAAG,YAAY,CAAC,EAAE,CAAC;IAEnB,KAAK,CAAC,IAAI;QACR,OAAO,EAAE,CAAA;IACX,CAAC;CACF,CAAC,CAAA","sourcesContent":["import type { ConnectRouter } from '@connectrpc/connect'\nimport type { IdResolver } from '@atproto/identity'\nimport { Service } from '../../../proto/bsky_connect.js'\nimport type { Database } from '../db/index.js'\nimport activitySubscription from './activity-subscription.js'\nimport { atmosphere } from './atmosphere.js'\nimport blocks from './blocks.js'\nimport bookmarks from './bookmarks.js'\nimport drafts from './drafts.js'\nimport feedGens from './feed-gens.js'\nimport feeds from './feeds.js'\nimport follows from './follows.js'\nimport identity from './identity.js'\nimport interactions from './interactions.js'\nimport labels from './labels.js'\nimport likes from './likes.js'\nimport lists from './lists.js'\nimport moderation from './moderation.js'\nimport mutes from './mutes.js'\nimport notifs from './notifs.js'\nimport profile from './profile.js'\nimport quotes from './quotes.js'\nimport records from './records.js'\nimport relationships from './relationships.js'\nimport reposts from './reposts.js'\nimport search from './search.js'\nimport sitemap from './sitemap.js'\nimport starterPacks from './starter-packs.js'\nimport suggestions from './suggestions.js'\nimport sync from './sync.js'\nimport threads from './threads.js'\n\nexport default (db: Database, idResolver: IdResolver) =>\n (router: ConnectRouter) =>\n router.service(Service, {\n ...activitySubscription(db),\n ...atmosphere(),\n ...blocks(db),\n ...bookmarks(db),\n ...drafts(db),\n ...feedGens(db),\n ...feeds(db),\n ...follows(db),\n ...identity(db, idResolver),\n ...interactions(db),\n ...labels(db),\n ...likes(db),\n ...lists(db),\n ...moderation(db),\n ...mutes(db),\n ...notifs(db),\n ...profile(db),\n ...quotes(db),\n ...records(db),\n ...relationships(db),\n ...reposts(db),\n ...search(db),\n ...sitemap(),\n ...suggestions(db),\n ...sync(db),\n ...threads(db),\n ...starterPacks(db),\n\n async ping() {\n return {}\n },\n })\n"]}
@@ -11,10 +11,20 @@ export declare enum Gate {
11
11
  SuggestedUsersForExploreEnable = "suggested_users:for_explore:enable",
12
12
  SuggestedUsersForDiscoverEnable = "suggested_users:for_discover:enable",
13
13
  SuggestedUsersForSeeMoreEnable = "suggested_users:for_see_more:enable",
14
+ SuggestedUsersIrisEnable = "suggested_users:iris:enable",
14
15
  SearchV2Enable = "search:v2:enable",
15
16
  IrisFeed = "iris:feed:enable",
17
+ IrisFeedWithFriendsEnable = "iris:feed:with-friends:enable",
18
+ IrisFeedThevidsEnable = "iris:feed:thevids:enable",
19
+ IrisFeedMutualsEnable = "iris:feed:mutuals:enable",
20
+ IrisFeedBskyTeamEnable = "iris:feed:bsky-team:enable",
21
+ IrisFeedBestOfFollowsEnable = "iris:feed:best-of-follows:enable",
22
+ IrisFeedFollowpicsEnable = "iris:feed:followpics:enable",
16
23
  OpThreadMetadataEnable = "op_thread_metadata:enable",
17
24
  KnownLikersFeedEnable = "known_likers:feed:enable",
25
+ SuggestedFeedsV2Enable = "suggested_feeds_v2:enable",
26
+ SuggestedStarterPacksV2Enable = "suggested_starter_packs_v2:enable",
27
+ SuggestedStarterPacksOnboardingV2Enable = "suggested_starter_packs_onboarding_v2:enable",
18
28
  AATest = "aa-test-appview"
19
29
  }
20
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oBAAY,IAAI;IACd,4BAA4B,0CAA0C;IACtE,+BAA+B,wCAAwC;IACvE,oCAAoC,6CAA6C;IACjF,gCAAgC,wCAAwC;IACxE,8BAA8B,uCAAuC;IACrE,+BAA+B,wCAAwC;IACvE,8BAA8B,wCAAwC;IACtE,cAAc,qBAAqB;IACnC,QAAQ,qBAAqB;IAC7B,sBAAsB,8BAA8B;IACpD,qBAAqB,6BAA6B;IAGlD,MAAM,oBAAoB;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,GAAG,CAAC,IAAI,CAAe,CAAA"}
1
+ {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oBAAY,IAAI;IACd,4BAA4B,0CAA0C;IACtE,+BAA+B,wCAAwC;IACvE,oCAAoC,6CAA6C;IACjF,gCAAgC,wCAAwC;IACxE,8BAA8B,uCAAuC;IACrE,+BAA+B,wCAAwC;IACvE,8BAA8B,wCAAwC;IACtE,wBAAwB,gCAAgC;IACxD,cAAc,qBAAqB;IACnC,QAAQ,qBAAqB;IAC7B,yBAAyB,kCAAkC;IAC3D,qBAAqB,6BAA6B;IAClD,qBAAqB,6BAA6B;IAClD,sBAAsB,+BAA+B;IACrD,2BAA2B,qCAAqC;IAChE,wBAAwB,gCAAgC;IACxD,sBAAsB,8BAA8B;IACpD,qBAAqB,6BAA6B;IAClD,sBAAsB,8BAA8B;IACpD,6BAA6B,sCAAsC;IACnE,uCAAuC,iDAAiD;IAGxF,MAAM,oBAAoB;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,GAAG,CAAC,IAAI,CAAe,CAAA"}
@@ -12,10 +12,20 @@ export var Gate;
12
12
  Gate["SuggestedUsersForExploreEnable"] = "suggested_users:for_explore:enable";
13
13
  Gate["SuggestedUsersForDiscoverEnable"] = "suggested_users:for_discover:enable";
14
14
  Gate["SuggestedUsersForSeeMoreEnable"] = "suggested_users:for_see_more:enable";
15
+ Gate["SuggestedUsersIrisEnable"] = "suggested_users:iris:enable";
15
16
  Gate["SearchV2Enable"] = "search:v2:enable";
16
17
  Gate["IrisFeed"] = "iris:feed:enable";
18
+ Gate["IrisFeedWithFriendsEnable"] = "iris:feed:with-friends:enable";
19
+ Gate["IrisFeedThevidsEnable"] = "iris:feed:thevids:enable";
20
+ Gate["IrisFeedMutualsEnable"] = "iris:feed:mutuals:enable";
21
+ Gate["IrisFeedBskyTeamEnable"] = "iris:feed:bsky-team:enable";
22
+ Gate["IrisFeedBestOfFollowsEnable"] = "iris:feed:best-of-follows:enable";
23
+ Gate["IrisFeedFollowpicsEnable"] = "iris:feed:followpics:enable";
17
24
  Gate["OpThreadMetadataEnable"] = "op_thread_metadata:enable";
18
25
  Gate["KnownLikersFeedEnable"] = "known_likers:feed:enable";
26
+ Gate["SuggestedFeedsV2Enable"] = "suggested_feeds_v2:enable";
27
+ Gate["SuggestedStarterPacksV2Enable"] = "suggested_starter_packs_v2:enable";
28
+ Gate["SuggestedStarterPacksOnboardingV2Enable"] = "suggested_starter_packs_onboarding_v2:enable";
19
29
  // temp
20
30
  Gate["AATest"] = "aa-test-appview";
21
31
  })(Gate || (Gate = {}));
@@ -1 +1 @@
1
- {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAN,IAAY,IAeX;AAfD,WAAY,IAAI;IACd,8EAAsE,CAAA;IACtE,+EAAuE,CAAA;IACvE,yFAAiF,CAAA;IACjF,gFAAwE,CAAA;IACxE,6EAAqE,CAAA;IACrE,+EAAuE,CAAA;IACvE,8EAAsE,CAAA;IACtE,2CAAmC,CAAA;IACnC,qCAA6B,CAAA;IAC7B,4DAAoD,CAAA;IACpD,0DAAkD,CAAA;IAElD,OAAO;IACP,kCAA0B,CAAA;AAC5B,CAAC,EAfW,IAAI,KAAJ,IAAI,QAef;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAc,IAAI,GAAG,CAAC,EAAE,CAAC,CAAA","sourcesContent":["/**\n * Enum of all gates in the system. This should be the single source of truth\n * for all gates, and should be used in all places where gates are checked or\n * defined.\n */\nexport enum Gate {\n SuggestedUsersDiscoverEnable = 'suggested_users:discover_agent:enable',\n SuggestedUsersSocialProofEnable = 'suggested_users:social_proof:enable',\n ThreadsReplyRankingExplorationEnable = 'threads:reply_ranking_exploration:enable',\n SearchFilteringExplorationEnable = 'search:filtering_exploration:enable',\n SuggestedUsersForExploreEnable = 'suggested_users:for_explore:enable',\n SuggestedUsersForDiscoverEnable = 'suggested_users:for_discover:enable',\n SuggestedUsersForSeeMoreEnable = 'suggested_users:for_see_more:enable',\n SearchV2Enable = 'search:v2:enable',\n IrisFeed = 'iris:feed:enable',\n OpThreadMetadataEnable = 'op_thread_metadata:enable',\n KnownLikersFeedEnable = 'known_likers:feed:enable',\n\n // temp\n AATest = 'aa-test-appview',\n}\n\n/**\n * Set of gates that should be ignored when tracking gate evaluations for\n * analytics purposes. This is useful for gates that are not user-facing or are\n * overly noisy.\n */\nexport const IGNORE_METRICS_FOR_GATES: Set<Gate> = new Set([])\n"]}
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/feature-gates/gates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAN,IAAY,IAyBX;AAzBD,WAAY,IAAI;IACd,8EAAsE,CAAA;IACtE,+EAAuE,CAAA;IACvE,yFAAiF,CAAA;IACjF,gFAAwE,CAAA;IACxE,6EAAqE,CAAA;IACrE,+EAAuE,CAAA;IACvE,8EAAsE,CAAA;IACtE,gEAAwD,CAAA;IACxD,2CAAmC,CAAA;IACnC,qCAA6B,CAAA;IAC7B,mEAA2D,CAAA;IAC3D,0DAAkD,CAAA;IAClD,0DAAkD,CAAA;IAClD,6DAAqD,CAAA;IACrD,wEAAgE,CAAA;IAChE,gEAAwD,CAAA;IACxD,4DAAoD,CAAA;IACpD,0DAAkD,CAAA;IAClD,4DAAoD,CAAA;IACpD,2EAAmE,CAAA;IACnE,gGAAwF,CAAA;IAExF,OAAO;IACP,kCAA0B,CAAA;AAC5B,CAAC,EAzBW,IAAI,KAAJ,IAAI,QAyBf;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAc,IAAI,GAAG,CAAC,EAAE,CAAC,CAAA","sourcesContent":["/**\n * Enum of all gates in the system. This should be the single source of truth\n * for all gates, and should be used in all places where gates are checked or\n * defined.\n */\nexport enum Gate {\n SuggestedUsersDiscoverEnable = 'suggested_users:discover_agent:enable',\n SuggestedUsersSocialProofEnable = 'suggested_users:social_proof:enable',\n ThreadsReplyRankingExplorationEnable = 'threads:reply_ranking_exploration:enable',\n SearchFilteringExplorationEnable = 'search:filtering_exploration:enable',\n SuggestedUsersForExploreEnable = 'suggested_users:for_explore:enable',\n SuggestedUsersForDiscoverEnable = 'suggested_users:for_discover:enable',\n SuggestedUsersForSeeMoreEnable = 'suggested_users:for_see_more:enable',\n SuggestedUsersIrisEnable = 'suggested_users:iris:enable',\n SearchV2Enable = 'search:v2:enable',\n IrisFeed = 'iris:feed:enable',\n IrisFeedWithFriendsEnable = 'iris:feed:with-friends:enable',\n IrisFeedThevidsEnable = 'iris:feed:thevids:enable',\n IrisFeedMutualsEnable = 'iris:feed:mutuals:enable',\n IrisFeedBskyTeamEnable = 'iris:feed:bsky-team:enable',\n IrisFeedBestOfFollowsEnable = 'iris:feed:best-of-follows:enable',\n IrisFeedFollowpicsEnable = 'iris:feed:followpics:enable',\n OpThreadMetadataEnable = 'op_thread_metadata:enable',\n KnownLikersFeedEnable = 'known_likers:feed:enable',\n SuggestedFeedsV2Enable = 'suggested_feeds_v2:enable',\n SuggestedStarterPacksV2Enable = 'suggested_starter_packs_v2:enable',\n SuggestedStarterPacksOnboardingV2Enable = 'suggested_starter_packs_onboarding_v2:enable',\n\n // temp\n AATest = 'aa-test-appview',\n}\n\n/**\n * Set of gates that should be ignored when tracking gate evaluations for\n * analytics purposes. This is useful for gates that are not user-facing or are\n * overly noisy.\n */\nexport const IGNORE_METRICS_FOR_GATES: Set<Gate> = new Set([])\n"]}
@@ -16,8 +16,8 @@ const REFETCH_INTERVAL = 60e3; // 1 minute
16
16
  /**
17
17
  * These need to match what the client sends
18
18
  */
19
- const ANALYTICS_HEADER_DEVICE_ID = 'X-Bsky-Device-Id';
20
- const ANALYTICS_HEADER_SESSION_ID = 'X-Bsky-Session-Id';
19
+ const ANALYTICS_HEADER_DEVICE_ID = 'x-atproto-device-id';
20
+ const ANALYTICS_HEADER_SESSION_ID = 'x-atproto-session-id';
21
21
  export {} from './types.js';
22
22
  export class FeatureGatesClient {
23
23
  constructor(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GrowthBookClient } from '@growthbook/growthbook'\nimport type express from 'express'\nimport { featureGatesLogger } from '../logger.js'\nimport { Gate, IGNORE_METRICS_FOR_GATES } from './gates.js'\nimport { MetricsClient } from './metrics.js'\nimport type {\n CheckedFeatureGatesMap,\n ScopedFeatureGatesClient,\n UserContext,\n} from './types.js'\nimport {\n extractUserContextFromGrowthbookUserContext,\n mergeUserContexts,\n normalizeUserContext,\n parsedUserContextToTrackingMetadata,\n} from './utils.js'\n\n/**\n * We want this to be sufficiently high that we don't time out under\n * normal conditions, but not so high that it takes too long to boot\n * the server.\n */\nconst FETCH_TIMEOUT = 3e3 // 3 seconds\n\n/**\n * StatSig used to default to every 10s, but I think 1m is fine\n */\nconst REFETCH_INTERVAL = 60e3 // 1 minute\n\n/**\n * These need to match what the client sends\n */\nconst ANALYTICS_HEADER_DEVICE_ID = 'X-Bsky-Device-Id'\nconst ANALYTICS_HEADER_SESSION_ID = 'X-Bsky-Session-Id'\n\nexport { type ScopedFeatureGatesClient } from './types.js'\n\nexport class FeatureGatesClient {\n private ready = false\n private client: GrowthBookClient | undefined = undefined\n private refreshInterval: NodeJS.Timeout | undefined = undefined\n private metrics: MetricsClient\n\n /**\n * Easy access to the `Gate` enum for consumers of this class, so they don't\n * need to import it separately.\n */\n Gate = Gate\n\n constructor(\n private config: {\n growthBookApiHost?: string\n growthBookClientKey?: string\n eventProxyTrackingEndpoint?: string\n },\n ) {\n this.metrics = new MetricsClient({\n trackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n }\n\n async start() {\n if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {\n featureGatesLogger.info(\n {},\n 'feature gates not configured, skipping initialization',\n )\n return\n }\n\n try {\n this.client = new GrowthBookClient({\n apiHost: this.config.growthBookApiHost,\n clientKey: this.config.growthBookClientKey,\n onFeatureUsage: async (feature, result, userContext) => {\n if (IGNORE_METRICS_FOR_GATES.has(feature as Gate)) return\n\n await this.metrics.track(\n 'feature:viewed',\n {\n featureId: feature,\n featureResultValue: result.value,\n experimentId: result.experiment?.key,\n variationId: result.experimentResult?.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n trackingCallback: async (experiment, result, userContext) => {\n /**\n * Experiments are only fired in a feature gate has an Experiment\n * attached in Growthbook. Howerver, we want to be extra sure that a\n * misconfigured experiment doesn't result in a huge increase in events, so we\n * protect this here.\n */\n if (\n result.featureId &&\n IGNORE_METRICS_FOR_GATES.has(result.featureId as Gate)\n )\n return\n\n await this.metrics.track(\n 'experiment:viewed',\n {\n experimentId: experiment.key,\n variationId: result.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n })\n\n const { source, error } = await this.client.init({\n timeout: FETCH_TIMEOUT,\n })\n\n /**\n * This does not necessarily mean that the client completely failed,\n * since it could just be that the request timed out. It may succeed\n * after the timeout, or later during refreshes.\n *\n * @see https://docs.growthbook.io/lib/node#error-handling\n */\n if (error) {\n featureGatesLogger.error(\n { err: error, source },\n 'Client failed to initialize normally',\n )\n }\n\n /**\n * Set up periodic refresh of feature definitions\n *\n * @see https://docs.growthbook.io/lib/node#refreshing-features\n */\n this.refreshInterval = setInterval(async () => {\n try {\n await this.client?.refreshFeatures({\n timeout: FETCH_TIMEOUT,\n })\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to refresh features')\n }\n }, REFETCH_INTERVAL)\n\n /* Ready or not, here we come */\n this.ready = true\n } catch (err) {\n featureGatesLogger.error({ err }, 'Client initialization failed')\n }\n }\n\n async destroy() {\n if (this.ready) {\n this.ready = false\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval)\n }\n }\n await this.metrics.stop()\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n\n /**\n * Evaluate multiple feature gates for a given user, returning a map of gate\n * ID to boolean result.\n */\n private checkGates(\n gates: Gate[],\n userContext: UserContext,\n ): CheckedFeatureGatesMap {\n const gb = this.client\n const attributes = normalizeUserContext(userContext)\n if (!gb || !this.ready) return new Map(gates.map((g) => [g, false]))\n return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]))\n }\n\n scope(scopedUserContext: UserContext): ScopedFeatureGatesClient {\n /*\n * Create initial deviceId and sessionId values for the scoped client, to\n * be used throughout this request lifecycle.\n */\n const base = normalizeUserContext(scopedUserContext)\n return {\n Gate: this.Gate,\n checkGates: (\n gates: Gate[],\n userContextOverrides?: Pick<UserContext, 'did'>,\n ) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates(gates, userContext)\n },\n checkGate: (gate: Gate, userContextOverrides?: UserContext) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates([gate], userContext).get(gate) || false\n },\n }\n }\n\n /**\n * Parse properties available in XRPC handlers to `UserContext`. The returned\n * proeprties are used as GrowthBook `attributes` as well as the metadata\n * payload for our analytics events. This ensures that the same user properties\n * are used for both feature gate targeting and analytics.\n */\n parseUserContextFromHandler({\n viewer,\n req,\n }: {\n /**\n * The user's DID\n */\n viewer: string | null\n /**\n * The express request object, used to extract analytics headers for the user context\n */\n req: express.Request\n }): UserContext {\n const deviceId = req.header(ANALYTICS_HEADER_DEVICE_ID)\n const sessionId = req.header(ANALYTICS_HEADER_SESSION_ID)\n\n return normalizeUserContext({\n did: viewer,\n deviceId,\n sessionId,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAM5C,OAAO,EACL,2CAA2C,EAC3C,iBAAiB,EACjB,oBAAoB,EACpB,mCAAmC,GACpC,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,MAAM,aAAa,GAAG,GAAG,CAAA,CAAC,YAAY;AAEtC;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,CAAA,CAAC,WAAW;AAEzC;;GAEG;AACH,MAAM,0BAA0B,GAAG,qBAAqB,CAAA;AACxD,MAAM,2BAA2B,GAAG,sBAAsB,CAAA;AAE1D,OAAO,EAAiC,MAAM,YAAY,CAAA;AAE1D,MAAM,OAAO,kBAAkB;IAY7B,YACU,MAIP;QAJO,WAAM,GAAN,MAAM,CAIb;QAhBK,UAAK,GAAG,KAAK,CAAA;QACb,WAAM,GAAiC,SAAS,CAAA;QAChD,oBAAe,GAA+B,SAAS,CAAA;QAG/D;;;WAGG;QACH,SAAI,GAAG,IAAI,CAAA;QAST,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC;YAC/B,gBAAgB,EAAE,MAAM,CAAC,0BAA0B;SACpD,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;YACvE,kBAAkB,CAAC,IAAI,CACrB,EAAE,EACF,uDAAuD,CACxD,CAAA;YACD,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC;gBACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;gBACtC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB;gBAC1C,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;oBACrD,IAAI,wBAAwB,CAAC,GAAG,CAAC,OAAe,CAAC;wBAAE,OAAM;oBAEzD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CACtB,gBAAgB,EAChB;wBACE,SAAS,EAAE,OAAO;wBAClB,kBAAkB,EAAE,MAAM,CAAC,KAAK;wBAChC,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG;wBACpC,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,GAAG;qBAC1C,EACD,mCAAmC,CACjC,2CAA2C,CAAC,WAAW,CAAC,CACzD,CACF,CAAA;gBACH,CAAC;gBACD,gBAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;oBAC1D;;;;;uBAKG;oBACH,IACE,MAAM,CAAC,SAAS;wBAChB,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAiB,CAAC;wBAEtD,OAAM;oBAER,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CACtB,mBAAmB,EACnB;wBACE,YAAY,EAAE,UAAU,CAAC,GAAG;wBAC5B,WAAW,EAAE,MAAM,CAAC,GAAG;qBACxB,EACD,mCAAmC,CACjC,2CAA2C,CAAC,WAAW,CAAC,CACzD,CACF,CAAA;gBACH,CAAC;aACF,CAAC,CAAA;YAEF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC/C,OAAO,EAAE,aAAa;aACvB,CAAC,CAAA;YAEF;;;;;;eAMG;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,kBAAkB,CAAC,KAAK,CACtB,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EACtB,sCAAsC,CACvC,CAAA;YACH,CAAC;YAED;;;;eAIG;YACH,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;gBAC5C,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC;wBACjC,OAAO,EAAE,aAAa;qBACvB,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAA;gBACjE,CAAC;YACH,CAAC,EAAE,gBAAgB,CAAC,CAAA;YAEpB,gCAAgC;YAChC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAA;QACnE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;YAClB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;IAED;;;OAGG;IACK,UAAU,CAChB,KAAa,EACb,WAAwB;QAExB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QACtB,MAAM,UAAU,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAA;QACpD,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;QACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC;IAED,KAAK,CAAC,iBAA8B;QAClC;;;WAGG;QACH,MAAM,IAAI,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAA;QACpD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,CACV,KAAa,EACb,oBAA+C,EAC/C,EAAE;gBACF,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAA;gBACjE,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;YAC5C,CAAC;YACD,SAAS,EAAE,CAAC,IAAU,EAAE,oBAAkC,EAAE,EAAE;gBAC5D,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAA;gBACjE,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAA;YAChE,CAAC;SACF,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACH,2BAA2B,CAAC,EAC1B,MAAM,EACN,GAAG,GAUJ;QACC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAA;QACvD,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAA;QAEzD,OAAO,oBAAoB,CAAC;YAC1B,GAAG,EAAE,MAAM;YACX,QAAQ;YACR,SAAS;SACV,CAAC,CAAA;IACJ,CAAC;CACF","sourcesContent":["import { GrowthBookClient } from '@growthbook/growthbook'\nimport type express from 'express'\nimport { featureGatesLogger } from '../logger.js'\nimport { Gate, IGNORE_METRICS_FOR_GATES } from './gates.js'\nimport { MetricsClient } from './metrics.js'\nimport type {\n CheckedFeatureGatesMap,\n ScopedFeatureGatesClient,\n UserContext,\n} from './types.js'\nimport {\n extractUserContextFromGrowthbookUserContext,\n mergeUserContexts,\n normalizeUserContext,\n parsedUserContextToTrackingMetadata,\n} from './utils.js'\n\n/**\n * We want this to be sufficiently high that we don't time out under\n * normal conditions, but not so high that it takes too long to boot\n * the server.\n */\nconst FETCH_TIMEOUT = 3e3 // 3 seconds\n\n/**\n * StatSig used to default to every 10s, but I think 1m is fine\n */\nconst REFETCH_INTERVAL = 60e3 // 1 minute\n\n/**\n * These need to match what the client sends\n */\nconst ANALYTICS_HEADER_DEVICE_ID = 'x-atproto-device-id'\nconst ANALYTICS_HEADER_SESSION_ID = 'x-atproto-session-id'\n\nexport { type ScopedFeatureGatesClient } from './types.js'\n\nexport class FeatureGatesClient {\n private ready = false\n private client: GrowthBookClient | undefined = undefined\n private refreshInterval: NodeJS.Timeout | undefined = undefined\n private metrics: MetricsClient\n\n /**\n * Easy access to the `Gate` enum for consumers of this class, so they don't\n * need to import it separately.\n */\n Gate = Gate\n\n constructor(\n private config: {\n growthBookApiHost?: string\n growthBookClientKey?: string\n eventProxyTrackingEndpoint?: string\n },\n ) {\n this.metrics = new MetricsClient({\n trackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n }\n\n async start() {\n if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {\n featureGatesLogger.info(\n {},\n 'feature gates not configured, skipping initialization',\n )\n return\n }\n\n try {\n this.client = new GrowthBookClient({\n apiHost: this.config.growthBookApiHost,\n clientKey: this.config.growthBookClientKey,\n onFeatureUsage: async (feature, result, userContext) => {\n if (IGNORE_METRICS_FOR_GATES.has(feature as Gate)) return\n\n await this.metrics.track(\n 'feature:viewed',\n {\n featureId: feature,\n featureResultValue: result.value,\n experimentId: result.experiment?.key,\n variationId: result.experimentResult?.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n trackingCallback: async (experiment, result, userContext) => {\n /**\n * Experiments are only fired in a feature gate has an Experiment\n * attached in Growthbook. Howerver, we want to be extra sure that a\n * misconfigured experiment doesn't result in a huge increase in events, so we\n * protect this here.\n */\n if (\n result.featureId &&\n IGNORE_METRICS_FOR_GATES.has(result.featureId as Gate)\n )\n return\n\n await this.metrics.track(\n 'experiment:viewed',\n {\n experimentId: experiment.key,\n variationId: result.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n })\n\n const { source, error } = await this.client.init({\n timeout: FETCH_TIMEOUT,\n })\n\n /**\n * This does not necessarily mean that the client completely failed,\n * since it could just be that the request timed out. It may succeed\n * after the timeout, or later during refreshes.\n *\n * @see https://docs.growthbook.io/lib/node#error-handling\n */\n if (error) {\n featureGatesLogger.error(\n { err: error, source },\n 'Client failed to initialize normally',\n )\n }\n\n /**\n * Set up periodic refresh of feature definitions\n *\n * @see https://docs.growthbook.io/lib/node#refreshing-features\n */\n this.refreshInterval = setInterval(async () => {\n try {\n await this.client?.refreshFeatures({\n timeout: FETCH_TIMEOUT,\n })\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to refresh features')\n }\n }, REFETCH_INTERVAL)\n\n /* Ready or not, here we come */\n this.ready = true\n } catch (err) {\n featureGatesLogger.error({ err }, 'Client initialization failed')\n }\n }\n\n async destroy() {\n if (this.ready) {\n this.ready = false\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval)\n }\n }\n await this.metrics.stop()\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n\n /**\n * Evaluate multiple feature gates for a given user, returning a map of gate\n * ID to boolean result.\n */\n private checkGates(\n gates: Gate[],\n userContext: UserContext,\n ): CheckedFeatureGatesMap {\n const gb = this.client\n const attributes = normalizeUserContext(userContext)\n if (!gb || !this.ready) return new Map(gates.map((g) => [g, false]))\n return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]))\n }\n\n scope(scopedUserContext: UserContext): ScopedFeatureGatesClient {\n /*\n * Create initial deviceId and sessionId values for the scoped client, to\n * be used throughout this request lifecycle.\n */\n const base = normalizeUserContext(scopedUserContext)\n return {\n Gate: this.Gate,\n checkGates: (\n gates: Gate[],\n userContextOverrides?: Pick<UserContext, 'did'>,\n ) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates(gates, userContext)\n },\n checkGate: (gate: Gate, userContextOverrides?: UserContext) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates([gate], userContext).get(gate) || false\n },\n }\n }\n\n /**\n * Parse properties available in XRPC handlers to `UserContext`. The returned\n * proeprties are used as GrowthBook `attributes` as well as the metadata\n * payload for our analytics events. This ensures that the same user properties\n * are used for both feature gate targeting and analytics.\n */\n parseUserContextFromHandler({\n viewer,\n req,\n }: {\n /**\n * The user's DID\n */\n viewer: string | null\n /**\n * The express request object, used to extract analytics headers for the user context\n */\n req: express.Request\n }): UserContext {\n const deviceId = req.header(ANALYTICS_HEADER_DEVICE_ID)\n const sessionId = req.header(ANALYTICS_HEADER_SESSION_ID)\n\n return normalizeUserContext({\n did: viewer,\n deviceId,\n sessionId,\n })\n }\n}\n"]}
@@ -1,11 +1,45 @@
1
- import type { AtUriString } from '@atproto/syntax';
1
+ import { type AtUriString, type DidString, type NsidString, type TypedLexMap } from '@atproto/lex';
2
2
  import type { DataPlaneClient } from '../data-plane/client/index.js';
3
3
  import type { SiteStandardDocumentRecord, SiteStandardPublicationRecord } from '../views/types.js';
4
4
  import { HydrationMap, type ItemRef, type RecordInfo } from './util.js';
5
+ /** Generic record bodies are decoded, but not validated against a Lexicon. */
6
+ export type GenericRecord = RecordInfo<TypedLexMap>;
7
+ export type GenericRecords = HydrationMap<AtUriString, GenericRecord>;
8
+ /** Keyed by `genericRecordKey(uri, cid)` to retain multiple versions of a URI. */
9
+ export type GenericRecordsByRef = HydrationMap<string, GenericRecord>;
10
+ export type AtmosphereActivityItem = {
11
+ uri: AtUriString;
12
+ sortedAt: Date;
13
+ };
14
+ export type AtmosphereTimeline = {
15
+ items: AtmosphereActivityItem[];
16
+ cursor?: string;
17
+ };
18
+ export type AtmosphereBacklinks = {
19
+ backlinks: AtmosphereActivityItem[];
20
+ cursor?: string;
21
+ };
22
+ export type AtmosphereBacklinkCounts = HydrationMap<AtUriString, Partial<Record<NsidString, number>>>;
23
+ export type AtmosphereBacklinksByActor = {
24
+ backlinks: HydrationMap<AtUriString, AtUriString[]>;
25
+ truncated: boolean;
26
+ };
27
+ /**
28
+ * Composes a stable map key from an `(uri, cid)` pair. A single hydration
29
+ * batch can pull more than one version of the same record URI (different
30
+ * posts pinning different cids), so the composite is needed for O(1)
31
+ * version-exact lookups.
32
+ */
33
+ export declare function genericRecordKey(uri: AtUriString, cid: string): string;
34
+ /** Recover the URI and CID from a composite hydration key. */
35
+ export declare function parseGenericRecordKey(key: string): {
36
+ uri: AtUriString;
37
+ cid: string;
38
+ };
5
39
  export type SiteStandardDocument = RecordInfo<SiteStandardDocumentRecord>;
6
40
  export type SiteStandardPublication = RecordInfo<SiteStandardPublicationRecord>;
7
41
  /**
8
- * Keyed by `${uri}@${cid}` — see `siteStandardRecordKey`. A single hydration
42
+ * Keyed by `${uri}@${cid}` — see `genericRecordKey`. A single hydration
9
43
  * batch can pull more than one version of the same URI (different posts
10
44
  * pinning different cids), so the composite key is needed for O(1)
11
45
  * version-exact lookups.
@@ -29,8 +63,37 @@ export type AssociatedSiteStandardRecord<T> = {
29
63
  export declare class ExternalHydrator {
30
64
  dataplane: DataPlaneClient;
31
65
  constructor(dataplane: DataPlaneClient);
66
+ /** Fetch exact record versions; unavailable records are represented by null. */
67
+ getRecordsByRef(refs: Required<ItemRef>[], includeTakedowns?: boolean): Promise<GenericRecordsByRef>;
68
+ /** Fetch the latest indexed versions without collection-specific validation. */
69
+ getRecordsByURI(uris: AtUriString[], includeTakedowns?: boolean): Promise<GenericRecords>;
70
+ /** Fetch a page of activity refs for subsequent generic record hydration. */
71
+ getAtmosphereTimeline(viewerDid: DidString, opts?: {
72
+ limit?: number;
73
+ cursor?: string;
74
+ }): Promise<AtmosphereTimeline>;
75
+ /** Fetch source-record counts, optionally restricted to one collection. */
76
+ getAtmosphereBacklinkCounts(targetUris: AtUriString[], collection?: NsidString): Promise<AtmosphereBacklinkCounts>;
77
+ /** Fetch a page of source records linking to a target. */
78
+ getAtmosphereBacklinks(targetUri: AtUriString, collection: NsidString, opts?: {
79
+ limit?: number;
80
+ cursor?: string;
81
+ }): Promise<AtmosphereBacklinks>;
82
+ /** Fetch an actor's links per target, retaining the batch truncation flag. */
83
+ getAtmosphereBacklinksByActor(targetUris: AtUriString[], actorDid: DidString, collection: NsidString): Promise<AtmosphereBacklinksByActor>;
84
+ /**
85
+ * Fetch exact `site.standard.{document,publication}` versions. Does NOT
86
+ * resolve a document's publication; callers must pin it explicitly.
87
+ */
32
88
  getSiteStandardRecordsByRef(refs: ItemRef[], includeTakedowns?: boolean): Promise<SiteStandardRecords>;
89
+ /**
90
+ * Fetch the latest `site.standard.{document,publication}` versions. The
91
+ * generic record lookup does not follow references, so publications named
92
+ * by the `site` field of the hydrated documents are fetched in a second
93
+ * call.
94
+ */
33
95
  getSiteStandardRecordsByURI(uris: AtUriString[], includeTakedowns?: boolean): Promise<SiteStandardRecords>;
96
+ private addSiteStandardRecordsByURI;
34
97
  }
35
98
  /**
36
99
  * Read-path resolution: caller pinned a set of `(uri, cid)` strongRefs in
@@ -1 +1 @@
1
- {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAWpE,OAAO,KAAK,EACV,0BAA0B,EAC1B,6BAA6B,EAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,UAAU,EAEhB,MAAM,WAAW,CAAA;AAElB,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,0BAA0B,CAAC,CAAA;AACzE,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,6BAA6B,CAAC,CAAA;AAE/E;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;AAC9E;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,YAAY,CACjD,MAAM,EACN,uBAAuB,CACxB,CAAA;AACD,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,qBAAqB,CAAA;IAChC,YAAY,EAAE,wBAAwB,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,4BAA4B,CAAC,CAAC,IAAI;IAC5C,GAAG,EAAE;QAAE,GAAG,EAAE,WAAW,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,IAAI,EAAE,CAAC,CAAA;CACR,CAAA;AAED,qBAAa,gBAAgB;IACR,SAAS,EAAE,eAAe;IAA7C,YAAmB,SAAS,EAAE,eAAe,EAAI;IAE3C,2BAA2B,CAC/B,IAAI,EAAE,OAAO,EAAE,EACf,gBAAgB,UAAQ,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAO9B;IAEK,2BAA2B,CAC/B,IAAI,EAAE,WAAW,EAAE,EACnB,gBAAgB,UAAQ,GACvB,OAAO,CAAC,mBAAmB,CAAC,CAK9B;CACF;AAiCD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,6CAA6C,mBACxC,SAAS;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,SAAS,aAC7D,qBAAqB,GAAG,SAAS,gBAC9B,wBAAwB,GAAG,SAAS,KACjD;IACD,QAAQ,EAAE,4BAA4B,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAA;IACxE,WAAW,EAAE,4BAA4B,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAA;CAwD/E,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,oDAAoD,cACpD,qBAAqB,GAAG,SAAS,gBAC9B,wBAAwB,GAAG,SAAS,KACjD;IACD,QAAQ,EAAE,4BAA4B,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAA;IACxE,WAAW,EAAE,4BAA4B,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAA;CA2C/E,CAAA"}
1
+ {"version":3,"file":"external.d.ts","sourceRoot":"","sources":["../../src/hydration/external.ts"],"names":[],"mappings":"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"}