@atproto/xrpc-server 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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","sourcesContent":["import { IncomingMessage, ServerResponse } from 'node:http'\nimport {\n RateLimiterAbstract,\n RateLimiterMemory,\n RateLimiterRedis,\n RateLimiterRes,\n} from 'rate-limiter-flexible'\nimport { ResponseType, XRPCError } from './errors.js'\nimport { logger } from './logger.js'\n\n// @NOTE Do not depend (directly or indirectly) on \"./types\" here, as it would\n// create a circular dependency.\n\nexport interface RateLimiterContext {\n req: IncomingMessage\n res?: ServerResponse\n}\n\nexport type CalcKeyFn<C extends RateLimiterContext = RateLimiterContext> = (\n ctx: C,\n) => string | null\nexport type CalcPointsFn<C extends RateLimiterContext = RateLimiterContext> = (\n ctx: C,\n) => number\n\nexport interface RateLimiterI<\n C extends RateLimiterContext = RateLimiterContext,\n> {\n consume: RateLimiterConsume<C>\n reset: RateLimiterReset<C>\n}\n\nexport type RateLimiterConsumeOptions<\n C extends RateLimiterContext = RateLimiterContext,\n> = {\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\nexport type RateLimiterConsume<\n C extends RateLimiterContext = RateLimiterContext,\n> = (\n ctx: C,\n opts?: RateLimiterConsumeOptions<C>,\n) => Promise<RateLimiterStatus | RateLimitExceededError | null>\n\nexport type RateLimiterStatus = {\n limit: number\n duration: number\n remainingPoints: number\n msBeforeNext: number\n consumedPoints: number\n isFirstInDuration: boolean\n}\n\nexport type RateLimiterResetOptions<\n C extends RateLimiterContext = RateLimiterContext,\n> = {\n calcKey?: CalcKeyFn<C>\n}\n\nexport type RateLimiterReset<\n C extends RateLimiterContext = RateLimiterContext,\n> = (ctx: C, opts?: RateLimiterResetOptions<C>) => Promise<void>\n\nexport type RateLimiterOptions<\n C extends RateLimiterContext = RateLimiterContext,\n> = {\n keyPrefix: string\n durationMs: number\n points: number\n calcKey: CalcKeyFn<C>\n calcPoints: CalcPointsFn<C>\n failClosed?: boolean\n}\n\nexport class RateLimiter<C extends RateLimiterContext = RateLimiterContext>\n implements RateLimiterI<C>\n{\n private readonly failClosed?: boolean\n private readonly calcKey: CalcKeyFn<C>\n private readonly calcPoints: CalcPointsFn<C>\n\n constructor(\n public limiter: RateLimiterAbstract,\n options: RateLimiterOptions<C>,\n ) {\n this.limiter = limiter\n this.failClosed = options.failClosed ?? false\n this.calcKey = options.calcKey\n this.calcPoints = options.calcPoints\n }\n\n async consume(\n ctx: C,\n opts?: RateLimiterConsumeOptions<C>,\n ): Promise<RateLimiterStatus | RateLimitExceededError | null> {\n const calcKey = opts?.calcKey ?? this.calcKey\n const key = calcKey(ctx)\n if (key === null) {\n return null\n }\n const calcPoints = opts?.calcPoints ?? this.calcPoints\n const points = calcPoints(ctx)\n if (points < 1) {\n return null\n }\n try {\n const res = await this.limiter.consume(key, points)\n return formatLimiterStatus(this.limiter, res)\n } catch (err) {\n // yes this library rejects with a res not an error\n if (err instanceof RateLimiterRes) {\n const status = formatLimiterStatus(this.limiter, err)\n return new RateLimitExceededError(status)\n } else {\n if (this.failClosed) {\n throw err\n }\n logger.error(\n {\n err,\n keyPrefix: this.limiter.keyPrefix,\n points: this.limiter.points,\n duration: this.limiter.duration,\n },\n 'rate limiter failed to consume points',\n )\n return null\n }\n }\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>): Promise<void> {\n const key = opts?.calcKey ? opts.calcKey(ctx) : this.calcKey(ctx)\n if (key === null) {\n return\n }\n\n try {\n await this.limiter.delete(key)\n } catch (cause) {\n throw new Error(`rate limiter failed to reset key: ${key}`, { cause })\n }\n }\n}\n\nexport class MemoryRateLimiter<\n C extends RateLimiterContext = RateLimiterContext,\n> extends RateLimiter<C> {\n constructor(options: RateLimiterOptions<C>) {\n const limiter = new RateLimiterMemory({\n keyPrefix: options.keyPrefix,\n duration: Math.floor(options.durationMs / 1000),\n points: options.points,\n })\n super(limiter, options)\n }\n}\n\nexport class RedisRateLimiter<\n C extends RateLimiterContext = RateLimiterContext,\n> extends RateLimiter<C> {\n constructor(storeClient: unknown, options: RateLimiterOptions<C>) {\n const limiter = new RateLimiterRedis({\n storeClient,\n keyPrefix: options.keyPrefix,\n duration: Math.floor(options.durationMs / 1000),\n points: options.points,\n })\n super(limiter, options)\n }\n}\n\nexport const formatLimiterStatus = (\n limiter: RateLimiterAbstract,\n res: RateLimiterRes,\n): RateLimiterStatus => {\n return {\n limit: limiter.points,\n duration: limiter.duration,\n remainingPoints: res.remainingPoints,\n msBeforeNext: res.msBeforeNext,\n consumedPoints: res.consumedPoints,\n isFirstInDuration: res.isFirstInDuration,\n }\n}\n\nexport type WrappedRateLimiterOptions<\n C extends RateLimiterContext = RateLimiterContext,\n> = {\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\n/**\n * Wraps a {@link RateLimiterI} instance with custom key and points calculation\n * functions.\n */\nexport class WrappedRateLimiter<\n C extends RateLimiterContext = RateLimiterContext,\n> implements RateLimiterI<C>\n{\n private constructor(\n private readonly rateLimiter: RateLimiterI<C>,\n private readonly options: Readonly<WrappedRateLimiterOptions<C>>,\n ) {}\n\n async consume(ctx: C, opts?: RateLimiterConsumeOptions<C>) {\n return this.rateLimiter.consume(ctx, {\n calcKey: opts?.calcKey ?? this.options.calcKey,\n calcPoints: opts?.calcPoints ?? this.options.calcPoints,\n })\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>) {\n return this.rateLimiter.reset(ctx, {\n calcKey: opts?.calcKey ?? this.options.calcKey,\n })\n }\n\n static from<C extends RateLimiterContext = RateLimiterContext>(\n rateLimiter: RateLimiterI<C>,\n { calcKey, calcPoints }: WrappedRateLimiterOptions<C> = {},\n ): RateLimiterI<C> {\n if (!calcKey && !calcPoints) return rateLimiter\n return new WrappedRateLimiter<C>(rateLimiter, { calcKey, calcPoints })\n }\n}\n\n/**\n * Combines multiple rate limiters into one.\n *\n * The combined rate limiter will return the tightest (most restrictive) of all\n * the provided rate limiters.\n */\nexport class CombinedRateLimiter<\n C extends RateLimiterContext = RateLimiterContext,\n> implements RateLimiterI<C>\n{\n private constructor(\n private readonly rateLimiters: readonly RateLimiterI<C>[],\n ) {}\n\n async consume(ctx: C, opts?: RateLimiterConsumeOptions<C>) {\n const promises: ReturnType<RateLimiterConsume>[] = []\n for (const rl of this.rateLimiters) promises.push(rl.consume(ctx, opts))\n return Promise.all(promises).then(getTightestLimit)\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>) {\n const promises: ReturnType<RateLimiterReset>[] = []\n for (const rl of this.rateLimiters) promises.push(rl.reset(ctx, opts))\n await Promise.all(promises)\n }\n\n static from<C extends RateLimiterContext = RateLimiterContext>(\n rateLimiters: readonly RateLimiterI<C>[],\n ): RateLimiterI<C> | undefined {\n if (rateLimiters.length === 0) return undefined\n if (rateLimiters.length === 1) return rateLimiters[0]\n return new CombinedRateLimiter(rateLimiters)\n }\n}\n\nconst getTightestLimit = (\n resps: (RateLimiterStatus | RateLimitExceededError | null)[],\n): RateLimiterStatus | RateLimitExceededError | null => {\n let lowest: RateLimiterStatus | null = null\n for (const resp of resps) {\n if (resp === null) continue\n if (resp instanceof RateLimitExceededError) return resp\n if (lowest === null || resp.remainingPoints < lowest.remainingPoints) {\n lowest = resp\n }\n }\n return lowest\n}\n\nexport type RouteRateLimiterOptions<\n C extends RateLimiterContext = RateLimiterContext,\n> = {\n bypass?: (ctx: C) => boolean\n}\n\n/**\n * Wraps a {@link RateLimiterI} interface into a class that will apply the\n * appropriate headers to the response if a limit is exceeded.\n */\nexport class RouteRateLimiter<C extends RateLimiterContext = RateLimiterContext>\n implements RateLimiterI<C>\n{\n constructor(\n private readonly rateLimiter: RateLimiterI<C>,\n private readonly options: Readonly<RouteRateLimiterOptions<C>> = {},\n ) {}\n\n async handle(ctx: C): Promise<RateLimiterStatus | null> {\n const { bypass } = this.options\n if (bypass && bypass(ctx)) {\n return null\n }\n\n const result = await this.consume(ctx)\n if (result instanceof RateLimitExceededError) {\n setStatusHeaders(ctx, result.status)\n throw result\n } else if (result != null) {\n setStatusHeaders(ctx, result)\n }\n\n return result\n }\n\n async consume(...args: Parameters<RateLimiterConsume<C>>) {\n return this.rateLimiter.consume(...args)\n }\n\n async reset(...args: Parameters<RateLimiterReset<C>>) {\n return this.rateLimiter.reset(...args)\n }\n\n static from<C extends RateLimiterContext = RateLimiterContext>(\n rateLimiters: readonly RateLimiterI<C>[],\n { bypass }: RouteRateLimiterOptions<C> = {},\n ): RouteRateLimiter<C> | undefined {\n const rateLimiter = CombinedRateLimiter.from(rateLimiters)\n if (!rateLimiter) return undefined\n\n return new RouteRateLimiter(rateLimiter, { bypass })\n }\n}\n\nfunction setStatusHeaders<C extends RateLimiterContext = RateLimiterContext>(\n ctx: C,\n status: RateLimiterStatus,\n) {\n const resetAt = Math.floor((Date.now() + status.msBeforeNext) / 1e3)\n\n ctx.res?.setHeader('RateLimit-Limit', status.limit)\n ctx.res?.setHeader('RateLimit-Reset', resetAt)\n ctx.res?.setHeader('RateLimit-Remaining', status.remainingPoints)\n ctx.res?.setHeader('RateLimit-Policy', `${status.limit};w=${status.duration}`)\n}\n\nexport class RateLimitExceededError extends XRPCError {\n constructor(\n public status: RateLimiterStatus,\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.RateLimitExceeded,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.RateLimitExceeded\n )\n }\n}\n"]}
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n RateLimiterAbstract,\n RateLimiterMemory,\n RateLimiterRedis,\n RateLimiterRes,\n} from 'rate-limiter-flexible'\nimport { ResponseType, XRPCError } from './errors.js'\n\n// @NOTE Do not depend (directly or indirectly) on \"./types\" here, as it would\n// create a circular dependency.\n\nexport type { RateLimiterAbstract }\n\nexport type CalcKeyFn<C = unknown> = (ctx: C) => string | null\nexport type CalcPointsFn<C = unknown> = (ctx: C) => number\n\nexport interface RateLimiterI<C = unknown> {\n consume: RateLimiterConsume<C>\n reset: RateLimiterReset<C>\n}\n\nexport type RateLimiterConsumeOptions<C = unknown> = {\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\nexport type RateLimiterConsume<C = unknown> = (\n ctx: C,\n opts?: RateLimiterConsumeOptions<C>,\n) => Promise<RateLimiterStatus | null>\n\nexport type RateLimiterStatus = {\n limit: number\n duration: number\n remainingPoints: number\n msBeforeNext: number\n consumedPoints: number\n isFirstInDuration: boolean\n}\n\nexport type RateLimiterResetOptions<C = unknown> = {\n calcKey?: CalcKeyFn<C>\n}\n\nexport type RateLimiterReset<C = unknown> = (\n ctx: C,\n opts?: RateLimiterResetOptions<C>,\n) => Promise<void>\n\nexport type RateLimiterErrorHandlerDetails = {\n key: string\n points: number\n limiter: {\n keyPrefix: string\n points: number\n duration: number\n }\n}\nexport type RateLimiterErrorHandler<C = unknown> = (\n err: unknown,\n ctx: C,\n details: RateLimiterErrorHandlerDetails,\n) => Promise<RateLimiterStatus | null>\n\nexport type RateLimiterOptions<C = unknown> = {\n keyPrefix: string\n durationMs: number\n points: number\n calcKey: CalcKeyFn<C>\n calcPoints: CalcPointsFn<C>\n onError?: RateLimiterErrorHandler<C>\n}\n\nexport class RateLimiter<C = unknown> implements RateLimiterI<C> {\n private readonly onError?: RateLimiterErrorHandler<C>\n private readonly calcKey: CalcKeyFn<C>\n private readonly calcPoints: CalcPointsFn<C>\n\n constructor(\n public limiter: RateLimiterAbstract,\n options: RateLimiterOptions<C>,\n ) {\n this.limiter = limiter\n this.onError = options.onError\n this.calcKey = options.calcKey\n this.calcPoints = options.calcPoints\n }\n\n async consume(\n ctx: C,\n opts?: RateLimiterConsumeOptions<C>,\n ): Promise<RateLimiterStatus | null> {\n const calcKey = opts?.calcKey ?? this.calcKey\n const key = calcKey(ctx)\n if (key === null) {\n return null\n }\n const calcPoints = opts?.calcPoints ?? this.calcPoints\n const points = calcPoints(ctx)\n if (points < 1) {\n return null\n }\n const { limiter } = this\n try {\n const res = await limiter.consume(key, points)\n return formatLimiterStatus(limiter, res)\n } catch (err) {\n if (err instanceof RateLimiterRes) {\n // Wrap rate-limiter-flexible error into our own error type\n const status = formatLimiterStatus(limiter, err)\n throw new RateLimitExceededError(status)\n } else if (err instanceof RateLimitExceededError) {\n // Propagate RateLimitExceededError errors\n throw err\n } else {\n // Most likely a system error (failed to connect to Redis, etc). Allow\n // the caller to decide how to handle it (fail open by allowing the\n // request, fail closed by rejecting the request, etc).\n const { onError } = this\n if (onError) return onError(err, ctx, { key, points, limiter })\n\n throw err\n }\n }\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>): Promise<void> {\n const key = opts?.calcKey ? opts.calcKey(ctx) : this.calcKey(ctx)\n if (key === null) {\n return\n }\n\n try {\n await this.limiter.delete(key)\n } catch (cause) {\n throw new Error(`rate limiter failed to reset key: ${key}`, { cause })\n }\n }\n}\n\nexport class MemoryRateLimiter<C = unknown> extends RateLimiter<C> {\n constructor(options: RateLimiterOptions<C>) {\n const limiter = new RateLimiterMemory({\n keyPrefix: options.keyPrefix,\n duration: Math.floor(options.durationMs / 1000),\n points: options.points,\n })\n super(limiter, options)\n }\n}\n\nexport class RedisRateLimiter<C = unknown> extends RateLimiter<C> {\n constructor(storeClient: unknown, options: RateLimiterOptions<C>) {\n const limiter = new RateLimiterRedis({\n storeClient,\n keyPrefix: options.keyPrefix,\n duration: Math.floor(options.durationMs / 1000),\n points: options.points,\n })\n super(limiter, options)\n }\n}\n\nexport const formatLimiterStatus = (\n limiter: RateLimiterAbstract,\n res: RateLimiterRes,\n): RateLimiterStatus => {\n return {\n limit: limiter.points,\n duration: limiter.duration,\n remainingPoints: res.remainingPoints,\n msBeforeNext: res.msBeforeNext,\n consumedPoints: res.consumedPoints,\n isFirstInDuration: res.isFirstInDuration,\n }\n}\n\nexport type WrappedRateLimiterOptions<C = unknown> = {\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\n/**\n * Wraps a {@link RateLimiterI} instance with custom key and points calculation\n * functions.\n */\nexport class WrappedRateLimiter<C = unknown> implements RateLimiterI<C> {\n private constructor(\n private readonly rateLimiter: RateLimiterI<C>,\n private readonly options: Readonly<WrappedRateLimiterOptions<C>>,\n ) {}\n\n async consume(ctx: C, opts?: RateLimiterConsumeOptions<C>) {\n return this.rateLimiter.consume(ctx, {\n calcKey: opts?.calcKey ?? this.options.calcKey,\n calcPoints: opts?.calcPoints ?? this.options.calcPoints,\n })\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>) {\n return this.rateLimiter.reset(ctx, {\n calcKey: opts?.calcKey ?? this.options.calcKey,\n })\n }\n\n static from<C = unknown>(\n rateLimiter: RateLimiterI<C>,\n { calcKey, calcPoints }: WrappedRateLimiterOptions<C> = {},\n ): RateLimiterI<C> {\n if (!calcKey && !calcPoints) return rateLimiter\n return new WrappedRateLimiter<C>(rateLimiter, { calcKey, calcPoints })\n }\n}\n\n/**\n * Combines multiple rate limiters into one.\n *\n * The combined rate limiter will return the tightest (most restrictive) of all\n * the provided rate limiters.\n */\nexport class CombinedRateLimiter<C = unknown> implements RateLimiterI<C> {\n private constructor(\n private readonly rateLimiters: readonly RateLimiterI<C>[],\n ) {}\n\n async consume(ctx: C, opts?: RateLimiterConsumeOptions<C>) {\n const promises: ReturnType<RateLimiterConsume>[] = []\n for (const rl of this.rateLimiters) promises.push(rl.consume(ctx, opts))\n const results = await Promise.all(promises)\n\n // Compute the tightest rate limit status (the one with the least remaining points)\n let lowest: RateLimiterStatus | null = null\n for (const resp of results) {\n if (resp === null) continue\n if (lowest === null || resp.remainingPoints < lowest.remainingPoints) {\n lowest = resp\n }\n }\n\n return lowest\n }\n\n async reset(ctx: C, opts?: RateLimiterResetOptions<C>) {\n const promises: ReturnType<RateLimiterReset>[] = []\n for (const rl of this.rateLimiters) promises.push(rl.reset(ctx, opts))\n await Promise.all(promises)\n }\n\n static from<C = unknown>(\n rateLimiters: readonly RateLimiterI<C>[],\n ): RateLimiterI<C> | undefined {\n if (rateLimiters.length === 0) return undefined\n if (rateLimiters.length === 1) return rateLimiters[0]\n return new CombinedRateLimiter(rateLimiters)\n }\n}\n\nexport class RateLimitExceededError extends XRPCError {\n constructor(\n public status: RateLimiterStatus,\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.RateLimitExceeded,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.RateLimitExceeded\n )\n }\n}\n"]}
package/dist/server.d.ts CHANGED
@@ -2,7 +2,8 @@ import { IncomingMessage } from 'node:http';
2
2
  import { Express, RequestHandler, Router } from 'express';
3
3
  import { l } from '@atproto/lex-schema';
4
4
  import { LexXrpcProcedure, LexXrpcQuery, LexXrpcSubscription, LexiconDoc, Lexicons } from '@atproto/lexicon';
5
- import { RateLimiterI, RouteRateLimiter } from './rate-limiter.js';
5
+ import { HttpRateLimiter } from './rate-limiter-http.js';
6
+ import { RateLimiterI } from './rate-limiter.js';
6
7
  import { XrpcStreamServer } from './stream/index.js';
7
8
  import { Auth, AuthResult, CatchallHandler, HandlerContext, Input, LexMethodConfig, LexMethodHandler, LexSubscriptionConfig, LexSubscriptionHandler, MethodAuthContext, MethodConfig, MethodConfigOrHandler, MethodHandler, Options, Output, Params, StreamAuthContext, StreamConfig, StreamConfigOrHandler, StreamContext } from './types.js';
8
9
  import { AuthVerifierInternal, InputVerifierInternal, OutputVerifierInternal, ParamsVerifierInternal } from './util.js';
@@ -13,7 +14,7 @@ export declare class Server {
13
14
  subscriptions: Map<string, XrpcStreamServer>;
14
15
  lex: Lexicons;
15
16
  options: Options;
16
- globalRateLimiter?: RouteRateLimiter<HandlerContext>;
17
+ globalRateLimiter?: HttpRateLimiter<HandlerContext>;
17
18
  sharedRateLimiters?: Map<string, RateLimiterI<HandlerContext>>;
18
19
  constructor(lexicons?: LexiconDoc[], opts?: Options);
19
20
  listen(port: number, callback?: () => void): import("http").Server<typeof IncomingMessage, typeof import("http").ServerResponse>;
@@ -35,7 +36,7 @@ export declare class Server {
35
36
  protected addRoute<A extends Auth = Auth>(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, config: MethodConfig<A>): Promise<void>;
36
37
  catchall: CatchallHandler;
37
38
  createHandler<A extends Auth = Auth, P extends Params = Params, I extends Input = Input, O extends Output = Output>(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, cfg: MethodConfig<A, P, I, O>): RequestHandler;
38
- protected createHandlerInternal<A extends Auth, P extends Params, I extends Input, O extends Output>(authVerifier: AuthVerifierInternal<MethodAuthContext<P>, A> | null, paramsVerifier: ParamsVerifierInternal<P>, inputVerifier: InputVerifierInternal<I>, routeLimiter: RouteRateLimiter<HandlerContext<A, P, I>> | undefined, handler: MethodHandler<A, P, I, O>, validateResOutput: null | OutputVerifierInternal<O>): RequestHandler;
39
+ protected createHandlerInternal<A extends Auth, P extends Params, I extends Input, O extends Output>(authVerifier: AuthVerifierInternal<MethodAuthContext<P>, A> | null, paramsVerifier: ParamsVerifierInternal<P>, inputVerifier: InputVerifierInternal<I>, routeLimiter: HttpRateLimiter<HandlerContext<A, P, I>> | undefined, handler: MethodHandler<A, P, I, O>, validateResOutput: null | OutputVerifierInternal<O>): RequestHandler;
39
40
  protected addSubscription<A extends Auth = Auth>(nsid: string, def: LexXrpcSubscription, cfg: StreamConfig<A, Params>): Promise<void>;
40
41
  protected addSubscriptionInternal<A extends Auth, P extends Params>(nsid: string, paramsVerifier: ParamsVerifierInternal<P>, authVerifier: AuthVerifierInternal<StreamAuthContext<P>, A> | null, handler: (ctx: StreamContext<A, P>) => AsyncIterable<unknown>): void;
41
42
  private createAuthVerifier;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -6,7 +6,8 @@ import { l } from '@atproto/lex-schema';
6
6
  import { Lexicons, lexToJson, } from '@atproto/lexicon';
7
7
  import { InternalServerError, InvalidRequestError, MethodNotImplementedError, XRPCError, excludeErrorResult, } from './errors.js';
8
8
  import log, { LOGGER_NAME } from './logger.js';
9
- import { RouteRateLimiter, WrappedRateLimiter, } from './rate-limiter.js';
9
+ import { HttpRateLimiter } from './rate-limiter-http.js';
10
+ import { WrappedRateLimiter, } from './rate-limiter.js';
10
11
  import { ErrorFrame, Frame, MessageFrame, XrpcStreamServer, } from './stream/index.js';
11
12
  import { isHandlerPipeThroughBuffer, isHandlerPipeThroughStream, isHandlerSuccess, isSharedRateLimitOpts, } from './types.js';
12
13
  import { asArray, createLexiconInputVerifier, createLexiconOutputVerifier, createLexiconParamsVerifier, createSchemaInputVerifier, createSchemaOutputVerifier, createSchemaParamsVerifier, extractUrlNsid, setHeaders, } from './util.js';
@@ -75,7 +76,7 @@ export class Server {
75
76
  if (opts.rateLimits) {
76
77
  const { global, shared, creator, bypass } = opts.rateLimits;
77
78
  if (global) {
78
- this.globalRateLimiter = RouteRateLimiter.from(global.map((options) => creator(buildRateLimiterOptions(options))), { bypass });
79
+ this.globalRateLimiter = HttpRateLimiter.from(global.map((options) => creator(buildRateLimiterOptions(options))), { bypass });
79
80
  }
80
81
  if (shared) {
81
82
  this.sharedRateLimiters = new Map(shared.map((options) => [
@@ -356,8 +357,9 @@ export class Server {
356
357
  createRouteRateLimiter(nsid, config) {
357
358
  // @NOTE global & shared rate limiters are instantiated with a context of
358
359
  // HandlerContext which is compatible (more generic) with the context of
359
- // this route specific rate limiters (C). For this reason, it's safe to
360
- // cast these with an `any` context
360
+ // this route specific rate limiters (C). For this reason, it's safe to cast
361
+ // the context of the global rate limiter to the context of the route
362
+ // specific rate limiter (HandlerContext<A, P, I>).
361
363
  const globalRateLimiter = this.globalRateLimiter;
362
364
  // No route specific rate limiting configured, use the global rate limiter.
363
365
  if (!config.rateLimit)
@@ -392,7 +394,9 @@ export class Server {
392
394
  // the route specific rate limiters.
393
395
  if (globalRateLimiter)
394
396
  rateLimiters.push(globalRateLimiter);
395
- return RouteRateLimiter.from(rateLimiters, { bypass });
397
+ return HttpRateLimiter.from(rateLimiters, {
398
+ bypass,
399
+ });
396
400
  }
397
401
  }
398
402
  function createErrorMiddleware({ errorParser = (err) => XRPCError.fromError(err), }) {
@@ -447,8 +451,17 @@ function toSimplifiedErrorLike(err) {
447
451
  }
448
452
  return err;
449
453
  }
450
- function buildRateLimiterOptions({ name, calcKey = defaultKey, calcPoints = defaultPoints, ...desc }) {
451
- return { ...desc, calcKey, calcPoints, keyPrefix: `rl-${name}` };
454
+ function buildRateLimiterOptions({ name, calcKey = defaultKey, calcPoints = defaultPoints, failClosed = false, durationMs, points, }) {
455
+ return {
456
+ durationMs,
457
+ points,
458
+ calcKey,
459
+ calcPoints,
460
+ keyPrefix: `rl-${name}`,
461
+ onError: failClosed
462
+ ? undefined // Let the error propagate
463
+ : rateLimiterLoggerErrorHandler,
464
+ };
452
465
  }
453
466
  const defaultPoints = () => 1;
454
467
  /**
@@ -458,4 +471,10 @@ const defaultPoints = () => 1;
458
471
  * @see {@link https://expressjs.com/en/guide/behind-proxies.html}
459
472
  */
460
473
  const defaultKey = ({ req }) => req.ip;
474
+ async function rateLimiterLoggerErrorHandler(err, ctx, { limiter: { keyPrefix, points, duration } }) {
475
+ const { req } = ctx;
476
+ const logger = isPinoHttpRequest(req) ? req.log : log;
477
+ logger.error({ err, keyPrefix, points, duration }, 'rate limiter failed to consume points');
478
+ return null;
479
+ }
461
480
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { IncomingMessage } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport express, {\n Application,\n ErrorRequestHandler,\n Express,\n RequestHandler,\n Router,\n} from 'express'\nimport { LexValue } from '@atproto/lex-data'\nimport { l } from '@atproto/lex-schema'\nimport {\n LexXrpcProcedure,\n LexXrpcQuery,\n LexXrpcSubscription,\n LexiconDoc,\n Lexicons,\n lexToJson,\n} from '@atproto/lexicon'\nimport {\n InternalServerError,\n InvalidRequestError,\n MethodNotImplementedError,\n XRPCError,\n excludeErrorResult,\n} from './errors.js'\nimport log, { LOGGER_NAME } from './logger.js'\nimport {\n CalcKeyFn,\n CalcPointsFn,\n RateLimiterI,\n RateLimiterOptions,\n RouteRateLimiter,\n WrappedRateLimiter,\n} from './rate-limiter.js'\nimport {\n ErrorFrame,\n Frame,\n MessageFrame,\n XrpcStreamServer,\n} from './stream/index.js'\nimport {\n Auth,\n AuthResult,\n AuthVerifier,\n CatchallHandler,\n HandlerContext,\n Input,\n LexMethodConfig,\n LexMethodHandler,\n LexMethodInput,\n LexMethodOutput,\n LexMethodParams,\n LexSubscriptionConfig,\n LexSubscriptionHandler,\n MethodAuthContext,\n MethodConfig,\n MethodConfigOrHandler,\n MethodHandler,\n Options,\n Output,\n Params,\n RouteOptions,\n ServerRateLimitDescription,\n StreamAuthContext,\n StreamConfig,\n StreamConfigOrHandler,\n StreamContext,\n isHandlerPipeThroughBuffer,\n isHandlerPipeThroughStream,\n isHandlerSuccess,\n isSharedRateLimitOpts,\n} from './types.js'\nimport {\n AuthVerifierInternal,\n InputVerifierInternal,\n OutputVerifierInternal,\n ParamsVerifierInternal,\n asArray,\n createLexiconInputVerifier,\n createLexiconOutputVerifier,\n createLexiconParamsVerifier,\n createSchemaInputVerifier,\n createSchemaOutputVerifier,\n createSchemaParamsVerifier,\n extractUrlNsid,\n setHeaders,\n} from './util.js'\n\nexport function createServer(lexicons?: LexiconDoc[], options?: Options) {\n return new Server(lexicons, options)\n}\n\nexport class Server {\n router: Express = express()\n routes: Router = Router()\n subscriptions = new Map<string, XrpcStreamServer>()\n lex = new Lexicons()\n options: Options\n globalRateLimiter?: RouteRateLimiter<HandlerContext>\n sharedRateLimiters?: Map<string, RateLimiterI<HandlerContext>>\n\n constructor(lexicons?: LexiconDoc[], opts: Options = {}) {\n if (lexicons) {\n this.addLexicons(lexicons)\n }\n this.router.use(this.routes)\n this.router.use(this.catchall)\n this.router.use(createErrorMiddleware(opts))\n this.router.once('mount', (app: Application) => {\n this.enableStreamingOnListen(app)\n })\n this.options = opts\n\n if (opts.rateLimits) {\n const { global, shared, creator, bypass } = opts.rateLimits\n\n if (global) {\n this.globalRateLimiter = RouteRateLimiter.from(\n global.map((options) => creator(buildRateLimiterOptions(options))),\n { bypass },\n )\n }\n\n if (shared) {\n this.sharedRateLimiters = new Map(\n shared.map((options) => [\n options.name,\n creator(buildRateLimiterOptions(options)),\n ]),\n )\n }\n }\n }\n\n listen(port: number, callback?: () => void) {\n return this.router.listen(port, callback)\n }\n\n // handlers\n // =\n\n // Routes with auth\n add<M extends l.Procedure | l.Query | l.Subscription, A extends AuthResult>(\n ns: l.Main<M>,\n config: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, A> & { auth: Exclude<unknown, void> }\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, A> & { auth: Exclude<unknown, void> }\n : never,\n ): void\n // Routes without auth\n add<M extends l.Procedure | l.Query | l.Subscription>(\n ns: l.Main<M>,\n config: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, void> | LexMethodHandler<M, void>\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, void> | LexSubscriptionHandler<M, void>\n : never,\n ): void\n add<M extends l.Procedure | l.Query | l.Subscription, A extends Auth>(\n ns: l.Main<M>,\n configOfHandler: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, A> | LexMethodHandler<M, A>\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, A> | LexSubscriptionHandler<M, A>\n : never,\n ): void {\n const schema = l.getMain(ns)\n const config =\n typeof configOfHandler === 'function'\n ? { handler: configOfHandler }\n : configOfHandler\n switch (schema.type) {\n case 'procedure':\n return this.addProcedureSchema(\n schema,\n config as LexMethodConfig<l.Procedure, A>,\n )\n case 'query':\n return this.addQuerySchema(\n schema,\n config as LexMethodConfig<l.Query, A>,\n )\n case 'subscription':\n return this.addSubscriptionSchema(\n schema,\n config as LexSubscriptionConfig<l.Subscription, A>,\n )\n default:\n throw new TypeError(\n // @ts-expect-error should never happen\n `Unsupported schema ${schema.nsid} of type ${schema.type}`,\n )\n }\n }\n\n protected addProcedureSchema<M extends l.Procedure, A extends Auth>(\n schema: M,\n config: LexMethodConfig<M, A>,\n ): void {\n this.routes.post(\n `/xrpc/${schema.nsid}`,\n this.createHandlerInternal<\n A,\n LexMethodParams<M>,\n LexMethodInput<M>,\n LexMethodOutput<M>\n >(\n this.createAuthVerifier(config),\n this.createSchemaParamsVerifier(schema, config.opts),\n this.createSchemaInputVerifier(schema, config.opts),\n this.createRouteRateLimiter(schema.nsid, config),\n config.handler,\n this.createSchemaOutputVerifier(schema),\n ),\n )\n }\n\n protected addQuerySchema<M extends l.Query, A extends Auth>(\n schema: M,\n config: LexMethodConfig<M, A>,\n ): void {\n this.routes.get(\n `/xrpc/${schema.nsid}`,\n this.createHandlerInternal<\n A,\n LexMethodParams<M>,\n LexMethodInput<M>,\n LexMethodOutput<M>\n >(\n this.createAuthVerifier(config),\n this.createSchemaParamsVerifier(schema, config.opts),\n this.createSchemaInputVerifier(schema, config.opts),\n this.createRouteRateLimiter(schema.nsid, config),\n config.handler,\n this.createSchemaOutputVerifier(schema),\n ),\n )\n }\n\n protected addSubscriptionSchema<\n M extends l.Subscription,\n A extends Auth = void,\n >(schema: M, config: LexSubscriptionConfig<M, A>): void {\n const { handler } = config\n const messageSchema =\n this.options.validateResponse === false ? undefined : schema.message\n\n return this.addSubscriptionInternal(\n schema.nsid,\n this.createSchemaParamsVerifier(schema),\n this.createAuthVerifier(config),\n // Wrap the handler to validate outgoing messages if a message schema\n // is available\n messageSchema\n ? async function* (ctx) {\n for await (const item of handler(ctx)) {\n if (item instanceof Frame) {\n messageSchema.validate(item.body)\n yield item\n } else {\n yield messageSchema.validate(item)\n }\n }\n }\n : handler,\n )\n }\n\n method<A extends Auth = Auth>(\n nsid: string,\n configOrFn: MethodConfigOrHandler<A>,\n ): void {\n this.addMethod(nsid, configOrFn)\n }\n\n addMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: MethodConfigOrHandler<A>,\n ) {\n const config =\n typeof configOrFn === 'function' ? { handler: configOrFn } : configOrFn\n if (config.opts && 'paramsParseLoose' in config.opts) {\n throw new Error(\n `paramsParseLoose is not supported with method(), use add() instead`,\n )\n }\n const def = this.lex.getDef(nsid)\n if (def?.type === 'query' || def?.type === 'procedure') {\n this.addRoute(nsid, def, config)\n } else {\n throw new Error(`Lex def for ${nsid} is not a query or a procedure`)\n }\n }\n\n streamMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: StreamConfigOrHandler<A, Params>,\n ) {\n this.addStreamMethod(nsid, configOrFn)\n }\n\n addStreamMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: StreamConfigOrHandler<A, Params>,\n ) {\n const config =\n typeof configOrFn === 'function' ? { handler: configOrFn } : configOrFn\n const def = this.lex.getDef(nsid)\n if (def?.type === 'subscription') {\n this.addSubscription(nsid, def, config)\n } else {\n throw new Error(`Lex def for ${nsid} is not a subscription`)\n }\n }\n\n // schemas\n // =\n\n addLexicon(doc: LexiconDoc) {\n this.lex.add(doc)\n }\n\n addLexicons(docs: LexiconDoc[]) {\n for (const doc of docs) {\n this.addLexicon(doc)\n }\n }\n\n // http\n // =\n\n protected async addRoute<A extends Auth = Auth>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n config: MethodConfig<A>,\n ) {\n const path = `/xrpc/${nsid}`\n const handler = this.createHandler(nsid, def, config)\n\n if (def.type === 'procedure') {\n this.routes.post(path, handler)\n } else {\n this.routes.get(path, handler)\n }\n }\n\n catchall: CatchallHandler = async (req, res, next) => {\n // catchall handler only applies to XRPC routes\n if (!req.url.startsWith('/xrpc/')) return next()\n\n // Validate the NSID\n const nsid = extractUrlNsid(req.url)\n if (!nsid) {\n return next(new InvalidRequestError('invalid xrpc path'))\n }\n\n if (this.globalRateLimiter) {\n try {\n await this.globalRateLimiter.handle({\n req,\n res,\n auth: undefined,\n params: {},\n input: undefined,\n async resetRouteRateLimits() {},\n })\n } catch (err) {\n return next(err)\n }\n }\n\n // Ensure that known XRPC methods are only called with the correct HTTP\n // method.\n const def = this.lex.getDef(nsid)\n if (def) {\n const expectedMethod =\n def.type === 'procedure' ? 'POST' : def.type === 'query' ? 'GET' : null\n if (expectedMethod != null && expectedMethod !== req.method) {\n return next(\n new InvalidRequestError(\n `Incorrect HTTP method (${req.method}) expected ${expectedMethod}`,\n ),\n )\n }\n }\n\n if (this.options.catchall) {\n this.options.catchall.call(null, req, res, next)\n } else if (!def) {\n next(new MethodNotImplementedError())\n } else {\n next()\n }\n }\n\n createHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n O extends Output = Output,\n >(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n cfg: MethodConfig<A, P, I, O>,\n ): RequestHandler {\n return this.createHandlerInternal<A, P, I, O>(\n this.createAuthVerifier(cfg),\n this.createLexiconParamsVerifier<P>(nsid, def),\n this.createLexiconInputVerifier<I>(nsid, def, cfg.opts),\n this.createRouteRateLimiter(nsid, cfg),\n cfg.handler,\n this.createLexiconOutputVerifier<O>(nsid, def),\n )\n }\n\n protected createHandlerInternal<\n A extends Auth,\n P extends Params,\n I extends Input,\n O extends Output,\n >(\n authVerifier: AuthVerifierInternal<MethodAuthContext<P>, A> | null,\n paramsVerifier: ParamsVerifierInternal<P>,\n inputVerifier: InputVerifierInternal<I>,\n routeLimiter: RouteRateLimiter<HandlerContext<A, P, I>> | undefined,\n handler: MethodHandler<A, P, I, O>,\n validateResOutput: null | OutputVerifierInternal<O>,\n ): RequestHandler {\n return async function (req, res, next) {\n try {\n // parse & validate params\n const params = paramsVerifier(req)\n\n // authenticate request\n const auth: A = authVerifier\n ? await authVerifier({ req, res, params })\n : (undefined as A)\n\n // parse & validate input\n const input: I = await inputVerifier(req, res)\n\n const ctx: HandlerContext<A, P, I> = {\n params,\n input,\n auth,\n req,\n res,\n resetRouteRateLimits: async () => routeLimiter?.reset(ctx),\n }\n\n // handle rate limits\n if (routeLimiter) await routeLimiter.handle(ctx)\n\n // run the handler\n const output = (await handler(ctx)) as O\n\n if (!output) {\n validateResOutput?.(output)\n res.status(200)\n res.end()\n } else if (isHandlerPipeThroughStream(output)) {\n setHeaders(res, output.headers)\n res.status(200)\n res.header('Content-Type', output.encoding)\n await pipeline(output.stream, res)\n } else if (isHandlerPipeThroughBuffer(output)) {\n setHeaders(res, output.headers)\n res.status(200)\n res.header('Content-Type', output.encoding)\n res.end(output.buffer)\n } else if (isHandlerSuccess(output)) {\n validateResOutput?.(output)\n\n res.status(200)\n setHeaders(res, output.headers)\n\n const encoding =\n output.encoding === 'json' ? 'application/json' : output.encoding\n\n res.header('Content-Type', encoding)\n\n if (output.body instanceof Readable) {\n // The \"Readable\" check comes first to avoid calling \"lexToJson\" on\n // a stream, which would be a bug.\n await pipeline(output.body, res)\n } else if (encoding === 'application/json') {\n const json = lexToJson(output.body)\n res.json(json)\n } else {\n res.send(\n Buffer.isBuffer(output.body)\n ? output.body\n : output.body instanceof Uint8Array\n ? Buffer.from(output.body)\n : output.body,\n )\n }\n } else {\n next(XRPCError.fromError(output))\n }\n } catch (err: unknown) {\n // Express will not call the next middleware (errorMiddleware in this case)\n // if the value passed to next is false-y (e.g. null, undefined, 0).\n // Hence we replace it with an InternalServerError.\n if (!err) {\n next(new InternalServerError())\n } else {\n next(err)\n }\n }\n }\n }\n\n protected async addSubscription<A extends Auth = Auth>(\n nsid: string,\n def: LexXrpcSubscription,\n cfg: StreamConfig<A, Params>,\n ) {\n this.addSubscriptionInternal(\n nsid,\n this.createLexiconParamsVerifier(nsid, def),\n this.createAuthVerifier(cfg),\n // @NOTE outgoing messages are not validated against the lexicon schema\n // (unlike the handlers for @atproto/lex based subscriptions)\n cfg.handler,\n )\n }\n\n protected addSubscriptionInternal<A extends Auth, P extends Params>(\n nsid: string,\n paramsVerifier: ParamsVerifierInternal<P>,\n authVerifier: AuthVerifierInternal<StreamAuthContext<P>, A> | null,\n handler: (ctx: StreamContext<A, P>) => AsyncIterable<unknown>,\n ) {\n this.subscriptions.set(\n nsid,\n new XrpcStreamServer({\n noServer: true,\n handler: async function* (req, signal) {\n try {\n // validate request\n const params = paramsVerifier(req)\n\n // authenticate request\n const auth = authVerifier\n ? await authVerifier({ req, params })\n : (undefined as A)\n\n // stream\n for await (const item of handler({ req, params, auth, signal })) {\n yield item instanceof Frame\n ? item\n : MessageFrame.fromLexValue(item as LexValue, nsid)\n }\n } catch (err) {\n yield ErrorFrame.fromError(err)\n }\n },\n }),\n )\n }\n\n private createAuthVerifier<C, A extends AuthResult>(cfg: {\n auth?: AuthVerifier<C, A>\n }): null | AuthVerifierInternal<C, A> {\n const { auth } = cfg\n if (!auth) return null\n\n return async (ctx) => {\n const result = await auth(ctx)\n return excludeErrorResult(result)\n }\n }\n\n private createLexiconParamsVerifier<P extends Params = Params>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure | LexXrpcSubscription,\n ) {\n return createLexiconParamsVerifier<P>(nsid, def, this.lex)\n }\n\n private createLexiconInputVerifier<I extends Input = Input>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n opts?: RouteOptions,\n ): InputVerifierInternal<I> {\n return createLexiconInputVerifier(\n nsid,\n def,\n {\n blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,\n jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,\n textLimit: opts?.textLimit ?? this.options.payload?.textLimit,\n },\n this.lex,\n )\n }\n\n private createLexiconOutputVerifier<O extends Output = Output>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n ): null | OutputVerifierInternal<O> {\n if (this.options.validateResponse === false) {\n return null\n }\n return createLexiconOutputVerifier(nsid, def, this.lex)\n }\n\n private createSchemaParamsVerifier<\n M extends l.Procedure | l.Query | l.Subscription,\n >(\n ns: l.Main<M>,\n opts?: RouteOptions,\n ): ParamsVerifierInternal<LexMethodParams<M>> {\n return createSchemaParamsVerifier<M>(ns, opts)\n }\n\n private createSchemaInputVerifier<M extends l.Procedure | l.Query>(\n ns: l.Main<M>,\n opts?: RouteOptions,\n ): InputVerifierInternal<LexMethodInput<M>> {\n return createSchemaInputVerifier<M>(ns, {\n blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,\n jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,\n textLimit: opts?.textLimit ?? this.options.payload?.textLimit,\n })\n }\n\n private createSchemaOutputVerifier<M extends l.Procedure | l.Query>(\n ns: l.Main<M>,\n ): null | OutputVerifierInternal<LexMethodOutput<M>> {\n if (this.options.validateResponse === false) {\n return null\n }\n return createSchemaOutputVerifier<M>(ns)\n }\n\n private enableStreamingOnListen(app: Application) {\n const _listen = app.listen\n app.listen = (...args) => {\n // @ts-ignore the args spread\n const httpServer = _listen.call(app, ...args)\n httpServer.on('upgrade', (req, socket, head) => {\n const nsid = req.url ? extractUrlNsid(req.url) : undefined\n const sub = nsid ? this.subscriptions.get(nsid) : undefined\n if (!sub) return socket.destroy()\n sub.wss.handleUpgrade(req, socket, head, (ws) =>\n sub.wss.emit('connection', ws, req),\n )\n })\n return httpServer\n }\n }\n\n private createRouteRateLimiter<\n A extends Auth,\n P extends Params,\n I extends Input,\n O extends Output,\n >(\n nsid: string,\n config: MethodConfig<A, P, I, O>,\n ): RouteRateLimiter<HandlerContext<A, P, I>> | undefined {\n // @NOTE global & shared rate limiters are instantiated with a context of\n // HandlerContext which is compatible (more generic) with the context of\n // this route specific rate limiters (C). For this reason, it's safe to\n // cast these with an `any` context\n\n const globalRateLimiter = this.globalRateLimiter as\n | RouteRateLimiter<any>\n | undefined\n\n // No route specific rate limiting configured, use the global rate limiter.\n if (!config.rateLimit) return globalRateLimiter\n\n const { rateLimits } = this.options\n\n // @NOTE Silently ignore creation of route specific rate limiter if the\n // `rateLimits` options was not provided to the constructor.\n if (!rateLimits) return globalRateLimiter\n\n const { creator, bypass } = rateLimits\n\n const rateLimiters = asArray(config.rateLimit).map((options, i) => {\n if (isSharedRateLimitOpts(options)) {\n const rateLimiter = this.sharedRateLimiters?.get(options.name)\n\n // The route config references a shared rate limiter that does not\n // exist. This is a configuration error.\n assert(rateLimiter, `Shared rate limiter \"${options.name}\" not defined`)\n\n return WrappedRateLimiter.from<any>(rateLimiter, options)\n } else {\n return creator({\n ...options,\n calcKey: options.calcKey ?? defaultKey,\n calcPoints: options.calcPoints ?? defaultPoints,\n keyPrefix: `${nsid}-${i}`,\n })\n }\n })\n\n // If the route config contains an empty array, use global rate limiter.\n if (!rateLimiters.length) return globalRateLimiter\n\n // The global rate limiter (if present) should be applied in addition to\n // the route specific rate limiters.\n if (globalRateLimiter) rateLimiters.push(globalRateLimiter)\n\n return RouteRateLimiter.from<any>(rateLimiters, { bypass })\n }\n}\n\nfunction createErrorMiddleware({\n errorParser = (err) => XRPCError.fromError(err),\n}: Options): ErrorRequestHandler {\n return (err, req, res, next) => {\n const nsid = extractUrlNsid(req.originalUrl)\n const xrpcError = errorParser(err)\n\n // Use the request's logger (if available) to benefit from request context\n // (id, timing) and logging configuration (serialization, etc.).\n const logger = isPinoHttpRequest(req) ? req.log : log\n\n const isInternalError = xrpcError instanceof InternalServerError\n\n const msgPrefix = isInternalError ? 'unhandled exception' : 'error'\n const msgSuffix = nsid ? `xrpc method ${nsid}` : `${req.method} ${req.url}`\n const msg = `${msgPrefix} in ${msgSuffix}`\n\n logger.error(\n {\n // @NOTE Computation of error stack is an expensive operation, so\n // we strip it for expected errors.\n err:\n isInternalError || process.env.NODE_ENV === 'development'\n ? err\n : toSimplifiedErrorLike(err),\n\n // XRPC specific properties, for easier browsing of logs\n nsid,\n type: xrpcError.type,\n status: xrpcError.statusCode,\n payload: xrpcError.payload,\n\n // Ensure that the logged item's name is set to LOGGER_NAME, instead of\n // the name of the pino-http logger, to ensure consistency across logs.\n name: LOGGER_NAME,\n },\n msg,\n )\n\n if (res.headersSent) {\n return next(err)\n }\n\n return res.status(xrpcError.statusCode).json(xrpcError.payload)\n }\n}\n\nfunction isPinoHttpRequest(req: IncomingMessage): req is IncomingMessage & {\n log: { error: (obj: unknown, msg: string) => void }\n} {\n return typeof (req as { log?: any }).log?.error === 'function'\n}\n\nfunction toSimplifiedErrorLike(err: unknown): unknown {\n if (err instanceof Error) {\n // Transform into an \"ErrorLike\" for pino's std \"err\" serializer\n return {\n ...err,\n // Carry over non-enumerable properties\n message: err.message,\n name:\n !Object.hasOwn(err, 'name') &&\n Object.prototype.toString.call(err.constructor) === '[object Function]'\n ? err.constructor.name // extract the class name for sub-classes of Error\n : err.name,\n // @NOTE Error.stack, Error.cause and AggregateError.error are non\n // enumerable properties so they won't be spread to the ErrorLike\n }\n }\n\n return err\n}\n\nfunction buildRateLimiterOptions<C extends HandlerContext = HandlerContext>({\n name,\n calcKey = defaultKey,\n calcPoints = defaultPoints,\n ...desc\n}: ServerRateLimitDescription<C>): RateLimiterOptions<C> {\n return { ...desc, calcKey, calcPoints, keyPrefix: `rl-${name}` }\n}\n\nconst defaultPoints: CalcPointsFn = () => 1\n\n/**\n * @note when using a proxy, ensure headers are getting forwarded correctly:\n * `app.set('trust proxy', true)`\n *\n * @see {@link https://expressjs.com/en/guide/behind-proxies.html}\n */\nconst defaultKey: CalcKeyFn<HandlerContext> = ({ req }) => req.ip\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { IncomingMessage } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport express, {\n Application,\n ErrorRequestHandler,\n Express,\n RequestHandler,\n Router,\n} from 'express'\nimport { LexValue } from '@atproto/lex-data'\nimport { l } from '@atproto/lex-schema'\nimport {\n LexXrpcProcedure,\n LexXrpcQuery,\n LexXrpcSubscription,\n LexiconDoc,\n Lexicons,\n lexToJson,\n} from '@atproto/lexicon'\nimport {\n InternalServerError,\n InvalidRequestError,\n MethodNotImplementedError,\n XRPCError,\n excludeErrorResult,\n} from './errors.js'\nimport log, { LOGGER_NAME } from './logger.js'\nimport { HttpRateLimiter } from './rate-limiter-http.js'\nimport {\n CalcKeyFn,\n CalcPointsFn,\n RateLimiterErrorHandlerDetails,\n RateLimiterI,\n RateLimiterOptions,\n WrappedRateLimiter,\n} from './rate-limiter.js'\nimport {\n ErrorFrame,\n Frame,\n MessageFrame,\n XrpcStreamServer,\n} from './stream/index.js'\nimport {\n Auth,\n AuthResult,\n AuthVerifier,\n CatchallHandler,\n HandlerContext,\n Input,\n LexMethodConfig,\n LexMethodHandler,\n LexMethodInput,\n LexMethodOutput,\n LexMethodParams,\n LexSubscriptionConfig,\n LexSubscriptionHandler,\n MethodAuthContext,\n MethodConfig,\n MethodConfigOrHandler,\n MethodHandler,\n Options,\n Output,\n Params,\n RouteOptions,\n ServerRateLimitDescription,\n StreamAuthContext,\n StreamConfig,\n StreamConfigOrHandler,\n StreamContext,\n isHandlerPipeThroughBuffer,\n isHandlerPipeThroughStream,\n isHandlerSuccess,\n isSharedRateLimitOpts,\n} from './types.js'\nimport {\n AuthVerifierInternal,\n InputVerifierInternal,\n OutputVerifierInternal,\n ParamsVerifierInternal,\n asArray,\n createLexiconInputVerifier,\n createLexiconOutputVerifier,\n createLexiconParamsVerifier,\n createSchemaInputVerifier,\n createSchemaOutputVerifier,\n createSchemaParamsVerifier,\n extractUrlNsid,\n setHeaders,\n} from './util.js'\n\nexport function createServer(lexicons?: LexiconDoc[], options?: Options) {\n return new Server(lexicons, options)\n}\n\nexport class Server {\n router: Express = express()\n routes: Router = Router()\n subscriptions = new Map<string, XrpcStreamServer>()\n lex = new Lexicons()\n options: Options\n globalRateLimiter?: HttpRateLimiter<HandlerContext>\n sharedRateLimiters?: Map<string, RateLimiterI<HandlerContext>>\n\n constructor(lexicons?: LexiconDoc[], opts: Options = {}) {\n if (lexicons) {\n this.addLexicons(lexicons)\n }\n this.router.use(this.routes)\n this.router.use(this.catchall)\n this.router.use(createErrorMiddleware(opts))\n this.router.once('mount', (app: Application) => {\n this.enableStreamingOnListen(app)\n })\n this.options = opts\n\n if (opts.rateLimits) {\n const { global, shared, creator, bypass } = opts.rateLimits\n\n if (global) {\n this.globalRateLimiter = HttpRateLimiter.from(\n global.map((options) => creator(buildRateLimiterOptions(options))),\n { bypass },\n )\n }\n\n if (shared) {\n this.sharedRateLimiters = new Map(\n shared.map((options) => [\n options.name,\n creator(buildRateLimiterOptions(options)),\n ]),\n )\n }\n }\n }\n\n listen(port: number, callback?: () => void) {\n return this.router.listen(port, callback)\n }\n\n // handlers\n // =\n\n // Routes with auth\n add<M extends l.Procedure | l.Query | l.Subscription, A extends AuthResult>(\n ns: l.Main<M>,\n config: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, A> & { auth: Exclude<unknown, void> }\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, A> & { auth: Exclude<unknown, void> }\n : never,\n ): void\n // Routes without auth\n add<M extends l.Procedure | l.Query | l.Subscription>(\n ns: l.Main<M>,\n config: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, void> | LexMethodHandler<M, void>\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, void> | LexSubscriptionHandler<M, void>\n : never,\n ): void\n add<M extends l.Procedure | l.Query | l.Subscription, A extends Auth>(\n ns: l.Main<M>,\n configOfHandler: M extends l.Procedure | l.Query\n ? LexMethodConfig<M, A> | LexMethodHandler<M, A>\n : M extends l.Subscription\n ? LexSubscriptionConfig<M, A> | LexSubscriptionHandler<M, A>\n : never,\n ): void {\n const schema = l.getMain(ns)\n const config =\n typeof configOfHandler === 'function'\n ? { handler: configOfHandler }\n : configOfHandler\n switch (schema.type) {\n case 'procedure':\n return this.addProcedureSchema(\n schema,\n config as LexMethodConfig<l.Procedure, A>,\n )\n case 'query':\n return this.addQuerySchema(\n schema,\n config as LexMethodConfig<l.Query, A>,\n )\n case 'subscription':\n return this.addSubscriptionSchema(\n schema,\n config as LexSubscriptionConfig<l.Subscription, A>,\n )\n default:\n throw new TypeError(\n // @ts-expect-error should never happen\n `Unsupported schema ${schema.nsid} of type ${schema.type}`,\n )\n }\n }\n\n protected addProcedureSchema<M extends l.Procedure, A extends Auth>(\n schema: M,\n config: LexMethodConfig<M, A>,\n ): void {\n this.routes.post(\n `/xrpc/${schema.nsid}`,\n this.createHandlerInternal<\n A,\n LexMethodParams<M>,\n LexMethodInput<M>,\n LexMethodOutput<M>\n >(\n this.createAuthVerifier(config),\n this.createSchemaParamsVerifier(schema, config.opts),\n this.createSchemaInputVerifier(schema, config.opts),\n this.createRouteRateLimiter(schema.nsid, config),\n config.handler,\n this.createSchemaOutputVerifier(schema),\n ),\n )\n }\n\n protected addQuerySchema<M extends l.Query, A extends Auth>(\n schema: M,\n config: LexMethodConfig<M, A>,\n ): void {\n this.routes.get(\n `/xrpc/${schema.nsid}`,\n this.createHandlerInternal<\n A,\n LexMethodParams<M>,\n LexMethodInput<M>,\n LexMethodOutput<M>\n >(\n this.createAuthVerifier(config),\n this.createSchemaParamsVerifier(schema, config.opts),\n this.createSchemaInputVerifier(schema, config.opts),\n this.createRouteRateLimiter(schema.nsid, config),\n config.handler,\n this.createSchemaOutputVerifier(schema),\n ),\n )\n }\n\n protected addSubscriptionSchema<\n M extends l.Subscription,\n A extends Auth = void,\n >(schema: M, config: LexSubscriptionConfig<M, A>): void {\n const { handler } = config\n const messageSchema =\n this.options.validateResponse === false ? undefined : schema.message\n\n return this.addSubscriptionInternal(\n schema.nsid,\n this.createSchemaParamsVerifier(schema),\n this.createAuthVerifier(config),\n // Wrap the handler to validate outgoing messages if a message schema\n // is available\n messageSchema\n ? async function* (ctx) {\n for await (const item of handler(ctx)) {\n if (item instanceof Frame) {\n messageSchema.validate(item.body)\n yield item\n } else {\n yield messageSchema.validate(item)\n }\n }\n }\n : handler,\n )\n }\n\n method<A extends Auth = Auth>(\n nsid: string,\n configOrFn: MethodConfigOrHandler<A>,\n ): void {\n this.addMethod(nsid, configOrFn)\n }\n\n addMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: MethodConfigOrHandler<A>,\n ) {\n const config =\n typeof configOrFn === 'function' ? { handler: configOrFn } : configOrFn\n if (config.opts && 'paramsParseLoose' in config.opts) {\n throw new Error(\n `paramsParseLoose is not supported with method(), use add() instead`,\n )\n }\n const def = this.lex.getDef(nsid)\n if (def?.type === 'query' || def?.type === 'procedure') {\n this.addRoute(nsid, def, config)\n } else {\n throw new Error(`Lex def for ${nsid} is not a query or a procedure`)\n }\n }\n\n streamMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: StreamConfigOrHandler<A, Params>,\n ) {\n this.addStreamMethod(nsid, configOrFn)\n }\n\n addStreamMethod<A extends Auth = Auth>(\n nsid: string,\n configOrFn: StreamConfigOrHandler<A, Params>,\n ) {\n const config =\n typeof configOrFn === 'function' ? { handler: configOrFn } : configOrFn\n const def = this.lex.getDef(nsid)\n if (def?.type === 'subscription') {\n this.addSubscription(nsid, def, config)\n } else {\n throw new Error(`Lex def for ${nsid} is not a subscription`)\n }\n }\n\n // schemas\n // =\n\n addLexicon(doc: LexiconDoc) {\n this.lex.add(doc)\n }\n\n addLexicons(docs: LexiconDoc[]) {\n for (const doc of docs) {\n this.addLexicon(doc)\n }\n }\n\n // http\n // =\n\n protected async addRoute<A extends Auth = Auth>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n config: MethodConfig<A>,\n ) {\n const path = `/xrpc/${nsid}`\n const handler = this.createHandler(nsid, def, config)\n\n if (def.type === 'procedure') {\n this.routes.post(path, handler)\n } else {\n this.routes.get(path, handler)\n }\n }\n\n catchall: CatchallHandler = async (req, res, next) => {\n // catchall handler only applies to XRPC routes\n if (!req.url.startsWith('/xrpc/')) return next()\n\n // Validate the NSID\n const nsid = extractUrlNsid(req.url)\n if (!nsid) {\n return next(new InvalidRequestError('invalid xrpc path'))\n }\n\n if (this.globalRateLimiter) {\n try {\n await this.globalRateLimiter.handle({\n req,\n res,\n auth: undefined,\n params: {},\n input: undefined,\n async resetRouteRateLimits() {},\n })\n } catch (err) {\n return next(err)\n }\n }\n\n // Ensure that known XRPC methods are only called with the correct HTTP\n // method.\n const def = this.lex.getDef(nsid)\n if (def) {\n const expectedMethod =\n def.type === 'procedure' ? 'POST' : def.type === 'query' ? 'GET' : null\n if (expectedMethod != null && expectedMethod !== req.method) {\n return next(\n new InvalidRequestError(\n `Incorrect HTTP method (${req.method}) expected ${expectedMethod}`,\n ),\n )\n }\n }\n\n if (this.options.catchall) {\n this.options.catchall.call(null, req, res, next)\n } else if (!def) {\n next(new MethodNotImplementedError())\n } else {\n next()\n }\n }\n\n createHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n O extends Output = Output,\n >(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n cfg: MethodConfig<A, P, I, O>,\n ): RequestHandler {\n return this.createHandlerInternal<A, P, I, O>(\n this.createAuthVerifier(cfg),\n this.createLexiconParamsVerifier<P>(nsid, def),\n this.createLexiconInputVerifier<I>(nsid, def, cfg.opts),\n this.createRouteRateLimiter(nsid, cfg),\n cfg.handler,\n this.createLexiconOutputVerifier<O>(nsid, def),\n )\n }\n\n protected createHandlerInternal<\n A extends Auth,\n P extends Params,\n I extends Input,\n O extends Output,\n >(\n authVerifier: AuthVerifierInternal<MethodAuthContext<P>, A> | null,\n paramsVerifier: ParamsVerifierInternal<P>,\n inputVerifier: InputVerifierInternal<I>,\n routeLimiter: HttpRateLimiter<HandlerContext<A, P, I>> | undefined,\n handler: MethodHandler<A, P, I, O>,\n validateResOutput: null | OutputVerifierInternal<O>,\n ): RequestHandler {\n return async function (req, res, next) {\n try {\n // parse & validate params\n const params = paramsVerifier(req)\n\n // authenticate request\n const auth: A = authVerifier\n ? await authVerifier({ req, res, params })\n : (undefined as A)\n\n // parse & validate input\n const input: I = await inputVerifier(req, res)\n\n const ctx: HandlerContext<A, P, I> = {\n params,\n input,\n auth,\n req,\n res,\n resetRouteRateLimits: async () => routeLimiter?.reset(ctx),\n }\n\n // handle rate limits\n if (routeLimiter) await routeLimiter.handle(ctx)\n\n // run the handler\n const output = (await handler(ctx)) as O\n\n if (!output) {\n validateResOutput?.(output)\n res.status(200)\n res.end()\n } else if (isHandlerPipeThroughStream(output)) {\n setHeaders(res, output.headers)\n res.status(200)\n res.header('Content-Type', output.encoding)\n await pipeline(output.stream, res)\n } else if (isHandlerPipeThroughBuffer(output)) {\n setHeaders(res, output.headers)\n res.status(200)\n res.header('Content-Type', output.encoding)\n res.end(output.buffer)\n } else if (isHandlerSuccess(output)) {\n validateResOutput?.(output)\n\n res.status(200)\n setHeaders(res, output.headers)\n\n const encoding =\n output.encoding === 'json' ? 'application/json' : output.encoding\n\n res.header('Content-Type', encoding)\n\n if (output.body instanceof Readable) {\n // The \"Readable\" check comes first to avoid calling \"lexToJson\" on\n // a stream, which would be a bug.\n await pipeline(output.body, res)\n } else if (encoding === 'application/json') {\n const json = lexToJson(output.body)\n res.json(json)\n } else {\n res.send(\n Buffer.isBuffer(output.body)\n ? output.body\n : output.body instanceof Uint8Array\n ? Buffer.from(output.body)\n : output.body,\n )\n }\n } else {\n next(XRPCError.fromError(output))\n }\n } catch (err: unknown) {\n // Express will not call the next middleware (errorMiddleware in this case)\n // if the value passed to next is false-y (e.g. null, undefined, 0).\n // Hence we replace it with an InternalServerError.\n if (!err) {\n next(new InternalServerError())\n } else {\n next(err)\n }\n }\n }\n }\n\n protected async addSubscription<A extends Auth = Auth>(\n nsid: string,\n def: LexXrpcSubscription,\n cfg: StreamConfig<A, Params>,\n ) {\n this.addSubscriptionInternal(\n nsid,\n this.createLexiconParamsVerifier(nsid, def),\n this.createAuthVerifier(cfg),\n // @NOTE outgoing messages are not validated against the lexicon schema\n // (unlike the handlers for @atproto/lex based subscriptions)\n cfg.handler,\n )\n }\n\n protected addSubscriptionInternal<A extends Auth, P extends Params>(\n nsid: string,\n paramsVerifier: ParamsVerifierInternal<P>,\n authVerifier: AuthVerifierInternal<StreamAuthContext<P>, A> | null,\n handler: (ctx: StreamContext<A, P>) => AsyncIterable<unknown>,\n ) {\n this.subscriptions.set(\n nsid,\n new XrpcStreamServer({\n noServer: true,\n handler: async function* (req, signal) {\n try {\n // validate request\n const params = paramsVerifier(req)\n\n // authenticate request\n const auth = authVerifier\n ? await authVerifier({ req, params })\n : (undefined as A)\n\n // stream\n for await (const item of handler({ req, params, auth, signal })) {\n yield item instanceof Frame\n ? item\n : MessageFrame.fromLexValue(item as LexValue, nsid)\n }\n } catch (err) {\n yield ErrorFrame.fromError(err)\n }\n },\n }),\n )\n }\n\n private createAuthVerifier<C, A extends AuthResult>(cfg: {\n auth?: AuthVerifier<C, A>\n }): null | AuthVerifierInternal<C, A> {\n const { auth } = cfg\n if (!auth) return null\n\n return async (ctx) => {\n const result = await auth(ctx)\n return excludeErrorResult(result)\n }\n }\n\n private createLexiconParamsVerifier<P extends Params = Params>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure | LexXrpcSubscription,\n ) {\n return createLexiconParamsVerifier<P>(nsid, def, this.lex)\n }\n\n private createLexiconInputVerifier<I extends Input = Input>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n opts?: RouteOptions,\n ): InputVerifierInternal<I> {\n return createLexiconInputVerifier(\n nsid,\n def,\n {\n blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,\n jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,\n textLimit: opts?.textLimit ?? this.options.payload?.textLimit,\n },\n this.lex,\n )\n }\n\n private createLexiconOutputVerifier<O extends Output = Output>(\n nsid: string,\n def: LexXrpcQuery | LexXrpcProcedure,\n ): null | OutputVerifierInternal<O> {\n if (this.options.validateResponse === false) {\n return null\n }\n return createLexiconOutputVerifier(nsid, def, this.lex)\n }\n\n private createSchemaParamsVerifier<\n M extends l.Procedure | l.Query | l.Subscription,\n >(\n ns: l.Main<M>,\n opts?: RouteOptions,\n ): ParamsVerifierInternal<LexMethodParams<M>> {\n return createSchemaParamsVerifier<M>(ns, opts)\n }\n\n private createSchemaInputVerifier<M extends l.Procedure | l.Query>(\n ns: l.Main<M>,\n opts?: RouteOptions,\n ): InputVerifierInternal<LexMethodInput<M>> {\n return createSchemaInputVerifier<M>(ns, {\n blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,\n jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,\n textLimit: opts?.textLimit ?? this.options.payload?.textLimit,\n })\n }\n\n private createSchemaOutputVerifier<M extends l.Procedure | l.Query>(\n ns: l.Main<M>,\n ): null | OutputVerifierInternal<LexMethodOutput<M>> {\n if (this.options.validateResponse === false) {\n return null\n }\n return createSchemaOutputVerifier<M>(ns)\n }\n\n private enableStreamingOnListen(app: Application) {\n const _listen = app.listen\n app.listen = (...args) => {\n // @ts-ignore the args spread\n const httpServer = _listen.call(app, ...args)\n httpServer.on('upgrade', (req, socket, head) => {\n const nsid = req.url ? extractUrlNsid(req.url) : undefined\n const sub = nsid ? this.subscriptions.get(nsid) : undefined\n if (!sub) return socket.destroy()\n sub.wss.handleUpgrade(req, socket, head, (ws) =>\n sub.wss.emit('connection', ws, req),\n )\n })\n return httpServer\n }\n }\n\n private createRouteRateLimiter<\n A extends Auth,\n P extends Params,\n I extends Input,\n O extends Output,\n >(\n nsid: string,\n config: MethodConfig<A, P, I, O>,\n ): HttpRateLimiter<HandlerContext<A, P, I>> | undefined {\n // @NOTE global & shared rate limiters are instantiated with a context of\n // HandlerContext which is compatible (more generic) with the context of\n // this route specific rate limiters (C). For this reason, it's safe to cast\n // the context of the global rate limiter to the context of the route\n // specific rate limiter (HandlerContext<A, P, I>).\n\n const globalRateLimiter = this.globalRateLimiter as\n | HttpRateLimiter<HandlerContext<A, P, I>>\n | undefined\n\n // No route specific rate limiting configured, use the global rate limiter.\n if (!config.rateLimit) return globalRateLimiter\n\n const { rateLimits } = this.options\n\n // @NOTE Silently ignore creation of route specific rate limiter if the\n // `rateLimits` options was not provided to the constructor.\n if (!rateLimits) return globalRateLimiter\n\n const { creator, bypass } = rateLimits\n\n const rateLimiters = asArray(config.rateLimit).map((options, i) => {\n if (isSharedRateLimitOpts(options)) {\n const rateLimiter = this.sharedRateLimiters?.get(options.name) as\n | RateLimiterI<HandlerContext<A, P, I>>\n | undefined\n\n // The route config references a shared rate limiter that does not\n // exist. This is a configuration error.\n assert(rateLimiter, `Shared rate limiter \"${options.name}\" not defined`)\n\n return WrappedRateLimiter.from<HandlerContext<A, P, I>>(\n rateLimiter,\n options,\n )\n } else {\n return creator({\n ...options,\n calcKey: options.calcKey ?? defaultKey,\n calcPoints: options.calcPoints ?? defaultPoints,\n keyPrefix: `${nsid}-${i}`,\n })\n }\n })\n\n // If the route config contains an empty array, use global rate limiter.\n if (!rateLimiters.length) return globalRateLimiter\n\n // The global rate limiter (if present) should be applied in addition to\n // the route specific rate limiters.\n if (globalRateLimiter) rateLimiters.push(globalRateLimiter)\n\n return HttpRateLimiter.from<HandlerContext<A, P, I>>(rateLimiters, {\n bypass,\n })\n }\n}\n\nfunction createErrorMiddleware({\n errorParser = (err) => XRPCError.fromError(err),\n}: Options): ErrorRequestHandler {\n return (err, req, res, next) => {\n const nsid = extractUrlNsid(req.originalUrl)\n const xrpcError = errorParser(err)\n\n // Use the request's logger (if available) to benefit from request context\n // (id, timing) and logging configuration (serialization, etc.).\n const logger = isPinoHttpRequest(req) ? req.log : log\n\n const isInternalError = xrpcError instanceof InternalServerError\n\n const msgPrefix = isInternalError ? 'unhandled exception' : 'error'\n const msgSuffix = nsid ? `xrpc method ${nsid}` : `${req.method} ${req.url}`\n const msg = `${msgPrefix} in ${msgSuffix}`\n\n logger.error(\n {\n // @NOTE Computation of error stack is an expensive operation, so\n // we strip it for expected errors.\n err:\n isInternalError || process.env.NODE_ENV === 'development'\n ? err\n : toSimplifiedErrorLike(err),\n\n // XRPC specific properties, for easier browsing of logs\n nsid,\n type: xrpcError.type,\n status: xrpcError.statusCode,\n payload: xrpcError.payload,\n\n // Ensure that the logged item's name is set to LOGGER_NAME, instead of\n // the name of the pino-http logger, to ensure consistency across logs.\n name: LOGGER_NAME,\n },\n msg,\n )\n\n if (res.headersSent) {\n return next(err)\n }\n\n return res.status(xrpcError.statusCode).json(xrpcError.payload)\n }\n}\n\nfunction isPinoHttpRequest(req: IncomingMessage): req is IncomingMessage & {\n log: { error: (obj: unknown, msg: string) => void }\n} {\n return typeof (req as { log?: any }).log?.error === 'function'\n}\n\nfunction toSimplifiedErrorLike(err: unknown): unknown {\n if (err instanceof Error) {\n // Transform into an \"ErrorLike\" for pino's std \"err\" serializer\n return {\n ...err,\n // Carry over non-enumerable properties\n message: err.message,\n name:\n !Object.hasOwn(err, 'name') &&\n Object.prototype.toString.call(err.constructor) === '[object Function]'\n ? err.constructor.name // extract the class name for sub-classes of Error\n : err.name,\n // @NOTE Error.stack, Error.cause and AggregateError.error are non\n // enumerable properties so they won't be spread to the ErrorLike\n }\n }\n\n return err\n}\n\nfunction buildRateLimiterOptions<C extends HandlerContext = HandlerContext>({\n name,\n calcKey = defaultKey,\n calcPoints = defaultPoints,\n failClosed = false,\n durationMs,\n points,\n}: ServerRateLimitDescription<C>): RateLimiterOptions<C> {\n return {\n durationMs,\n points,\n calcKey,\n calcPoints,\n keyPrefix: `rl-${name}`,\n onError: failClosed\n ? undefined // Let the error propagate\n : rateLimiterLoggerErrorHandler,\n }\n}\n\nconst defaultPoints: CalcPointsFn = () => 1\n\n/**\n * @note when using a proxy, ensure headers are getting forwarded correctly:\n * `app.set('trust proxy', true)`\n *\n * @see {@link https://expressjs.com/en/guide/behind-proxies.html}\n */\nconst defaultKey: CalcKeyFn<HandlerContext> = ({ req }) => req.ip\n\nasync function rateLimiterLoggerErrorHandler(\n err: unknown,\n ctx: HandlerContext,\n { limiter: { keyPrefix, points, duration } }: RateLimiterErrorHandlerDetails,\n): Promise<null> {\n const { req } = ctx\n const logger = isPinoHttpRequest(req) ? req.log : log\n\n logger.error(\n { err, keyPrefix, points, duration },\n 'rate limiter failed to consume points',\n )\n\n return null\n}\n"]}
@@ -7,7 +7,7 @@ export declare abstract class Frame<T extends LexValue = LexValue> {
7
7
  toBytes(): Uint8Array;
8
8
  isMessage(): this is MessageFrame;
9
9
  isError(): this is ErrorFrame;
10
- static fromBytes(bytes: Uint8Array): MessageFrame<LexValue> | ErrorFrame<string>;
10
+ static fromBytes(bytes: Uint8Array): ErrorFrame<string> | MessageFrame<LexValue>;
11
11
  }
12
12
  export declare class MessageFrame<T extends LexValue = LexValue> extends Frame<T> {
13
13
  header: MessageFrameHeader;
@@ -16,9 +16,9 @@ export declare class MessageFrame<T extends LexValue = LexValue> extends Frame<T
16
16
  type?: string;
17
17
  });
18
18
  get type(): string | undefined;
19
- static fromLexValue(data: LexValue, nsid: string): MessageFrame<import("@atproto/lex-data").LexScalar | LexValue[]> | MessageFrame<{
19
+ static fromLexValue(data: LexValue, nsid: string): MessageFrame<{
20
20
  [x: string]: LexValue | undefined;
21
- }>;
21
+ }> | MessageFrame<LexValue[] | import("@atproto/lex-data").LexScalar>;
22
22
  }
23
23
  export declare class ErrorFrame<T extends string = string> extends Frame<ErrorFrameBody<T>> {
24
24
  header: ErrorFrameHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../src/stream/frames.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAiB,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,kBAAkB,EAGnB,MAAM,YAAY,CAAA;AAEnB,8BAAsB,KAAK,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAEhB,IAAI,EAAE,IAAI,SAAS,CAElB;IACD,OAAO,IAAI,UAAU;IAGrB,SAAS,IAAI,IAAI,IAAI,YAAY;IAGjC,OAAO,IAAI,IAAI,IAAI,UAAU;IAG7B,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU;CA8BnC;AAED,qBAAa,YAAY,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,CAAE,SAAQ,KAAK,CAAC,CAAC,CAAC;IACvE,MAAM,EAAE,kBAAkB,CAAA;IAC1B,IAAI,EAAE,CAAC,CAAA;gBAEK,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;IAQ7C,IAAI,IAAI,uBAEP;IAED,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM;;;CAsBjD;AAED,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK,CAC9D,cAAc,CAAC,CAAC,CAAC,CAClB;IACC,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;gBAEX,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IAKnC,IAAI,IAAI,MAEP;IACD,IAAI,OAAO,uBAEV;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU;CAK3C"}
1
+ {"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../src/stream/frames.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAiB,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,kBAAkB,EAGnB,MAAM,YAAY,CAAA;AAEnB,8BAAsB,KAAK,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IACvD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAEhB,IAAI,EAAE,IAAI,SAAS,CAElB;IACD,OAAO,IAAI,UAAU,CAEpB;IACD,SAAS,IAAI,IAAI,IAAI,YAAY,CAEhC;IACD,OAAO,IAAI,IAAI,IAAI,UAAU,CAE5B;IACD,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,+CA6BjC;CACF;AAED,qBAAa,YAAY,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,CAAE,SAAQ,KAAK,CAAC,CAAC,CAAC;IACvE,MAAM,EAAE,kBAAkB,CAAA;IAC1B,IAAI,EAAE,CAAC,CAAA;IAEP,YAAY,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAO5C;IACD,IAAI,IAAI,uBAEP;IAED,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM;;0EAqB/C;CACF;AAED,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,KAAK,CAC9D,cAAc,CAAC,CAAC,CAAC,CAClB;IACC,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IAEvB,YAAY,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EAIlC;IACD,IAAI,IAAI,MAEP;IACD,IAAI,OAAO,uBAEV;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAIzC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/stream/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,eAAO,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CACtB,CAAA;AAEhC,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/stream/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,eAAO,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CACtB,CAAA;eAEjB,MAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/stream/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAE/C,OAAO,EAAc,KAAK,EAAE,MAAM,aAAa,CAAA;AAG/C,qBAAa,gBAAgB;IAC3B,GAAG,EAAE,eAAe,CAAA;gBACR,IAAI,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE;CAqCvD;AAED,MAAM,MAAM,OAAO,GAAG,CACpB,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,gBAAgB,KACrB,aAAa,CAAC,KAAK,CAAC,CAAA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/stream/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAE/C,OAAO,EAAc,KAAK,EAAE,MAAM,aAAa,CAAA;AAG/C,qBAAa,gBAAgB;IAC3B,GAAG,EAAE,eAAe,CAAA;IACpB,YAAY,IAAI,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,EAoCrD;CACF;AAED,MAAM,MAAM,OAAO,GAAG,CACpB,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,gBAAgB,KACrB,aAAa,CAAC,KAAK,CAAC,CAAA"}
@@ -2,7 +2,7 @@ import { DuplexOptions } from 'node:stream';
2
2
  import { WebSocket } from 'ws';
3
3
  import { MessageFrame } from './frames.js';
4
4
  export declare function streamByteChunks(ws: WebSocket, options?: DuplexOptions): import("stream").Duplex;
5
- export declare function byFrame(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<import("@atproto/lex-data").LexValue> | import("./frames.js").ErrorFrame<string>, void, unknown>;
5
+ export declare function byFrame(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<import("./frames.js").ErrorFrame<string> | MessageFrame<import("@atproto/lex-data").LexValue>, void, unknown>;
6
6
  export declare function byMessage(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<import("@atproto/lex-data").LexValue>, void, unknown>;
7
7
  export declare function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame;
8
8
  //# sourceMappingURL=stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAKvC,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IAE1B,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd;gBAhBM,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd;IAGI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC;CA4BnD;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAKvC,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IAE1B,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd;IAjBH,YACS,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd,EACC;IAEG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CA2BjD;CACF;eAEc,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ClientOptions } from 'ws'\nimport { isPlainObject } from '@atproto/lex-data'\nimport { WebSocketKeepAlive } from '@atproto/ws-client'\nimport { ensureChunkIsMessage } from './stream.js'\n\nexport class Subscription<T = unknown> {\n constructor(\n public opts: ClientOptions & {\n service: string\n method: string\n maxReconnectSeconds?: number\n heartbeatIntervalMs?: number\n signal?: AbortSignal\n validate: (obj: unknown) => T | undefined\n onReconnectError?: (\n error: unknown,\n n: number,\n initialSetup: boolean,\n ) => void\n getParams?: () =>\n | Record<string, unknown>\n | Promise<Record<string, unknown> | undefined>\n | undefined\n },\n ) {}\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n const ws = new WebSocketKeepAlive({\n ...this.opts,\n getUrl: async () => {\n const params = (await this.opts.getParams?.()) ?? {}\n const query = encodeQueryParams(params)\n return `${this.opts.service}/xrpc/${this.opts.method}?${query}`\n },\n })\n for await (const chunk of ws) {\n const message = ensureChunkIsMessage(chunk)\n const t = message.header.t\n\n const typedBody = isPlainObject(message.body)\n ? t !== undefined\n ? {\n ...message.body,\n $type: t.startsWith('#') ? this.opts.method + t : t,\n }\n : message.body\n : undefined\n\n const result = this.opts.validate(typedBody)\n if (result !== undefined) {\n yield result\n }\n }\n }\n}\n\nexport default Subscription\n\nfunction encodeQueryParams(obj: Record<string, unknown>): string {\n const params = new URLSearchParams()\n Object.entries(obj).forEach(([key, value]) => {\n const encoded = encodeQueryParam(value)\n if (Array.isArray(encoded)) {\n encoded.forEach((enc) => params.append(key, enc))\n } else {\n params.set(key, encoded)\n }\n })\n return params.toString()\n}\n\n// Adapted from xrpc, but without any lex-specific knowledge\nfunction encodeQueryParam(value: unknown): string | string[] {\n if (typeof value === 'string') {\n return value\n }\n if (typeof value === 'number') {\n return value.toString()\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'undefined') {\n return ''\n }\n if (typeof value === 'object') {\n if (value instanceof Date) {\n return value.toISOString()\n } else if (Array.isArray(value)) {\n return value.flatMap(encodeQueryParam)\n } else if (!value) {\n return ''\n }\n }\n throw new Error(`Cannot encode ${typeof value}s into query params`)\n}\n"]}
1
+ {"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ClientOptions } from 'ws'\nimport { isPlainObject } from '@atproto/lex-data'\nimport { WebSocketKeepAlive } from '@atproto/ws-client'\nimport { ensureChunkIsMessage } from './stream.js'\n\nexport class Subscription<T = unknown> {\n constructor(\n public opts: ClientOptions & {\n service: string\n method: string\n maxReconnectSeconds?: number\n heartbeatIntervalMs?: number\n signal?: AbortSignal\n validate: (obj: unknown) => T | undefined\n onReconnectError?: (\n error: unknown,\n n: number,\n initialSetup: boolean,\n ) => void\n getParams?: () =>\n | Record<string, unknown>\n | Promise<Record<string, unknown> | undefined>\n | undefined\n },\n ) {}\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n const ws = new WebSocketKeepAlive({\n ...this.opts,\n getUrl: async () => {\n const params = (await this.opts.getParams?.()) ?? {}\n const query = encodeQueryParams(params)\n return `${this.opts.service}/xrpc/${this.opts.method}?${query}`\n },\n })\n for await (const chunk of ws) {\n const message = ensureChunkIsMessage(chunk)\n const t = message.header.t\n\n const typedBody = isPlainObject(message.body)\n ? t !== undefined\n ? {\n ...message.body,\n $type: t.startsWith('#') ? this.opts.method + t : t,\n }\n : message.body\n : undefined\n\n const result = this.opts.validate(typedBody)\n if (result !== undefined) {\n yield result\n }\n }\n }\n}\n\nexport default Subscription\n\nfunction encodeQueryParams(obj: Record<string, unknown>): string {\n const params = new URLSearchParams()\n Object.entries(obj).forEach(([key, value]) => {\n const encoded = encodeQueryParam(value)\n if (Array.isArray(encoded)) {\n encoded.forEach((enc) => params.append(key, enc))\n } else {\n params.set(key, encoded)\n }\n })\n return params.toString()\n}\n\n// Adapted from xrpc, but without any lex-specific knowledge\nfunction encodeQueryParam(value: unknown): string | string[] {\n if (typeof value === 'string') {\n return value\n }\n if (typeof value === 'number') {\n return value.toString()\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'undefined') {\n return ''\n }\n if (typeof value === 'object') {\n if (value instanceof Date) {\n return value.toISOString()\n } else if (Array.isArray(value)) {\n return value.flatMap(encodeQueryParam)\n } else if (!value) {\n return ''\n }\n }\n throw new Error(`Cannot encode ${typeof value}s into query params`)\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}