Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version packages #2706

Merged
merged 1 commit into from
Aug 12, 2024
Merged

Version packages #2706

merged 1 commit into from
Aug 12, 2024

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Aug 12, 2024

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@atproto/api@0.13.0

Minor Changes

  • #2483 b934b396b Thanks @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
    ), 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.

    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;
    }
    import { Agent } from "@atproto/api";
    
    async function doStuffWithAgent(agent: Agent, arg: string) {
      return agent.resolveHandle(arg);
    }
    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:

    Before After
    import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from "@atproto/api";
    
    const baseClient = new AtpBaseClient();
    
    baseClient.xrpc.lex.assertValidXrpcMessage("io.example.doStuff", {
      // ...
    });
    import { lexicons } from "@atproto/api";
    
    lexicons.assertValidXrpcMessage("io.example.doStuff", {
      // ...
    });

    If you are extending the BskyAgent to perform custom session manipulation, define your own Agent subclass instead:

    Before After
    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}`,
          },
        });
      }
    }
    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";
      }
    }

    If you are monkey patching the xrpc service client to perform client-side rate limiting, you can now do this in the FetchHandler function:

    Before After
    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);
    };
    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);
          },
        });
      }
    }

    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:

    Before After
    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);
      },
    });
    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 });
          },
        });
      }
    }

    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.

    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.

    Before After
    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");
    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");

    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:

    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:

    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:

    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 b934b396b Thanks @matthieusieben! - Add the ability to use fetch() compatible BodyInit body when making XRPC calls.

Patch Changes

@atproto/lex-cli@0.5.0

Minor Changes

  • #2707 2bdf75d7a Thanks @matthieusieben! - The generated client implementation uses the new XrpcClient class from @atproto/xrpc, instead of the deprecated Client and ServiceClient class.

Patch Changes

@atproto/xrpc@0.6.0

Minor Changes

  • #2483 b934b396b Thanks @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
    ), 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.

    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;
    }
    import { Agent } from "@atproto/api";
    
    async function doStuffWithAgent(agent: Agent, arg: string) {
      return agent.resolveHandle(arg);
    }
    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:

    Before After
    import { AtpBaseClient, ComAtprotoSyncSubscribeRepos } from "@atproto/api";
    
    const baseClient = new AtpBaseClient();
    
    baseClient.xrpc.lex.assertValidXrpcMessage("io.example.doStuff", {
      // ...
    });
    import { lexicons } from "@atproto/api";
    
    lexicons.assertValidXrpcMessage("io.example.doStuff", {
      // ...
    });

    If you are extending the BskyAgent to perform custom session manipulation, define your own Agent subclass instead:

    Before After
    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}`,
          },
        });
      }
    }
    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";
      }
    }

    If you are monkey patching the xrpc service client to perform client-side rate limiting, you can now do this in the FetchHandler function:

    Before After
    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);
    };
    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);
          },
        });
      }
    }

    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:

    Before After
    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);
      },
    });
    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 });
          },
        });
      }
    }

    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.

    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.

    Before After
    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");
    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");

    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:

    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:

    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:

    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 b934b396b Thanks @matthieusieben! - Add the ability to use fetch() compatible BodyInit body when making XRPC calls.

Patch Changes

@atproto/aws@0.2.2

Patch Changes

  • Updated dependencies []:
    • @atproto/repo@0.4.2

@atproto/bsky@0.0.74

Patch Changes

@atproto/dev-env@0.3.39

Patch Changes

  • Updated dependencies [b934b396b, 2bdf75d7a, b934b396b, b934b396b]:
    • @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

@atproto/did@0.1.1

Patch Changes

@atproto-labs/did-resolver@0.1.2

Patch Changes

  • Updated dependencies [b934b396b]:
    • @atproto/did@0.1.1

@atproto-labs/handle-resolver@0.1.2

Patch Changes

@atproto-labs/handle-resolver-node@0.1.2

Patch Changes

  • Updated dependencies [b934b396b, b934b396b]:
    • @atproto-labs/handle-resolver@0.1.2
    • @atproto/did@0.1.1

@atproto-labs/identity-resolver@0.1.2

Patch Changes

  • #2483 b934b396b Thanks @matthieusieben! - Expose getDocumentFromDid and getDocumentFromHandle as public methods on IdentityResolver

  • Updated dependencies [b934b396b]:

    • @atproto-labs/handle-resolver@0.1.2
    • @atproto-labs/did-resolver@0.1.2

@atproto/lexicon@0.4.1

Patch Changes

@atproto/jwk-jose@0.1.2

Patch Changes

@atproto/jwk-webcrypto@0.1.2

Patch Changes

@atproto/oauth-client@0.1.2

Patch Changes

@atproto/oauth-client-browser@0.1.2

Patch Changes

  • Updated dependencies [b934b396b, b934b396b, b934b396b, b934b396b]:
    • @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

@atproto/oauth-client-node@0.0.2

Patch Changes

  • #2483 b934b396b Thanks @matthieusieben! - Better implement aptroto OAuth spec

  • Updated dependencies [b934b396b, b934b396b, b934b396b, b934b396b]:

    • @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

@atproto/oauth-provider@0.1.2

Patch Changes

@atproto/oauth-types@0.1.2

Patch Changes

@atproto/ozone@0.1.36

Patch Changes

@atproto/pds@0.4.48

Patch Changes

  • Updated dependencies [b934b396b, 2bdf75d7a, b934b396b, b934b396b, b934b396b]:
    • @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

@atproto/repo@0.4.2

Patch Changes

@atproto/xrpc-server@0.6.1

Patch Changes

class MyAgent extends BskyAgent {
private accessToken?: string;

async createOrRefleshSession(identifier: string, password: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async createOrRefleshSession(identifier: string, password: string) {
async createOrRefreshSession(identifier: string, password: string) {

I think there's a typo here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks!

</tr>
</table>

If you are monkey patching the the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you are monkey patching the the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:
If you are monkey patching the `xrpc` service client to perform client-side rate limiting, you can now do this in the `FetchHandler` function:

the is repeated

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 from making the actual request to the server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This function is responsible from making the actual request to the server.
This function is responsible for making the actual request to the server.

This sounds like it should be for?

@github-actions github-actions bot force-pushed the changeset-release/main branch from e9f90eb to 9db352b Compare August 12, 2024 20:01
@devinivy devinivy merged commit 3940733 into main Aug 12, 2024
@devinivy devinivy deleted the changeset-release/main branch August 12, 2024 20:11
estrattonbailey added a commit that referenced this pull request Aug 15, 2024
* origin/main:
  Provide a ponyfill for CustomEvent (#2710)
  Ensure presence of DPoP related response headers (#2711)
  prettier ignore changelogs, as changesets not resolving prettier config properly
  Version packages (#2709)
  Export `AtpAgentOptions` type from @atproto/api (#2708)
  tidy
  Version packages (#2706)
  Update changeset to better reflect changes (#2707)
  Client SDK rework (#2483)
  Allow aud of pds or entryway for service auth tokens on pds (#2694)
  Version packages (#2692)
  Lex-cli prettier changes changeset (#2691)
  Version packages (#2689)
  PDS - inspect bearer tokens (#2688)
  Version packages (#2685)
  Service auth method binding - PDS (#2668)
  minor typos in descriptions and comments (#2681)
  Fix run-dev-env-logged command (#2682)
  Version packages (#2677)
  Tweak some wording in `oauth-client-browser` readme (#2678)
haileyok pushed a commit that referenced this pull request Aug 16, 2024
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants