Version packages (#2706)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
2bdf75d7a6
commit
3940733bf0
.changeset
brown-dryers-fail.mdearly-pugs-hug.mdfriendly-bikes-share.mdfunny-schools-watch.mdhappy-socks-smell.mdhonest-bears-bake.mdhonest-hornets-approve.mdnew-olives-sparkle.mdpurple-pans-shout.mdrare-feet-happen.mdsilver-buckets-hope.mdtame-pans-care.mdyellow-rocks-drum.md
packages
api
aws
bsky
dev-env
did
internal
did-resolver
handle-resolver-node
handle-resolver
identity-resolver
lex-cli
lexicon
oauth
jwk-jose
jwk-webcrypto
oauth-client-browser
oauth-client-node
oauth-client
oauth-provider
oauth-types
ozone
pds
repo
xrpc-server
xrpc
@ -1,6 +0,0 @@
|
||||
---
|
||||
"@atproto/oauth-client": patch
|
||||
"@atproto/jwk-jose": patch
|
||||
---
|
||||
|
||||
Misc fixes for confidential client usage
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/jwk-jose": patch
|
||||
---
|
||||
|
||||
Allow importing JoseKey without specifying a kid
|
@ -1,7 +0,0 @@
|
||||
---
|
||||
"@atproto/oauth-client-node": patch
|
||||
"@atproto/oauth-client": patch
|
||||
"@atproto/oauth-types": patch
|
||||
---
|
||||
|
||||
Better implement aptroto OAuth spec
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto-labs/handle-resolver": patch
|
||||
---
|
||||
|
||||
Updated to use "AtprotoDid" utils from @atproto/did
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/did": patch
|
||||
---
|
||||
|
||||
Expose atproto specific types and utilities
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
Update tests according to new @atproto/xrpc implementation
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/lexicon": patch
|
||||
---
|
||||
|
||||
Add the ability to instantiate a Lexicon from an iterable, and to use a Lexicon as iterable.
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/lexicon": patch
|
||||
---
|
||||
|
||||
Remove internal circular dependency.
|
@ -1,581 +0,0 @@
|
||||
---
|
||||
"@atproto/xrpc": minor
|
||||
"@atproto/api": minor
|
||||
---
|
||||
|
||||
## Motivation
|
||||
|
||||
The motivation for these changes is the need to make the `@atproto/api` package
|
||||
compatible with OAuth session management. We don't have OAuth client support
|
||||
"launched" and documented quite yet, so you can keep using the current app
|
||||
password authentication system. When we do "launch" OAuth support and begin
|
||||
encouraging its usage in the near future (see the [OAuth
|
||||
Roadmap](https://github.com/bluesky-social/atproto/discussions/2656)), these
|
||||
changes will make it easier to migrate.
|
||||
|
||||
In addition, the redesigned session management system fixes a bug that could
|
||||
cause the session data to become invalid when Agent clones are created (e.g.
|
||||
using `agent.withProxy()`).
|
||||
|
||||
## New Features
|
||||
|
||||
We've restructured the `XrpcClient` HTTP fetch handler to be specified during
|
||||
the instantiation of the XRPC client, through the constructor, instead of using
|
||||
a default implementation (which was statically defined).
|
||||
|
||||
With this refactor, the XRPC client is now more modular and reusable. Session
|
||||
management, retries, cryptographic signing, and other request-specific logic can
|
||||
be implemented in the fetch handler itself rather than by the calling code.
|
||||
|
||||
A new abstract class named `Agent`, has been added to `@atproto/api`. This class
|
||||
will be the base class for all Bluesky agents classes in the `@atproto`
|
||||
ecosystem. It is meant to be extended by implementations that provide session
|
||||
management and fetch handling.
|
||||
|
||||
As you adapt your code to these changes, make sure to use the `Agent` type
|
||||
wherever you expect to receive an agent, and use the `AtpAgent` type (class)
|
||||
only to instantiate your client. The reason for this is to be forward compatible
|
||||
with the OAuth agent implementation that will also extend `Agent`, and not
|
||||
`AtpAgent`.
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from '@atproto/api'
|
||||
|
||||
async function setupAgent(service: string, username: string, password: string): Promise<Agent> {
|
||||
const agent = new AtpAgent({
|
||||
service,
|
||||
persistSession: (evt, session) => {
|
||||
// handle session update
|
||||
},
|
||||
})
|
||||
|
||||
await agent.login(username, password)
|
||||
|
||||
return agent
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent } from '@atproto/api'
|
||||
|
||||
async function doStuffWithAgent(agent: Agent, arg: string) {
|
||||
return agent.resolveHandle(arg)
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from '@atproto/api'
|
||||
|
||||
class MyClass {
|
||||
agent: Agent
|
||||
|
||||
constructor () {
|
||||
this.agent = new AtpAgent()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Breaking changes
|
||||
|
||||
Most of the changes introduced in this version are backward-compatible. However,
|
||||
there are a couple of breaking changes you should be aware of:
|
||||
|
||||
- Customizing `fetch`: The ability to customize the `fetch: FetchHandler`
|
||||
property of `@atproto/xrpc`'s `Client` and `@atproto/api`'s `AtpAgent` classes
|
||||
has been removed. Previously, the `fetch` property could be set to a function
|
||||
that would be used as the fetch handler for that instance, and was initialized
|
||||
to a default fetch handler. That property is still accessible in a read-only
|
||||
fashion through the `fetchHandler` property and can only be set during the
|
||||
instance creation. Attempting to set/get the `fetch` property will now result
|
||||
in an error.
|
||||
- The `fetch()` method, as well as WhatWG compliant `Request` and `Headers`
|
||||
constructors, must be globally available in your environment. Use a polyfill
|
||||
if necessary.
|
||||
|
||||
- The `AtpBaseClient` has been removed. The `AtpServiceClient` has been renamed
|
||||
`AtpBaseClient`. Any code using either of these classes will need to be
|
||||
updated.
|
||||
|
||||
- Instead of *wrapping* an `XrpcClient` in its `xrpc` property, the
|
||||
`AtpBaseClient` (formerly `AtpServiceClient`) class - created through
|
||||
`lex-cli` - now *extends* the `XrpcClient` class. This means that a client
|
||||
instance now passes the `instanceof XrpcClient` check. The `xrpc` property now
|
||||
returns the instance itself and has been deprecated.
|
||||
|
||||
- `setSessionPersistHandler` is no longer available on the `AtpAgent` or
|
||||
`BskyAgent` classes. The session handler can only be set though the
|
||||
`persistSession` options of the `AtpAgent` constructor.
|
||||
|
||||
- The new class hierarchy is as follows:
|
||||
- `BskyAgent` extends `AtpAgent`: but add no functionality (hence its
|
||||
deprecation).
|
||||
- `AtpAgent` extends `Agent`: adds password based session management.
|
||||
- `Agent` extends `AtpBaseClient`: this abstract class that adds syntactic sugar
|
||||
methods `app.bsky` lexicons. It also adds abstract session management
|
||||
methods and adds atproto specific utilities
|
||||
(`labelers` & `proxy` headers, cloning capability)
|
||||
- `AtpBaseClient` extends `XrpcClient`: automatically code that adds fully
|
||||
typed lexicon defined namespaces (`instance.app.bsky.feed.getPosts()`) to
|
||||
the `XrpcClient`.
|
||||
- `XrpcClient` is the base class.
|
||||
|
||||
## Non-breaking changes
|
||||
|
||||
- The `com.*` and `app.*` namespaces have been made directly available to every
|
||||
`Agent` instances.
|
||||
|
||||
## Deprecations
|
||||
|
||||
- The default export of the `@atproto/xrpc` package has been deprecated. Use
|
||||
named exports instead.
|
||||
|
||||
- The `Client` and `ServiceClient` classes are now deprecated. They are replaced by a single `XrpcClient` class.
|
||||
|
||||
- The default export of the `@atproto/api` package has been deprecated. Use
|
||||
named exports instead.
|
||||
|
||||
- The `BskyAgent` has been deprecated. Use the `AtpAgent` class instead.
|
||||
|
||||
- The `xrpc` property of the `AtpClient` instances has been deprecated. The
|
||||
instance itself should be used as the XRPC client.
|
||||
|
||||
- The `api` property of the `AtpAgent` and `BskyAgent` instances has been
|
||||
deprecated. Use the instance itself instead.
|
||||
|
||||
## Migration
|
||||
|
||||
### The `@atproto/api` package
|
||||
|
||||
If you were relying on the `AtpBaseClient` solely to perform validation, use
|
||||
this:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from '@atproto/api'
|
||||
|
||||
const baseClient = new AtpBaseClient()
|
||||
|
||||
baseClient.xrpc.lex.assertValidXrpcMessage('io.example.doStuff', {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { lexicons } from '@atproto/api'
|
||||
|
||||
lexicons.assertValidXrpcMessage('io.example.doStuff', {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you are extending the `BskyAgent` to perform custom `session` manipulation, define your own `Agent` subclass instead:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from '@atproto/api'
|
||||
|
||||
class MyAgent extends BskyAgent {
|
||||
private accessToken?: string
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.accessToken = 'my-access-jwt'
|
||||
}
|
||||
|
||||
async doStuff() {
|
||||
return this.call('io.example.doStuff', {
|
||||
headers: {
|
||||
'Authorization': this.accessToken && `Bearer ${this.accessToken}`
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { Agent } from '@atproto/api'
|
||||
|
||||
class MyAgent extends Agent {
|
||||
private accessToken?: string
|
||||
public did?: string
|
||||
|
||||
constructor(private readonly service: string | URL) {
|
||||
super({
|
||||
service,
|
||||
headers: {
|
||||
Authorization: () =>
|
||||
this.accessToken ? `Bearer ${this.accessToken}` : null,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
clone(): MyAgent {
|
||||
const agent = new MyAgent(this.service)
|
||||
agent.accessToken = this.accessToken
|
||||
agent.did = this.did
|
||||
return this.copyInto(agent)
|
||||
}
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.did = 'did:example:123'
|
||||
this.accessToken = 'my-access-jwt'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
If you are monkey patching the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from '@atproto/api'
|
||||
import { RateLimitThreshold } from "rate-limit-threshold"
|
||||
|
||||
const agent = new BskyAgent()
|
||||
const limiter = new RateLimitThreshold(
|
||||
3000,
|
||||
300_000
|
||||
)
|
||||
|
||||
const origCall = agent.api.xrpc.call
|
||||
agent.api.xrpc.call = async function (...args) {
|
||||
await limiter.wait()
|
||||
return origCall.call(this, ...args)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from '@atproto/api'
|
||||
import { RateLimitThreshold } from "rate-limit-threshold"
|
||||
|
||||
class LimitedAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch: typeof globalThis.fetch = options.fetch ?? globalThis.fetch
|
||||
const limiter = new RateLimitThreshold(
|
||||
3000,
|
||||
300_000
|
||||
)
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (...args) => {
|
||||
await limiter.wait()
|
||||
return fetch(...args)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you configure a static `fetch` handler on the `BskyAgent` class - for example
|
||||
to modify the headers of every request - you can now do this by providing your
|
||||
own `fetch` function:
|
||||
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent, defaultFetchHandler } from '@atproto/api'
|
||||
|
||||
BskyAgent.configure({
|
||||
fetch: async (httpUri, httpMethod, httpHeaders, httpReqBody) => {
|
||||
|
||||
const ua = httpHeaders["User-Agent"]
|
||||
|
||||
httpHeaders["User-Agent"] = ua ? `${ua} ${userAgent}` : userAgent
|
||||
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from '@atproto/api'
|
||||
|
||||
class MyAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch = options.fetch ?? globalThis.fetch
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (url, init) => {
|
||||
const headers = new Headers(init.headers)
|
||||
|
||||
const ua = headersList.get("User-Agent")
|
||||
headersList.set("User-Agent", ua ? `${ua} ${userAgent}` : userAgent)
|
||||
|
||||
return fetch(url, { ...init, headers })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<!-- <table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// before
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// after
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table> -->
|
||||
|
||||
|
||||
### The `@atproto/xrpc` package
|
||||
|
||||
The `Client` and `ServiceClient` classes are now **deprecated**. If you need a
|
||||
lexicon based client, you should update the code to use the `XrpcClient` class
|
||||
instead.
|
||||
|
||||
The deprecated `ServiceClient` class now extends the new `XrpcClient` class.
|
||||
Because of this, the `fetch` `FetchHandler` can no longer be configured on the
|
||||
`Client` instances (including the default export of the package). If you are not
|
||||
relying on the `fetch` `FetchHandler`, the new changes should have no impact on
|
||||
your code. Beware that the deprecated classes will eventually be removed in a
|
||||
future version.
|
||||
|
||||
Since its use has completely changed, the `FetchHandler` type has also
|
||||
completely changed. The new `FetchHandler` type is now a function that receives
|
||||
a `url` pathname and a `RequestInit` object and returns a `Promise<Response>`.
|
||||
This function is responsible for making the actual request to the server.
|
||||
|
||||
```ts
|
||||
export type FetchHandler = (
|
||||
this: void,
|
||||
/**
|
||||
* The URL (pathname + query parameters) to make the request to, without the
|
||||
* origin. The origin (protocol, hostname, and port) must be added by this
|
||||
* {@link FetchHandler}, typically based on authentication or other factors.
|
||||
*/
|
||||
url: string,
|
||||
init: RequestInit,
|
||||
) => Promise<Response>
|
||||
```
|
||||
|
||||
A noticeable change that has been introduced is that the `uri` field of the
|
||||
`ServiceClient` class has _not_ been ported to the new `XrpcClient` class. It is
|
||||
now the responsibility of the `FetchHandler` to determine the full URL to make
|
||||
the request to. The same goes for the `headers`, which should now be set through
|
||||
the `FetchHandler` function.
|
||||
|
||||
If you _do_ rely on the legacy `Client.fetch` property to perform custom logic
|
||||
upon request, you will need to migrate your code to use the new `XrpcClient`
|
||||
class. The `XrpcClient` class has a similar API to the old `ServiceClient`
|
||||
class, but with a few differences:
|
||||
|
||||
- The `Client` + `ServiceClient` duality was removed in favor of a single
|
||||
`XrpcClient` class. This means that:
|
||||
|
||||
- There no longer exists a centralized lexicon registry. If you need a global
|
||||
lexicon registry, you can maintain one yourself using a `new Lexicons` (from
|
||||
`@atproto/lexicon`).
|
||||
|
||||
- The `FetchHandler` is no longer a statically defined property of the
|
||||
`Client` class. Instead, it is passed as an argument to the `XrpcClient`
|
||||
constructor.
|
||||
|
||||
- The `XrpcClient` constructor now requires a `FetchHandler` function as the
|
||||
first argument, and an optional `Lexicon` instance as the second argument.
|
||||
|
||||
- The `setHeader` and `unsetHeader` methods were not ported to the new
|
||||
`XrpcClient` class. If you need to set or unset headers, you should do so in
|
||||
the `FetchHandler` function provided in the constructor arg.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import client, { defaultFetchHandler } from '@atproto/xrpc'
|
||||
|
||||
client.fetch = function (
|
||||
httpUri: string,
|
||||
httpMethod: string,
|
||||
httpHeaders: Headers,
|
||||
httpReqBody: unknown,
|
||||
) {
|
||||
// Custom logic here
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody)
|
||||
}
|
||||
|
||||
client.addLexicon({
|
||||
lexicon: 1,
|
||||
id: 'io.example.doStuff',
|
||||
defs: {},
|
||||
})
|
||||
|
||||
const instance = client.service('http://my-service.com')
|
||||
|
||||
instance.setHeader('my-header', 'my-value')
|
||||
|
||||
await instance.call('io.example.doStuff')
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from '@atproto/xrpc'
|
||||
|
||||
const instance = new XrpcClient(
|
||||
async (url, init) => {
|
||||
const headers = new Headers(init.headers)
|
||||
|
||||
headers.set('my-header', 'my-value')
|
||||
|
||||
// Custom logic here
|
||||
|
||||
const fullUrl = new URL(url, 'http://my-service.com')
|
||||
|
||||
return fetch(fullUrl, { ...init, headers })
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: 'io.example.doStuff',
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
await instance.call('io.example.doStuff')
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If your fetch handler does not require any "custom logic", and all you need is
|
||||
an `XrpcClient` that makes its HTTP requests towards a static service URL, the
|
||||
previous example can be simplified to:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from '@atproto/xrpc'
|
||||
|
||||
const instance = new XrpcClient('http://my-service.com', [
|
||||
{
|
||||
lexicon: 1,
|
||||
id: 'io.example.doStuff',
|
||||
defs: {},
|
||||
},
|
||||
])
|
||||
```
|
||||
|
||||
If you need to add static headers to all requests, you can instead instantiate
|
||||
the `XrpcClient` as follows:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from '@atproto/xrpc'
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: 'http://my-service.com',
|
||||
headers: {
|
||||
'my-header': 'my-value',
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: 'io.example.doStuff',
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
If you need the headers or service url to be dynamic, you can define them using
|
||||
functions:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from '@atproto/xrpc'
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: () => 'http://my-service.com',
|
||||
headers: {
|
||||
'my-header': () => 'my-value',
|
||||
'my-ignored-header': () => null, // ignored
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: 'io.example.doStuff',
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
)
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
"@atproto/xrpc": minor
|
||||
"@atproto/api": minor
|
||||
---
|
||||
|
||||
Add the ability to use `fetch()` compatible `BodyInit` body when making XRPC calls.
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/lex-cli": minor
|
||||
---
|
||||
|
||||
The generated client implementation uses the new `XrpcClient` class from `@atproto/xrpc`, instead of the deprecated `Client` and `ServiceClient` class.
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto/oauth-provider": patch
|
||||
---
|
||||
|
||||
Remove unused file
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
"@atproto-labs/identity-resolver": patch
|
||||
---
|
||||
|
||||
Expose getDocumentFromDid and getDocumentFromHandle as public methods on IdentityResolver
|
@ -1,5 +1,575 @@
|
||||
# @atproto/api
|
||||
|
||||
## 0.13.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - ## Motivation
|
||||
|
||||
The motivation for these changes is the need to make the `@atproto/api` package
|
||||
compatible with OAuth session management. We don't have OAuth client support
|
||||
"launched" and documented quite yet, so you can keep using the current app
|
||||
password authentication system. When we do "launch" OAuth support and begin
|
||||
encouraging its usage in the near future (see the [OAuth
|
||||
Roadmap](https://github.com/bluesky-social/atproto/discussions/2656)), these
|
||||
changes will make it easier to migrate.
|
||||
|
||||
In addition, the redesigned session management system fixes a bug that could
|
||||
cause the session data to become invalid when Agent clones are created (e.g.
|
||||
using `agent.withProxy()`).
|
||||
|
||||
## New Features
|
||||
|
||||
We've restructured the `XrpcClient` HTTP fetch handler to be specified during
|
||||
the instantiation of the XRPC client, through the constructor, instead of using
|
||||
a default implementation (which was statically defined).
|
||||
|
||||
With this refactor, the XRPC client is now more modular and reusable. Session
|
||||
management, retries, cryptographic signing, and other request-specific logic can
|
||||
be implemented in the fetch handler itself rather than by the calling code.
|
||||
|
||||
A new abstract class named `Agent`, has been added to `@atproto/api`. This class
|
||||
will be the base class for all Bluesky agents classes in the `@atproto`
|
||||
ecosystem. It is meant to be extended by implementations that provide session
|
||||
management and fetch handling.
|
||||
|
||||
As you adapt your code to these changes, make sure to use the `Agent` type
|
||||
wherever you expect to receive an agent, and use the `AtpAgent` type (class)
|
||||
only to instantiate your client. The reason for this is to be forward compatible
|
||||
with the OAuth agent implementation that will also extend `Agent`, and not
|
||||
`AtpAgent`.
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from "@atproto/api";
|
||||
|
||||
async function setupAgent(
|
||||
service: string,
|
||||
username: string,
|
||||
password: string,
|
||||
): Promise<Agent> {
|
||||
const agent = new AtpAgent({
|
||||
service,
|
||||
persistSession: (evt, session) => {
|
||||
// handle session update
|
||||
},
|
||||
});
|
||||
|
||||
await agent.login(username, password);
|
||||
|
||||
return agent;
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent } from "@atproto/api";
|
||||
|
||||
async function doStuffWithAgent(agent: Agent, arg: string) {
|
||||
return agent.resolveHandle(arg);
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from "@atproto/api";
|
||||
|
||||
class MyClass {
|
||||
agent: Agent;
|
||||
|
||||
constructor() {
|
||||
this.agent = new AtpAgent();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Breaking changes
|
||||
|
||||
Most of the changes introduced in this version are backward-compatible. However,
|
||||
there are a couple of breaking changes you should be aware of:
|
||||
|
||||
- Customizing `fetch`: The ability to customize the `fetch: FetchHandler`
|
||||
property of `@atproto/xrpc`'s `Client` and `@atproto/api`'s `AtpAgent` classes
|
||||
has been removed. Previously, the `fetch` property could be set to a function
|
||||
that would be used as the fetch handler for that instance, and was initialized
|
||||
to a default fetch handler. That property is still accessible in a read-only
|
||||
fashion through the `fetchHandler` property and can only be set during the
|
||||
instance creation. Attempting to set/get the `fetch` property will now result
|
||||
in an error.
|
||||
- The `fetch()` method, as well as WhatWG compliant `Request` and `Headers`
|
||||
constructors, must be globally available in your environment. Use a polyfill
|
||||
if necessary.
|
||||
- The `AtpBaseClient` has been removed. The `AtpServiceClient` has been renamed
|
||||
`AtpBaseClient`. Any code using either of these classes will need to be
|
||||
updated.
|
||||
- Instead of _wrapping_ an `XrpcClient` in its `xrpc` property, the
|
||||
`AtpBaseClient` (formerly `AtpServiceClient`) class - created through
|
||||
`lex-cli` - now _extends_ the `XrpcClient` class. This means that a client
|
||||
instance now passes the `instanceof XrpcClient` check. The `xrpc` property now
|
||||
returns the instance itself and has been deprecated.
|
||||
- `setSessionPersistHandler` is no longer available on the `AtpAgent` or
|
||||
`BskyAgent` classes. The session handler can only be set though the
|
||||
`persistSession` options of the `AtpAgent` constructor.
|
||||
- The new class hierarchy is as follows:
|
||||
- `BskyAgent` extends `AtpAgent`: but add no functionality (hence its
|
||||
deprecation).
|
||||
- `AtpAgent` extends `Agent`: adds password based session management.
|
||||
- `Agent` extends `AtpBaseClient`: this abstract class that adds syntactic sugar
|
||||
methods `app.bsky` lexicons. It also adds abstract session management
|
||||
methods and adds atproto specific utilities
|
||||
(`labelers` & `proxy` headers, cloning capability)
|
||||
- `AtpBaseClient` extends `XrpcClient`: automatically code that adds fully
|
||||
typed lexicon defined namespaces (`instance.app.bsky.feed.getPosts()`) to
|
||||
the `XrpcClient`.
|
||||
- `XrpcClient` is the base class.
|
||||
|
||||
## Non-breaking changes
|
||||
|
||||
- The `com.*` and `app.*` namespaces have been made directly available to every
|
||||
`Agent` instances.
|
||||
|
||||
## Deprecations
|
||||
|
||||
- The default export of the `@atproto/xrpc` package has been deprecated. Use
|
||||
named exports instead.
|
||||
- The `Client` and `ServiceClient` classes are now deprecated. They are replaced by a single `XrpcClient` class.
|
||||
- The default export of the `@atproto/api` package has been deprecated. Use
|
||||
named exports instead.
|
||||
- The `BskyAgent` has been deprecated. Use the `AtpAgent` class instead.
|
||||
- The `xrpc` property of the `AtpClient` instances has been deprecated. The
|
||||
instance itself should be used as the XRPC client.
|
||||
- The `api` property of the `AtpAgent` and `BskyAgent` instances has been
|
||||
deprecated. Use the instance itself instead.
|
||||
|
||||
## Migration
|
||||
|
||||
### The `@atproto/api` package
|
||||
|
||||
If you were relying on the `AtpBaseClient` solely to perform validation, use
|
||||
this:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from "@atproto/api";
|
||||
|
||||
const baseClient = new AtpBaseClient();
|
||||
|
||||
baseClient.xrpc.lex.assertValidXrpcMessage("io.example.doStuff", {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { lexicons } from "@atproto/api";
|
||||
|
||||
lexicons.assertValidXrpcMessage("io.example.doStuff", {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you are extending the `BskyAgent` to perform custom `session` manipulation, define your own `Agent` subclass instead:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from "@atproto/api";
|
||||
|
||||
class MyAgent extends BskyAgent {
|
||||
private accessToken?: string;
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.accessToken = "my-access-jwt";
|
||||
}
|
||||
|
||||
async doStuff() {
|
||||
return this.call("io.example.doStuff", {
|
||||
headers: {
|
||||
Authorization: this.accessToken && `Bearer ${this.accessToken}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { Agent } from "@atproto/api";
|
||||
|
||||
class MyAgent extends Agent {
|
||||
private accessToken?: string;
|
||||
public did?: string;
|
||||
|
||||
constructor(private readonly service: string | URL) {
|
||||
super({
|
||||
service,
|
||||
headers: {
|
||||
Authorization: () =>
|
||||
this.accessToken ? `Bearer ${this.accessToken}` : null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
clone(): MyAgent {
|
||||
const agent = new MyAgent(this.service);
|
||||
agent.accessToken = this.accessToken;
|
||||
agent.did = this.did;
|
||||
return this.copyInto(agent);
|
||||
}
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.did = "did:example:123";
|
||||
this.accessToken = "my-access-jwt";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you are monkey patching the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from "@atproto/api";
|
||||
import { RateLimitThreshold } from "rate-limit-threshold";
|
||||
|
||||
const agent = new BskyAgent();
|
||||
const limiter = new RateLimitThreshold(3000, 300_000);
|
||||
|
||||
const origCall = agent.api.xrpc.call;
|
||||
agent.api.xrpc.call = async function (...args) {
|
||||
await limiter.wait();
|
||||
return origCall.call(this, ...args);
|
||||
};
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from "@atproto/api";
|
||||
import { RateLimitThreshold } from "rate-limit-threshold";
|
||||
|
||||
class LimitedAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch: typeof globalThis.fetch = options.fetch ?? globalThis.fetch;
|
||||
const limiter = new RateLimitThreshold(3000, 300_000);
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (...args) => {
|
||||
await limiter.wait();
|
||||
return fetch(...args);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you configure a static `fetch` handler on the `BskyAgent` class - for example
|
||||
to modify the headers of every request - you can now do this by providing your
|
||||
own `fetch` function:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent, defaultFetchHandler } from "@atproto/api";
|
||||
|
||||
BskyAgent.configure({
|
||||
fetch: async (httpUri, httpMethod, httpHeaders, httpReqBody) => {
|
||||
const ua = httpHeaders["User-Agent"];
|
||||
|
||||
httpHeaders["User-Agent"] = ua ? `${ua} ${userAgent}` : userAgent;
|
||||
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from "@atproto/api";
|
||||
|
||||
class MyAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch = options.fetch ?? globalThis.fetch;
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (url, init) => {
|
||||
const headers = new Headers(init.headers);
|
||||
|
||||
const ua = headersList.get("User-Agent");
|
||||
headersList.set("User-Agent", ua ? `${ua} ${userAgent}` : userAgent);
|
||||
|
||||
return fetch(url, { ...init, headers });
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- <table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// before
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// after
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table> -->
|
||||
|
||||
### The `@atproto/xrpc` package
|
||||
|
||||
The `Client` and `ServiceClient` classes are now **deprecated**. If you need a
|
||||
lexicon based client, you should update the code to use the `XrpcClient` class
|
||||
instead.
|
||||
|
||||
The deprecated `ServiceClient` class now extends the new `XrpcClient` class.
|
||||
Because of this, the `fetch` `FetchHandler` can no longer be configured on the
|
||||
`Client` instances (including the default export of the package). If you are not
|
||||
relying on the `fetch` `FetchHandler`, the new changes should have no impact on
|
||||
your code. Beware that the deprecated classes will eventually be removed in a
|
||||
future version.
|
||||
|
||||
Since its use has completely changed, the `FetchHandler` type has also
|
||||
completely changed. The new `FetchHandler` type is now a function that receives
|
||||
a `url` pathname and a `RequestInit` object and returns a `Promise<Response>`.
|
||||
This function is responsible for making the actual request to the server.
|
||||
|
||||
```ts
|
||||
export type FetchHandler = (
|
||||
this: void,
|
||||
/**
|
||||
* The URL (pathname + query parameters) to make the request to, without the
|
||||
* origin. The origin (protocol, hostname, and port) must be added by this
|
||||
* {@link FetchHandler}, typically based on authentication or other factors.
|
||||
*/
|
||||
url: string,
|
||||
init: RequestInit,
|
||||
) => Promise<Response>;
|
||||
```
|
||||
|
||||
A noticeable change that has been introduced is that the `uri` field of the
|
||||
`ServiceClient` class has _not_ been ported to the new `XrpcClient` class. It is
|
||||
now the responsibility of the `FetchHandler` to determine the full URL to make
|
||||
the request to. The same goes for the `headers`, which should now be set through
|
||||
the `FetchHandler` function.
|
||||
|
||||
If you _do_ rely on the legacy `Client.fetch` property to perform custom logic
|
||||
upon request, you will need to migrate your code to use the new `XrpcClient`
|
||||
class. The `XrpcClient` class has a similar API to the old `ServiceClient`
|
||||
class, but with a few differences:
|
||||
|
||||
- The `Client` + `ServiceClient` duality was removed in favor of a single
|
||||
`XrpcClient` class. This means that:
|
||||
|
||||
- There no longer exists a centralized lexicon registry. If you need a global
|
||||
lexicon registry, you can maintain one yourself using a `new Lexicons` (from
|
||||
`@atproto/lexicon`).
|
||||
- The `FetchHandler` is no longer a statically defined property of the
|
||||
`Client` class. Instead, it is passed as an argument to the `XrpcClient`
|
||||
constructor.
|
||||
|
||||
- The `XrpcClient` constructor now requires a `FetchHandler` function as the
|
||||
first argument, and an optional `Lexicon` instance as the second argument.
|
||||
- The `setHeader` and `unsetHeader` methods were not ported to the new
|
||||
`XrpcClient` class. If you need to set or unset headers, you should do so in
|
||||
the `FetchHandler` function provided in the constructor arg.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import client, { defaultFetchHandler } from "@atproto/xrpc";
|
||||
|
||||
client.fetch = function (
|
||||
httpUri: string,
|
||||
httpMethod: string,
|
||||
httpHeaders: Headers,
|
||||
httpReqBody: unknown,
|
||||
) {
|
||||
// Custom logic here
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody);
|
||||
};
|
||||
|
||||
client.addLexicon({
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
});
|
||||
|
||||
const instance = client.service("http://my-service.com");
|
||||
|
||||
instance.setHeader("my-header", "my-value");
|
||||
|
||||
await instance.call("io.example.doStuff");
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
async (url, init) => {
|
||||
const headers = new Headers(init.headers);
|
||||
|
||||
headers.set("my-header", "my-value");
|
||||
|
||||
// Custom logic here
|
||||
|
||||
const fullUrl = new URL(url, "http://my-service.com");
|
||||
|
||||
return fetch(fullUrl, { ...init, headers });
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
await instance.call("io.example.doStuff");
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If your fetch handler does not require any "custom logic", and all you need is
|
||||
an `XrpcClient` that makes its HTTP requests towards a static service URL, the
|
||||
previous example can be simplified to:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient("http://my-service.com", [
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
]);
|
||||
```
|
||||
|
||||
If you need to add static headers to all requests, you can instead instantiate
|
||||
the `XrpcClient` as follows:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: "http://my-service.com",
|
||||
headers: {
|
||||
"my-header": "my-value",
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
If you need the headers or service url to be dynamic, you can define them using
|
||||
functions:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: () => "http://my-service.com",
|
||||
headers: {
|
||||
"my-header": () => "my-value",
|
||||
"my-ignored-header": () => null, // ignored
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add the ability to use `fetch()` compatible `BodyInit` body when making XRPC calls.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/xrpc@0.6.0
|
||||
|
||||
## 0.12.29
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/api",
|
||||
"version": "0.12.29",
|
||||
"version": "0.13.0",
|
||||
"license": "MIT",
|
||||
"description": "Client library for atproto and Bluesky",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,12 @@
|
||||
# @atproto/aws
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @atproto/repo@0.4.2
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/aws",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"license": "MIT",
|
||||
"description": "Shared AWS cloud API helpers for atproto services",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,15 @@
|
||||
# @atproto/bsky
|
||||
|
||||
## 0.0.74
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/api@0.13.0
|
||||
- @atproto/repo@0.4.2
|
||||
- @atproto/xrpc-server@0.6.1
|
||||
|
||||
## 0.0.73
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/bsky",
|
||||
"version": "0.0.73",
|
||||
"version": "0.0.74",
|
||||
"license": "MIT",
|
||||
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,17 @@
|
||||
# @atproto/dev-env
|
||||
|
||||
## 0.3.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/api@0.13.0
|
||||
- @atproto/bsky@0.0.74
|
||||
- @atproto/ozone@0.1.36
|
||||
- @atproto/pds@0.4.48
|
||||
- @atproto/xrpc-server@0.6.1
|
||||
|
||||
## 0.3.38
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/dev-env",
|
||||
"version": "0.3.38",
|
||||
"version": "0.3.39",
|
||||
"license": "MIT",
|
||||
"description": "Local development environment helper for atproto development",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,11 @@
|
||||
# @atproto/did
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose atproto specific types and utilities
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/did",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"license": "MIT",
|
||||
"description": "DID resolution and verification library",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,12 @@
|
||||
# @atproto-labs/did-resolver
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/did@0.1.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto-labs/did-resolver",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "DID resolution and verification library",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,13 @@
|
||||
# @atproto-labs/handle-resolver-node
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto-labs/handle-resolver@0.1.2
|
||||
- @atproto/did@0.1.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto-labs/handle-resolver-node",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "Node specific ATProto handle to DID resolver",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,14 @@
|
||||
# @atproto-labs/handle-resolver
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Updated to use "AtprotoDid" utils from @atproto/did
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/did@0.1.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto-labs/handle-resolver",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "Isomorphic ATProto handle to DID resolver",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,15 @@
|
||||
# @atproto-labs/identity-resolver
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose getDocumentFromDid and getDocumentFromHandle as public methods on IdentityResolver
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto-labs/handle-resolver@0.1.2
|
||||
- @atproto-labs/did-resolver@0.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto-labs/identity-resolver",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "A library resolving ATPROTO identities",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,16 @@
|
||||
# @atproto/lex-cli
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2707](https://github.com/bluesky-social/atproto/pull/2707) [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e) Thanks [@matthieusieben](https://github.com/matthieusieben)! - The generated client implementation uses the new `XrpcClient` class from `@atproto/xrpc`, instead of the deprecated `Client` and `ServiceClient` class.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/lex-cli",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.0",
|
||||
"license": "MIT",
|
||||
"description": "TypeScript codegen tool for atproto Lexicon schemas",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,13 @@
|
||||
# @atproto/lexicon
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add the ability to instantiate a Lexicon from an iterable, and to use a Lexicon as iterable.
|
||||
|
||||
- [#2707](https://github.com/bluesky-social/atproto/pull/2707) [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Remove internal circular dependency.
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/lexicon",
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.1",
|
||||
"license": "MIT",
|
||||
"description": "atproto Lexicon schema language library",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,13 @@
|
||||
# @atproto/jwk-jose
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Misc fixes for confidential client usage
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Allow importing JoseKey without specifying a kid
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/jwk-jose",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "`jose` based implementation of @atproto/jwk Key's",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,12 @@
|
||||
# @atproto/jwk-webcrypto
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/jwk-jose@0.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/jwk-webcrypto",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "Webcrypto based implementation of @atproto/jwk Key's",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,17 @@
|
||||
# @atproto/oauth-client-browser
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/oauth-client@0.1.2
|
||||
- @atproto/oauth-types@0.1.2
|
||||
- @atproto-labs/handle-resolver@0.1.2
|
||||
- @atproto/did@0.1.1
|
||||
- @atproto/jwk-webcrypto@0.1.2
|
||||
- @atproto-labs/did-resolver@0.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/oauth-client-browser",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "ATPROTO OAuth client for the browser (relies on WebCrypto & Indexed DB)",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,20 @@
|
||||
# @atproto/oauth-client-node
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Better implement aptroto OAuth spec
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/oauth-client@0.1.2
|
||||
- @atproto/jwk-jose@0.1.2
|
||||
- @atproto/oauth-types@0.1.2
|
||||
- @atproto/did@0.1.1
|
||||
- @atproto/jwk-webcrypto@0.1.2
|
||||
- @atproto-labs/handle-resolver-node@0.1.2
|
||||
- @atproto-labs/did-resolver@0.1.2
|
||||
|
||||
## 0.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/oauth-client-node",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"license": "MIT",
|
||||
"description": "ATPROTO OAuth client for the NodeJS",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,22 @@
|
||||
# @atproto/oauth-client
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Misc fixes for confidential client usage
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Better implement aptroto OAuth spec
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/oauth-types@0.1.2
|
||||
- @atproto-labs/handle-resolver@0.1.2
|
||||
- @atproto/did@0.1.1
|
||||
- @atproto/xrpc@0.6.0
|
||||
- @atproto/api@0.13.0
|
||||
- @atproto-labs/identity-resolver@0.1.2
|
||||
- @atproto-labs/did-resolver@0.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/oauth-client",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "OAuth client for ATPROTO PDS. This package serves as common base for environment-specific implementations (NodeJS, Browser, React-Native).",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,15 @@
|
||||
# @atproto/oauth-provider
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Remove unused file
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/jwk-jose@0.1.2
|
||||
- @atproto/oauth-types@0.1.2
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/oauth-provider",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,11 @@
|
||||
# @atproto/oauth-types
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Better implement aptroto OAuth spec
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/oauth-types",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"description": "OAuth typing & validation library",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,15 @@
|
||||
# @atproto/ozone
|
||||
|
||||
## 0.1.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/xrpc@0.6.0
|
||||
- @atproto/api@0.13.0
|
||||
- @atproto/xrpc-server@0.6.1
|
||||
|
||||
## 0.1.35
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/ozone",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.36",
|
||||
"license": "MIT",
|
||||
"description": "Backend service for moderating the Bluesky network.",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,18 @@
|
||||
# @atproto/pds
|
||||
|
||||
## 0.4.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/xrpc@0.6.0
|
||||
- @atproto/api@0.13.0
|
||||
- @atproto/oauth-provider@0.1.2
|
||||
- @atproto/repo@0.4.2
|
||||
- @atproto/xrpc-server@0.6.1
|
||||
- @atproto/aws@0.2.2
|
||||
|
||||
## 0.4.47
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/pds",
|
||||
"version": "0.4.47",
|
||||
"version": "0.4.48",
|
||||
"license": "MIT",
|
||||
"description": "Reference implementation of atproto Personal Data Server (PDS)",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,12 @@
|
||||
# @atproto/repo
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/repo",
|
||||
"version": "0.4.1",
|
||||
"version": "0.4.2",
|
||||
"license": "MIT",
|
||||
"description": "atproto repo and MST implementation",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,13 @@
|
||||
# @atproto/xrpc-server
|
||||
|
||||
## 0.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
- @atproto/xrpc@0.6.0
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/xrpc-server",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"license": "MIT",
|
||||
"description": "atproto HTTP API (XRPC) server library",
|
||||
"keywords": [
|
||||
|
@ -1,5 +1,574 @@
|
||||
# @atproto/xrpc
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - ## Motivation
|
||||
|
||||
The motivation for these changes is the need to make the `@atproto/api` package
|
||||
compatible with OAuth session management. We don't have OAuth client support
|
||||
"launched" and documented quite yet, so you can keep using the current app
|
||||
password authentication system. When we do "launch" OAuth support and begin
|
||||
encouraging its usage in the near future (see the [OAuth
|
||||
Roadmap](https://github.com/bluesky-social/atproto/discussions/2656)), these
|
||||
changes will make it easier to migrate.
|
||||
|
||||
In addition, the redesigned session management system fixes a bug that could
|
||||
cause the session data to become invalid when Agent clones are created (e.g.
|
||||
using `agent.withProxy()`).
|
||||
|
||||
## New Features
|
||||
|
||||
We've restructured the `XrpcClient` HTTP fetch handler to be specified during
|
||||
the instantiation of the XRPC client, through the constructor, instead of using
|
||||
a default implementation (which was statically defined).
|
||||
|
||||
With this refactor, the XRPC client is now more modular and reusable. Session
|
||||
management, retries, cryptographic signing, and other request-specific logic can
|
||||
be implemented in the fetch handler itself rather than by the calling code.
|
||||
|
||||
A new abstract class named `Agent`, has been added to `@atproto/api`. This class
|
||||
will be the base class for all Bluesky agents classes in the `@atproto`
|
||||
ecosystem. It is meant to be extended by implementations that provide session
|
||||
management and fetch handling.
|
||||
|
||||
As you adapt your code to these changes, make sure to use the `Agent` type
|
||||
wherever you expect to receive an agent, and use the `AtpAgent` type (class)
|
||||
only to instantiate your client. The reason for this is to be forward compatible
|
||||
with the OAuth agent implementation that will also extend `Agent`, and not
|
||||
`AtpAgent`.
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from "@atproto/api";
|
||||
|
||||
async function setupAgent(
|
||||
service: string,
|
||||
username: string,
|
||||
password: string,
|
||||
): Promise<Agent> {
|
||||
const agent = new AtpAgent({
|
||||
service,
|
||||
persistSession: (evt, session) => {
|
||||
// handle session update
|
||||
},
|
||||
});
|
||||
|
||||
await agent.login(username, password);
|
||||
|
||||
return agent;
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent } from "@atproto/api";
|
||||
|
||||
async function doStuffWithAgent(agent: Agent, arg: string) {
|
||||
return agent.resolveHandle(arg);
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Agent, AtpAgent } from "@atproto/api";
|
||||
|
||||
class MyClass {
|
||||
agent: Agent;
|
||||
|
||||
constructor() {
|
||||
this.agent = new AtpAgent();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Breaking changes
|
||||
|
||||
Most of the changes introduced in this version are backward-compatible. However,
|
||||
there are a couple of breaking changes you should be aware of:
|
||||
|
||||
- Customizing `fetch`: The ability to customize the `fetch: FetchHandler`
|
||||
property of `@atproto/xrpc`'s `Client` and `@atproto/api`'s `AtpAgent` classes
|
||||
has been removed. Previously, the `fetch` property could be set to a function
|
||||
that would be used as the fetch handler for that instance, and was initialized
|
||||
to a default fetch handler. That property is still accessible in a read-only
|
||||
fashion through the `fetchHandler` property and can only be set during the
|
||||
instance creation. Attempting to set/get the `fetch` property will now result
|
||||
in an error.
|
||||
- The `fetch()` method, as well as WhatWG compliant `Request` and `Headers`
|
||||
constructors, must be globally available in your environment. Use a polyfill
|
||||
if necessary.
|
||||
- The `AtpBaseClient` has been removed. The `AtpServiceClient` has been renamed
|
||||
`AtpBaseClient`. Any code using either of these classes will need to be
|
||||
updated.
|
||||
- Instead of _wrapping_ an `XrpcClient` in its `xrpc` property, the
|
||||
`AtpBaseClient` (formerly `AtpServiceClient`) class - created through
|
||||
`lex-cli` - now _extends_ the `XrpcClient` class. This means that a client
|
||||
instance now passes the `instanceof XrpcClient` check. The `xrpc` property now
|
||||
returns the instance itself and has been deprecated.
|
||||
- `setSessionPersistHandler` is no longer available on the `AtpAgent` or
|
||||
`BskyAgent` classes. The session handler can only be set though the
|
||||
`persistSession` options of the `AtpAgent` constructor.
|
||||
- The new class hierarchy is as follows:
|
||||
- `BskyAgent` extends `AtpAgent`: but add no functionality (hence its
|
||||
deprecation).
|
||||
- `AtpAgent` extends `Agent`: adds password based session management.
|
||||
- `Agent` extends `AtpBaseClient`: this abstract class that adds syntactic sugar
|
||||
methods `app.bsky` lexicons. It also adds abstract session management
|
||||
methods and adds atproto specific utilities
|
||||
(`labelers` & `proxy` headers, cloning capability)
|
||||
- `AtpBaseClient` extends `XrpcClient`: automatically code that adds fully
|
||||
typed lexicon defined namespaces (`instance.app.bsky.feed.getPosts()`) to
|
||||
the `XrpcClient`.
|
||||
- `XrpcClient` is the base class.
|
||||
|
||||
## Non-breaking changes
|
||||
|
||||
- The `com.*` and `app.*` namespaces have been made directly available to every
|
||||
`Agent` instances.
|
||||
|
||||
## Deprecations
|
||||
|
||||
- The default export of the `@atproto/xrpc` package has been deprecated. Use
|
||||
named exports instead.
|
||||
- The `Client` and `ServiceClient` classes are now deprecated. They are replaced by a single `XrpcClient` class.
|
||||
- The default export of the `@atproto/api` package has been deprecated. Use
|
||||
named exports instead.
|
||||
- The `BskyAgent` has been deprecated. Use the `AtpAgent` class instead.
|
||||
- The `xrpc` property of the `AtpClient` instances has been deprecated. The
|
||||
instance itself should be used as the XRPC client.
|
||||
- The `api` property of the `AtpAgent` and `BskyAgent` instances has been
|
||||
deprecated. Use the instance itself instead.
|
||||
|
||||
## Migration
|
||||
|
||||
### The `@atproto/api` package
|
||||
|
||||
If you were relying on the `AtpBaseClient` solely to perform validation, use
|
||||
this:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from "@atproto/api";
|
||||
|
||||
const baseClient = new AtpBaseClient();
|
||||
|
||||
baseClient.xrpc.lex.assertValidXrpcMessage("io.example.doStuff", {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { lexicons } from "@atproto/api";
|
||||
|
||||
lexicons.assertValidXrpcMessage("io.example.doStuff", {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you are extending the `BskyAgent` to perform custom `session` manipulation, define your own `Agent` subclass instead:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from "@atproto/api";
|
||||
|
||||
class MyAgent extends BskyAgent {
|
||||
private accessToken?: string;
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.accessToken = "my-access-jwt";
|
||||
}
|
||||
|
||||
async doStuff() {
|
||||
return this.call("io.example.doStuff", {
|
||||
headers: {
|
||||
Authorization: this.accessToken && `Bearer ${this.accessToken}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { Agent } from "@atproto/api";
|
||||
|
||||
class MyAgent extends Agent {
|
||||
private accessToken?: string;
|
||||
public did?: string;
|
||||
|
||||
constructor(private readonly service: string | URL) {
|
||||
super({
|
||||
service,
|
||||
headers: {
|
||||
Authorization: () =>
|
||||
this.accessToken ? `Bearer ${this.accessToken}` : null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
clone(): MyAgent {
|
||||
const agent = new MyAgent(this.service);
|
||||
agent.accessToken = this.accessToken;
|
||||
agent.did = this.did;
|
||||
return this.copyInto(agent);
|
||||
}
|
||||
|
||||
async createOrRefreshSession(identifier: string, password: string) {
|
||||
// custom logic here
|
||||
|
||||
this.did = "did:example:123";
|
||||
this.accessToken = "my-access-jwt";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you are monkey patching the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent } from "@atproto/api";
|
||||
import { RateLimitThreshold } from "rate-limit-threshold";
|
||||
|
||||
const agent = new BskyAgent();
|
||||
const limiter = new RateLimitThreshold(3000, 300_000);
|
||||
|
||||
const origCall = agent.api.xrpc.call;
|
||||
agent.api.xrpc.call = async function (...args) {
|
||||
await limiter.wait();
|
||||
return origCall.call(this, ...args);
|
||||
};
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from "@atproto/api";
|
||||
import { RateLimitThreshold } from "rate-limit-threshold";
|
||||
|
||||
class LimitedAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch: typeof globalThis.fetch = options.fetch ?? globalThis.fetch;
|
||||
const limiter = new RateLimitThreshold(3000, 300_000);
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (...args) => {
|
||||
await limiter.wait();
|
||||
return fetch(...args);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you configure a static `fetch` handler on the `BskyAgent` class - for example
|
||||
to modify the headers of every request - you can now do this by providing your
|
||||
own `fetch` function:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { BskyAgent, defaultFetchHandler } from "@atproto/api";
|
||||
|
||||
BskyAgent.configure({
|
||||
fetch: async (httpUri, httpMethod, httpHeaders, httpReqBody) => {
|
||||
const ua = httpHeaders["User-Agent"];
|
||||
|
||||
httpHeaders["User-Agent"] = ua ? `${ua} ${userAgent}` : userAgent;
|
||||
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { AtpAgent } from "@atproto/api";
|
||||
|
||||
class MyAtpAgent extends AtpAgent {
|
||||
constructor(options: AtpAgentOptions) {
|
||||
const fetch = options.fetch ?? globalThis.fetch;
|
||||
|
||||
super({
|
||||
...options,
|
||||
fetch: async (url, init) => {
|
||||
const headers = new Headers(init.headers);
|
||||
|
||||
const ua = headersList.get("User-Agent");
|
||||
headersList.set("User-Agent", ua ? `${ua} ${userAgent}` : userAgent);
|
||||
|
||||
return fetch(url, { ...init, headers });
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- <table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// before
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
// after
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table> -->
|
||||
|
||||
### The `@atproto/xrpc` package
|
||||
|
||||
The `Client` and `ServiceClient` classes are now **deprecated**. If you need a
|
||||
lexicon based client, you should update the code to use the `XrpcClient` class
|
||||
instead.
|
||||
|
||||
The deprecated `ServiceClient` class now extends the new `XrpcClient` class.
|
||||
Because of this, the `fetch` `FetchHandler` can no longer be configured on the
|
||||
`Client` instances (including the default export of the package). If you are not
|
||||
relying on the `fetch` `FetchHandler`, the new changes should have no impact on
|
||||
your code. Beware that the deprecated classes will eventually be removed in a
|
||||
future version.
|
||||
|
||||
Since its use has completely changed, the `FetchHandler` type has also
|
||||
completely changed. The new `FetchHandler` type is now a function that receives
|
||||
a `url` pathname and a `RequestInit` object and returns a `Promise<Response>`.
|
||||
This function is responsible for making the actual request to the server.
|
||||
|
||||
```ts
|
||||
export type FetchHandler = (
|
||||
this: void,
|
||||
/**
|
||||
* The URL (pathname + query parameters) to make the request to, without the
|
||||
* origin. The origin (protocol, hostname, and port) must be added by this
|
||||
* {@link FetchHandler}, typically based on authentication or other factors.
|
||||
*/
|
||||
url: string,
|
||||
init: RequestInit,
|
||||
) => Promise<Response>;
|
||||
```
|
||||
|
||||
A noticeable change that has been introduced is that the `uri` field of the
|
||||
`ServiceClient` class has _not_ been ported to the new `XrpcClient` class. It is
|
||||
now the responsibility of the `FetchHandler` to determine the full URL to make
|
||||
the request to. The same goes for the `headers`, which should now be set through
|
||||
the `FetchHandler` function.
|
||||
|
||||
If you _do_ rely on the legacy `Client.fetch` property to perform custom logic
|
||||
upon request, you will need to migrate your code to use the new `XrpcClient`
|
||||
class. The `XrpcClient` class has a similar API to the old `ServiceClient`
|
||||
class, but with a few differences:
|
||||
|
||||
- The `Client` + `ServiceClient` duality was removed in favor of a single
|
||||
`XrpcClient` class. This means that:
|
||||
|
||||
- There no longer exists a centralized lexicon registry. If you need a global
|
||||
lexicon registry, you can maintain one yourself using a `new Lexicons` (from
|
||||
`@atproto/lexicon`).
|
||||
- The `FetchHandler` is no longer a statically defined property of the
|
||||
`Client` class. Instead, it is passed as an argument to the `XrpcClient`
|
||||
constructor.
|
||||
|
||||
- The `XrpcClient` constructor now requires a `FetchHandler` function as the
|
||||
first argument, and an optional `Lexicon` instance as the second argument.
|
||||
- The `setHeader` and `unsetHeader` methods were not ported to the new
|
||||
`XrpcClient` class. If you need to set or unset headers, you should do so in
|
||||
the `FetchHandler` function provided in the constructor arg.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><center>Before</center></td> <td><center>After</center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import client, { defaultFetchHandler } from "@atproto/xrpc";
|
||||
|
||||
client.fetch = function (
|
||||
httpUri: string,
|
||||
httpMethod: string,
|
||||
httpHeaders: Headers,
|
||||
httpReqBody: unknown,
|
||||
) {
|
||||
// Custom logic here
|
||||
return defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody);
|
||||
};
|
||||
|
||||
client.addLexicon({
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
});
|
||||
|
||||
const instance = client.service("http://my-service.com");
|
||||
|
||||
instance.setHeader("my-header", "my-value");
|
||||
|
||||
await instance.call("io.example.doStuff");
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
async (url, init) => {
|
||||
const headers = new Headers(init.headers);
|
||||
|
||||
headers.set("my-header", "my-value");
|
||||
|
||||
// Custom logic here
|
||||
|
||||
const fullUrl = new URL(url, "http://my-service.com");
|
||||
|
||||
return fetch(fullUrl, { ...init, headers });
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
await instance.call("io.example.doStuff");
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If your fetch handler does not require any "custom logic", and all you need is
|
||||
an `XrpcClient` that makes its HTTP requests towards a static service URL, the
|
||||
previous example can be simplified to:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient("http://my-service.com", [
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
]);
|
||||
```
|
||||
|
||||
If you need to add static headers to all requests, you can instead instantiate
|
||||
the `XrpcClient` as follows:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: "http://my-service.com",
|
||||
headers: {
|
||||
"my-header": "my-value",
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
If you need the headers or service url to be dynamic, you can define them using
|
||||
functions:
|
||||
|
||||
```ts
|
||||
import { XrpcClient } from "@atproto/xrpc";
|
||||
|
||||
const instance = new XrpcClient(
|
||||
{
|
||||
service: () => "http://my-service.com",
|
||||
headers: {
|
||||
"my-header": () => "my-value",
|
||||
"my-ignored-header": () => null, // ignored
|
||||
},
|
||||
},
|
||||
[
|
||||
{
|
||||
lexicon: 1,
|
||||
id: "io.example.doStuff",
|
||||
defs: {},
|
||||
},
|
||||
],
|
||||
);
|
||||
```
|
||||
|
||||
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add the ability to use `fetch()` compatible `BodyInit` body when making XRPC calls.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b934b396b`](https://github.com/bluesky-social/atproto/commit/b934b396b13ba32bf2bf7e75ecdf6871e5f310dd), [`2bdf75d7a`](https://github.com/bluesky-social/atproto/commit/2bdf75d7a63924c10e7a311f16cb447d595b933e)]:
|
||||
- @atproto/lexicon@0.4.1
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@atproto/xrpc",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.0",
|
||||
"license": "MIT",
|
||||
"description": "atproto HTTP API (XRPC) client library",
|
||||
"keywords": [
|
||||
|
Loading…
x
Reference in New Issue
Block a user