@atproto/bsky 0.0.205 → 0.0.207
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/CHANGELOG.md +18 -0
- package/dist/api/age-assurance/const.d.ts.map +1 -1
- package/dist/api/age-assurance/const.js +8 -0
- package/dist/api/age-assurance/const.js.map +1 -1
- package/dist/api/app/bsky/actor/getProfile.js +1 -1
- package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
- package/dist/hydration/actor.d.ts +6 -0
- package/dist/hydration/actor.d.ts.map +1 -1
- package/dist/hydration/actor.js +2 -2
- package/dist/hydration/actor.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +2 -2
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +9 -3
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +26 -2
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +13 -1
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/ageassurance/defs.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/ageassurance/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/ageassurance/defs.js.map +1 -1
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +4 -1
- package/dist/views/index.js.map +1 -1
- package/package.json +6 -6
- package/src/api/age-assurance/const.ts +8 -0
- package/src/api/app/bsky/actor/getProfile.ts +1 -1
- package/src/hydration/actor.ts +12 -2
- package/src/hydration/hydrator.ts +10 -3
- package/src/lexicon/lexicons.ts +14 -1
- package/src/lexicon/types/app/bsky/actor/defs.ts +2 -0
- package/src/lexicon/types/app/bsky/ageassurance/defs.ts +2 -0
- package/src/views/index.ts +4 -1
- package/tests/views/__snapshots__/profile.test.ts.snap +6 -2
- package/tests/views/age-assurance-v2.test.ts +2 -0
- package/tests/views/profile.test.ts +41 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsky",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.207",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -52,17 +52,17 @@
|
|
|
52
52
|
"undici": "^6.19.8",
|
|
53
53
|
"zod": "3.23.8",
|
|
54
54
|
"@atproto-labs/fetch-node": "0.2.0",
|
|
55
|
-
"@atproto/api": "^0.18.10",
|
|
56
55
|
"@atproto/common": "^0.5.6",
|
|
57
|
-
"@atproto/
|
|
56
|
+
"@atproto/api": "^0.18.12",
|
|
58
57
|
"@atproto-labs/xrpc-utils": "0.0.24",
|
|
58
|
+
"@atproto/crypto": "^0.4.5",
|
|
59
59
|
"@atproto/did": "^0.2.4",
|
|
60
60
|
"@atproto/identity": "^0.4.10",
|
|
61
61
|
"@atproto/lexicon": "^0.6.0",
|
|
62
|
+
"@atproto/repo": "^0.8.12",
|
|
62
63
|
"@atproto/sync": "^0.1.39",
|
|
63
64
|
"@atproto/syntax": "^0.4.2",
|
|
64
|
-
"@atproto/xrpc-server": "^0.10.7"
|
|
65
|
-
"@atproto/repo": "^0.8.12"
|
|
65
|
+
"@atproto/xrpc-server": "^0.10.7"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@bufbuild/buf": "^1.28.1",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"jest": "^28.1.2",
|
|
79
79
|
"ts-node": "^10.8.2",
|
|
80
80
|
"typescript": "^5.6.3",
|
|
81
|
-
"@atproto/api": "^0.18.
|
|
81
|
+
"@atproto/api": "^0.18.12",
|
|
82
82
|
"@atproto/lex-cli": "^0.9.8",
|
|
83
83
|
"@atproto/pds": "^0.4.202",
|
|
84
84
|
"@atproto/xrpc": "^0.7.7"
|
|
@@ -16,6 +16,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
16
16
|
{
|
|
17
17
|
countryCode: 'GB',
|
|
18
18
|
regionCode: undefined,
|
|
19
|
+
minAccessAge: 13,
|
|
19
20
|
rules: [
|
|
20
21
|
{
|
|
21
22
|
$type: ids.IfAssuredOverAge,
|
|
@@ -36,6 +37,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
36
37
|
{
|
|
37
38
|
countryCode: 'AU',
|
|
38
39
|
regionCode: undefined,
|
|
40
|
+
minAccessAge: 16,
|
|
39
41
|
rules: [
|
|
40
42
|
{
|
|
41
43
|
$type: ids.IfAccountNewerThan,
|
|
@@ -66,6 +68,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
66
68
|
{
|
|
67
69
|
countryCode: 'US',
|
|
68
70
|
regionCode: 'SD',
|
|
71
|
+
minAccessAge: 13,
|
|
69
72
|
rules: [
|
|
70
73
|
{
|
|
71
74
|
$type: ids.IfAssuredOverAge,
|
|
@@ -86,6 +89,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
86
89
|
{
|
|
87
90
|
countryCode: 'US',
|
|
88
91
|
regionCode: 'WY',
|
|
92
|
+
minAccessAge: 13,
|
|
89
93
|
rules: [
|
|
90
94
|
{
|
|
91
95
|
$type: ids.IfAssuredOverAge,
|
|
@@ -106,6 +110,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
106
110
|
{
|
|
107
111
|
countryCode: 'US',
|
|
108
112
|
regionCode: 'OH',
|
|
113
|
+
minAccessAge: 13,
|
|
109
114
|
rules: [
|
|
110
115
|
{
|
|
111
116
|
$type: ids.IfAssuredOverAge,
|
|
@@ -126,6 +131,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
126
131
|
{
|
|
127
132
|
countryCode: 'US',
|
|
128
133
|
regionCode: 'MS',
|
|
134
|
+
minAccessAge: 18,
|
|
129
135
|
rules: [
|
|
130
136
|
{
|
|
131
137
|
$type: ids.IfAssuredOverAge,
|
|
@@ -141,6 +147,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
141
147
|
{
|
|
142
148
|
countryCode: 'US',
|
|
143
149
|
regionCode: 'VA',
|
|
150
|
+
minAccessAge: 16,
|
|
144
151
|
rules: [
|
|
145
152
|
{
|
|
146
153
|
$type: ids.IfAssuredOverAge,
|
|
@@ -161,6 +168,7 @@ export const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {
|
|
|
161
168
|
{
|
|
162
169
|
countryCode: 'US',
|
|
163
170
|
regionCode: 'TN',
|
|
171
|
+
minAccessAge: 18,
|
|
164
172
|
rules: [
|
|
165
173
|
{
|
|
166
174
|
$type: ids.IfAssuredOverAge,
|
package/src/hydration/actor.ts
CHANGED
|
@@ -160,10 +160,20 @@ export class ActorHydrator {
|
|
|
160
160
|
dids: string[],
|
|
161
161
|
opts: {
|
|
162
162
|
includeTakedowns?: boolean
|
|
163
|
+
/**
|
|
164
|
+
* The raw `HydrationCtx.includeTakedowns` value, independent of any
|
|
165
|
+
* special casing that may apply to `includeTakedowns` within this
|
|
166
|
+
* method.
|
|
167
|
+
*/
|
|
168
|
+
includeTakedownsBase?: boolean
|
|
163
169
|
skipCacheForDids?: string[]
|
|
164
170
|
} = {},
|
|
165
171
|
): Promise<Actors> {
|
|
166
|
-
const {
|
|
172
|
+
const {
|
|
173
|
+
includeTakedowns = false,
|
|
174
|
+
skipCacheForDids,
|
|
175
|
+
includeTakedownsBase = false,
|
|
176
|
+
} = opts
|
|
167
177
|
if (!dids.length) return new HydrationMap<Actor>()
|
|
168
178
|
const res = await this.dataplane.getActors({ dids, skipCacheForDids })
|
|
169
179
|
return dids.reduce((acc, did, i) => {
|
|
@@ -184,7 +194,7 @@ export class ActorHydrator {
|
|
|
184
194
|
: undefined
|
|
185
195
|
|
|
186
196
|
const status = actor.statusRecord
|
|
187
|
-
? parseRecord<StatusRecord>(actor.statusRecord,
|
|
197
|
+
? parseRecord<StatusRecord>(actor.statusRecord, includeTakedownsBase)
|
|
188
198
|
: undefined
|
|
189
199
|
|
|
190
200
|
const verifications = mapDefined(
|
|
@@ -80,7 +80,7 @@ export class HydrateCtx {
|
|
|
80
80
|
labelers = this.vals.labelers
|
|
81
81
|
viewer = this.vals.viewer !== null ? serviceRefToDid(this.vals.viewer) : null
|
|
82
82
|
includeTakedowns = this.vals.includeTakedowns
|
|
83
|
-
|
|
83
|
+
overrideIncludeTakedownsForActor = this.vals.overrideIncludeTakedownsForActor
|
|
84
84
|
include3pBlocks = this.vals.include3pBlocks
|
|
85
85
|
includeDebugField = this.vals.includeDebugField
|
|
86
86
|
featureGates: CheckedFeatureGatesMap = this.vals.featureGates || new Map()
|
|
@@ -99,7 +99,7 @@ export type HydrateCtxVals = {
|
|
|
99
99
|
labelers: ParsedLabelers
|
|
100
100
|
viewer: string | null
|
|
101
101
|
includeTakedowns?: boolean
|
|
102
|
-
|
|
102
|
+
overrideIncludeTakedownsForActor?: boolean
|
|
103
103
|
include3pBlocks?: boolean
|
|
104
104
|
includeDebugField?: boolean
|
|
105
105
|
featureGates?: CheckedFeatureGatesMap
|
|
@@ -228,10 +228,17 @@ export class Hydrator {
|
|
|
228
228
|
dids: string[],
|
|
229
229
|
ctx: HydrateCtx,
|
|
230
230
|
): Promise<HydrationState> {
|
|
231
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Special case here, we want to include takedowns in special cases, like
|
|
233
|
+
* `getProfile`, since we throw client-facing errors later in the pipeline.
|
|
234
|
+
*/
|
|
235
|
+
const includeTakedowns =
|
|
236
|
+
ctx.includeTakedowns || ctx.overrideIncludeTakedownsForActor
|
|
237
|
+
const includeTakedownsBase = ctx.includeTakedowns
|
|
232
238
|
const [actors, labels, profileViewersState] = await Promise.all([
|
|
233
239
|
this.actor.getActors(dids, {
|
|
234
240
|
includeTakedowns,
|
|
241
|
+
includeTakedownsBase,
|
|
235
242
|
skipCacheForDids: ctx.skipCacheForViewer,
|
|
236
243
|
}),
|
|
237
244
|
this.label.getLabelsForSubjects(labelSubjectsForDid(dids), ctx.labelers),
|
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -812,6 +812,14 @@ export const schemaDict = {
|
|
|
812
812
|
type: 'object',
|
|
813
813
|
required: ['status', 'record'],
|
|
814
814
|
properties: {
|
|
815
|
+
uri: {
|
|
816
|
+
type: 'string',
|
|
817
|
+
format: 'at-uri',
|
|
818
|
+
},
|
|
819
|
+
cid: {
|
|
820
|
+
type: 'string',
|
|
821
|
+
format: 'cid',
|
|
822
|
+
},
|
|
815
823
|
status: {
|
|
816
824
|
type: 'string',
|
|
817
825
|
description: 'The status for the account.',
|
|
@@ -1345,7 +1353,7 @@ export const schemaDict = {
|
|
|
1345
1353
|
configRegion: {
|
|
1346
1354
|
type: 'object',
|
|
1347
1355
|
description: 'The Age Assurance configuration for a specific region.',
|
|
1348
|
-
required: ['countryCode', 'rules'],
|
|
1356
|
+
required: ['countryCode', 'minAccessAge', 'rules'],
|
|
1349
1357
|
properties: {
|
|
1350
1358
|
countryCode: {
|
|
1351
1359
|
type: 'string',
|
|
@@ -1357,6 +1365,11 @@ export const schemaDict = {
|
|
|
1357
1365
|
description:
|
|
1358
1366
|
'The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country.',
|
|
1359
1367
|
},
|
|
1368
|
+
minAccessAge: {
|
|
1369
|
+
type: 'integer',
|
|
1370
|
+
description:
|
|
1371
|
+
'The minimum age (as a whole integer) required to use Bluesky in this region.',
|
|
1372
|
+
},
|
|
1360
1373
|
rules: {
|
|
1361
1374
|
type: 'array',
|
|
1362
1375
|
description:
|
|
@@ -652,6 +652,8 @@ export function validatePostInteractionSettingsPref<V>(v: V) {
|
|
|
652
652
|
|
|
653
653
|
export interface StatusView {
|
|
654
654
|
$type?: 'app.bsky.actor.defs#statusView'
|
|
655
|
+
uri?: string
|
|
656
|
+
cid?: string
|
|
655
657
|
/** The status for the account. */
|
|
656
658
|
status: 'app.bsky.actor.status#live' | (string & {})
|
|
657
659
|
record: { [_ in string]: unknown }
|
|
@@ -83,6 +83,8 @@ export interface ConfigRegion {
|
|
|
83
83
|
countryCode: string
|
|
84
84
|
/** The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country. */
|
|
85
85
|
regionCode?: string
|
|
86
|
+
/** The minimum age (as a whole integer) required to use Bluesky in this region. */
|
|
87
|
+
minAccessAge: number
|
|
86
88
|
/** The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item. */
|
|
87
89
|
rules: (
|
|
88
90
|
| $Typed<ConfigRegionRuleDefault>
|
package/src/views/index.ts
CHANGED
|
@@ -545,7 +545,8 @@ export class Views {
|
|
|
545
545
|
if (!actor?.status) return
|
|
546
546
|
|
|
547
547
|
const { status } = actor
|
|
548
|
-
const { record, sortedAt } = status
|
|
548
|
+
const { record, sortedAt, cid } = status
|
|
549
|
+
const uri = AtUri.make(did, ids.AppBskyActorStatus, 'self').toString()
|
|
549
550
|
|
|
550
551
|
const minDuration = 5 * MINUTE
|
|
551
552
|
const maxDuration = 4 * HOUR
|
|
@@ -564,6 +565,8 @@ export class Views {
|
|
|
564
565
|
const isActive = expiresAtMs ? expiresAtMs > Date.now() : undefined
|
|
565
566
|
|
|
566
567
|
return {
|
|
568
|
+
uri,
|
|
569
|
+
cid,
|
|
567
570
|
record: record,
|
|
568
571
|
status: record.status,
|
|
569
572
|
embed: isExternalEmbed(record.embed)
|
|
@@ -703,6 +703,7 @@ Object {
|
|
|
703
703
|
|
|
704
704
|
exports[`pds profile views status returns active status when within the duration 1`] = `
|
|
705
705
|
Object {
|
|
706
|
+
"cid": "cids(0)",
|
|
706
707
|
"embed": Object {
|
|
707
708
|
"$type": "app.bsky.embed.external#view",
|
|
708
709
|
"external": Object {
|
|
@@ -728,11 +729,13 @@ Object {
|
|
|
728
729
|
"status": "app.bsky.actor.status#live",
|
|
729
730
|
},
|
|
730
731
|
"status": "app.bsky.actor.status#live",
|
|
732
|
+
"uri": "record(0)",
|
|
731
733
|
}
|
|
732
734
|
`;
|
|
733
735
|
|
|
734
736
|
exports[`pds profile views status when outside the duration returns inactive status 1`] = `
|
|
735
737
|
Object {
|
|
738
|
+
"cid": "cids(0)",
|
|
736
739
|
"embed": Object {
|
|
737
740
|
"$type": "app.bsky.embed.external#view",
|
|
738
741
|
"external": Object {
|
|
@@ -741,11 +744,11 @@ Object {
|
|
|
741
744
|
"uri": "https://example.com",
|
|
742
745
|
},
|
|
743
746
|
},
|
|
744
|
-
"expiresAt": "
|
|
747
|
+
"expiresAt": "1970-01-01T00:00:00.000Z",
|
|
745
748
|
"isActive": false,
|
|
746
749
|
"record": Object {
|
|
747
750
|
"$type": "app.bsky.actor.status",
|
|
748
|
-
"createdAt": "
|
|
751
|
+
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
749
752
|
"durationMinutes": 10,
|
|
750
753
|
"embed": Object {
|
|
751
754
|
"$type": "app.bsky.embed.external",
|
|
@@ -758,5 +761,6 @@ Object {
|
|
|
758
761
|
"status": "app.bsky.actor.status#live",
|
|
759
762
|
},
|
|
760
763
|
"status": "app.bsky.actor.status#live",
|
|
764
|
+
"uri": "record(0)",
|
|
761
765
|
}
|
|
762
766
|
`;
|
|
@@ -33,6 +33,7 @@ jest.mock('../../dist/api/age-assurance/const.js', () => {
|
|
|
33
33
|
{
|
|
34
34
|
countryCode: 'AA',
|
|
35
35
|
regionCode: undefined,
|
|
36
|
+
minAccessAge: 13,
|
|
36
37
|
rules: [
|
|
37
38
|
{
|
|
38
39
|
$type: ruleIds.IfAssuredOverAge,
|
|
@@ -48,6 +49,7 @@ jest.mock('../../dist/api/age-assurance/const.js', () => {
|
|
|
48
49
|
{
|
|
49
50
|
countryCode: 'BB',
|
|
50
51
|
regionCode: undefined,
|
|
52
|
+
minAccessAge: 13,
|
|
51
53
|
rules: [
|
|
52
54
|
{
|
|
53
55
|
$type: ruleIds.IfAssuredOverAge,
|
|
@@ -490,7 +490,47 @@ describe('pds profile views', () => {
|
|
|
490
490
|
)
|
|
491
491
|
|
|
492
492
|
// Doesn't need `forSnapshot` because the dates are already mocked.
|
|
493
|
-
expect(data.status).toMatchSnapshot()
|
|
493
|
+
expect(forSnapshot(data.status)).toMatchSnapshot()
|
|
494
|
+
})
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
describe('when taken down', () => {
|
|
498
|
+
it('it does not return the live status', async () => {
|
|
499
|
+
const res = await sc.agent.com.atproto.repo.putRecord(
|
|
500
|
+
{
|
|
501
|
+
repo: alice,
|
|
502
|
+
collection: ids.AppBskyActorStatus,
|
|
503
|
+
rkey: 'self',
|
|
504
|
+
record: {
|
|
505
|
+
status: 'app.bsky.actor.status#live',
|
|
506
|
+
embed,
|
|
507
|
+
durationMinutes: 10,
|
|
508
|
+
createdAt: new Date().toISOString(),
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
headers: sc.getHeaders(alice),
|
|
513
|
+
encoding: 'application/json',
|
|
514
|
+
},
|
|
515
|
+
)
|
|
516
|
+
await network.processAll()
|
|
517
|
+
|
|
518
|
+
await network.bsky.ctx.dataplane.takedownRecord({
|
|
519
|
+
recordUri: res.data.uri,
|
|
520
|
+
})
|
|
521
|
+
await network.processAll()
|
|
522
|
+
|
|
523
|
+
const { data } = await agent.api.app.bsky.actor.getProfile(
|
|
524
|
+
{ actor: alice },
|
|
525
|
+
{
|
|
526
|
+
headers: await network.serviceHeaders(
|
|
527
|
+
alice,
|
|
528
|
+
ids.AppBskyActorGetProfile,
|
|
529
|
+
),
|
|
530
|
+
},
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
expect(forSnapshot(data.status)).toBeUndefined()
|
|
494
534
|
})
|
|
495
535
|
})
|
|
496
536
|
})
|