@atproto/bsky 0.0.234 → 0.0.235

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/bsky",
3
- "version": "0.0.234",
3
+ "version": "0.0.235",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of app.bsky App View (Bluesky API)",
6
6
  "keywords": [
@@ -50,12 +50,12 @@
50
50
  "zod": "3.23.8",
51
51
  "@atproto-labs/fetch-node": "^0.3.0",
52
52
  "@atproto-labs/xrpc-utils": "^0.1.0",
53
- "@atproto/api": "^0.20.5",
53
+ "@atproto/api": "^0.20.6",
54
54
  "@atproto/common": "^0.6.1",
55
55
  "@atproto/crypto": "^0.5.0",
56
- "@atproto/did": "^0.4.0",
56
+ "@atproto/did": "^0.5.0",
57
57
  "@atproto/identity": "^0.5.0",
58
- "@atproto/lex": "^0.1.2",
58
+ "@atproto/lex": "^0.1.3",
59
59
  "@atproto/repo": "^0.10.0",
60
60
  "@atproto/sync": "^0.3.1",
61
61
  "@atproto/syntax": "^0.6.1",
@@ -74,7 +74,7 @@
74
74
  "ts-node": "^10.8.2",
75
75
  "typescript": "^6.0.3",
76
76
  "vitest": "^4.0.16",
77
- "@atproto/pds": "^0.5.0"
77
+ "@atproto/pds": "^0.5.1"
78
78
  },
79
79
  "type": "module",
80
80
  "exports": {
@@ -1,6 +1,7 @@
1
1
  import { AtUriString } from '@atproto/syntax'
2
2
  import { DataPlaneClient } from '../data-plane/client/index.js'
3
3
  import { site } from '../lexicons/index.js'
4
+ import { hydrationLogger } from '../logger.js'
4
5
  import {
5
6
  GetSiteStandardRecordsByRefResponse,
6
7
  GetSiteStandardRecordsByURIResponse,
@@ -162,6 +163,14 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (
162
163
  // (or tampered with), so reject the whole pairing.
163
164
  if (document && publication) {
164
165
  if (document.info.record.site !== publication.ref.uri) {
166
+ hydrationLogger.warn(
167
+ {
168
+ documentUri: document.ref.uri,
169
+ documentSite: document.info.record.site,
170
+ publicationUri: publication.ref.uri,
171
+ },
172
+ 'site.standard byRefs lookup failed: doc.site does not match hydrated publication.uri',
173
+ )
165
174
  return { document: undefined, publication: undefined }
166
175
  }
167
176
  }
@@ -172,6 +181,10 @@ export const getSiteStandardRecordsFromHydrationMapsByRefs = (
172
181
  if (document && !publication) {
173
182
  const site = document.info.record.site
174
183
  if (site && site.startsWith('at://')) {
184
+ hydrationLogger.warn(
185
+ { documentUri: document.ref.uri, documentSite: site },
186
+ 'site.standard byRefs lookup failed: document.site is AT URI but no matching publication was hydrated',
187
+ )
175
188
  return { document: undefined, publication: undefined }
176
189
  }
177
190
  }
@@ -234,6 +247,10 @@ export const getSiteStandardRecordsFromHydrationMapsByDocumentUri = (
234
247
  }
235
248
  }
236
249
  if (!publication) {
250
+ hydrationLogger.warn(
251
+ { documentUri: document.ref.uri, documentSite: site },
252
+ 'site.standard byDocumentUri lookup failed: document.site is AT URI but no matching publication was hydrated',
253
+ )
237
254
  return { document: undefined, publication: undefined }
238
255
  }
239
256
  }
@@ -101,6 +101,13 @@ describe(validateStandardSiteForUrl, () => {
101
101
  validateStandardSiteForUrl(undefined, pub, 'https://other.com'),
102
102
  ).toBe(false)
103
103
  })
104
+
105
+ it('accepts when assumedUrl has a trailing slash and publication.url does not', () => {
106
+ const pub = makePub({ url: 'https://atproto.com/blog' })
107
+ expect(
108
+ validateStandardSiteForUrl(undefined, pub, 'https://atproto.com/blog/'),
109
+ ).toBe(true)
110
+ })
104
111
  })
105
112
 
106
113
  describe('neither', () => {
@@ -1,4 +1,4 @@
1
- import { HOUR, MINUTE, mapDefined } from '@atproto/common'
1
+ import { HOUR, MINUTE, dedupeStrs, mapDefined } from '@atproto/common'
2
2
  import {
3
3
  $Typed,
4
4
  Un$Typed,
@@ -2141,14 +2141,6 @@ export class Views {
2141
2141
  state,
2142
2142
  assumedUrl: embed.external.uri,
2143
2143
  })
2144
- // Profiles of the owners of pinned `associatedRefs`. Hydrator covers
2145
- // these DIDs alongside post-author profiles, so misses here only
2146
- // happen when an actor is unavailable (suspended, deleted, etc.) —
2147
- // drop those rather than emit `undefined` slots.
2148
- const associatedProfiles = mapDefined(
2149
- embed.external.associatedRefs ?? [],
2150
- (ref) => this.profileBasic(uriToDid(ref.uri), state),
2151
- ) as ProfileViewBasic[]
2152
2144
  return app.bsky.embed.external.view.$build({
2153
2145
  external: {
2154
2146
  uri: embed.external.uri,
@@ -2163,9 +2155,6 @@ export class Views {
2163
2155
  : undefined,
2164
2156
  ...ssView,
2165
2157
  associatedRefs: embed.external.associatedRefs,
2166
- associatedProfiles: associatedProfiles.length
2167
- ? associatedProfiles
2168
- : undefined,
2169
2158
  },
2170
2159
  })
2171
2160
  }
@@ -2263,7 +2252,7 @@ export class Views {
2263
2252
  documentUri: document?.ref.uri,
2264
2253
  publicationUri: publication?.ref.uri,
2265
2254
  },
2266
- 'SS record(s) failed URL validation for external embed',
2255
+ 'site.standard URL validation failed',
2267
2256
  )
2268
2257
  return undefined
2269
2258
  }
@@ -2333,6 +2322,21 @@ export class Views {
2333
2322
  overlay.source = this.externalEmbedSource(publication)
2334
2323
  }
2335
2324
 
2325
+ // Profiles of the owners of the records backing this embed. Hydrator
2326
+ // covers these DIDs alongside post-author profiles, so misses here
2327
+ // only happen when an actor is unavailable (suspended, deleted, etc.)
2328
+ // — drop those rather than emit `undefined` slots.
2329
+ const uniqueDids = dedupeStrs(
2330
+ mapDefined([document?.ref.uri, publication?.ref.uri], (uri) =>
2331
+ uri ? uriToDid(uri) : undefined,
2332
+ ) as DidString[],
2333
+ )
2334
+ const associatedProfiles = mapDefined(uniqueDids, (did) =>
2335
+ this.profileBasic(did, state),
2336
+ ) as ProfileViewBasic[]
2337
+ if (associatedProfiles.length)
2338
+ overlay.associatedProfiles = associatedProfiles
2339
+
2336
2340
  return overlay
2337
2341
  }
2338
2342
 
@@ -724,18 +724,14 @@ describe('pds profile views', () => {
724
724
  })
725
725
 
726
726
  it('filters out Go zero-value dates from dataplane', async () => {
727
- // Spy on the dataplane getActors method
728
- const getActorsSpy = vi.spyOn(network.bsky.ctx.dataplane, 'getActors')
727
+ using getActorsSpy = vi.spyOn(network.bsky.ctx.dataplane, 'getActors')
729
728
 
730
- // Call the original implementation but modify the result
731
729
  getActorsSpy.mockImplementationOnce(async (req) => {
732
- // Call the real method
733
730
  const result = await network.bsky.ctx.dataplane.getActors(req)
734
731
 
735
- // Modify the result to inject a Go zero-value date
732
+ // Inject a Go zero-value date (0001-01-01 00:00:00 UTC)
736
733
  if (result.actors.length > 0 && result.actors[0]) {
737
734
  const actor = result.actors[0]
738
- // Create a Timestamp with Go zero-value (0001-01-01 00:00:00 UTC)
739
735
  const goZeroDate = new Date(-62135596800000)
740
736
  actor.createdAt = Timestamp.fromDate(goZeroDate)
741
737
  }
@@ -750,11 +746,8 @@ describe('pds profile views', () => {
750
746
  },
751
747
  )
752
748
 
753
- // The createdAt should be undefined because the hydration layer filters it out
749
+ // The hydration layer filters Go zero-values out
754
750
  expect(data.createdAt).toBeUndefined()
755
-
756
- // Clean up
757
- getActorsSpy.mockRestore()
758
751
  })
759
752
 
760
753
  async function updateProfile(did: string, record: Record<string, unknown>) {