@atproto/lex-server 0.0.19 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atproto/lex-server
2
2
 
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
8
+
9
+ - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
10
+
11
+ Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
12
+
13
+ - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0.
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [[`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c), [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9), [`affb50c`](https://github.com/bluesky-social/atproto/commit/affb50c040b497a12631df99a6310f8e78cab557), [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705)]:
18
+ - @atproto/crypto@0.5.0
19
+ - @atproto/did@0.4.0
20
+ - @atproto/lex-cbor@0.1.0
21
+ - @atproto/lex-client@0.1.0
22
+ - @atproto/lex-data@0.1.0
23
+ - @atproto/lex-json@0.1.0
24
+ - @atproto/lex-schema@0.1.0
25
+ - @atproto-labs/did-resolver@0.3.0
26
+
3
27
  ## 0.0.19
4
28
 
5
29
  ### Patch Changes
package/dist/errors.js CHANGED
@@ -1,24 +1,18 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexServerAuthError = exports.LexServerError = exports.LexError = void 0;
4
- const lex_client_1 = require("@atproto/lex-client");
5
- const lex_data_1 = require("@atproto/lex-data");
6
- Object.defineProperty(exports, "LexError", { enumerable: true, get: function () { return lex_data_1.LexError; } });
7
- const lex_schema_1 = require("@atproto/lex-schema");
8
- const www_authenticate_js_1 = require("./lib/www-authenticate.js");
1
+ import { XrpcError } from '@atproto/lex-client';
2
+ import { LexError } from '@atproto/lex-data';
3
+ import { LexValidationError } from '@atproto/lex-schema';
4
+ import { formatWWWAuthenticateHeader, } from './lib/www-authenticate.js';
5
+ export { LexError };
9
6
  /**
10
7
  * Base error class for representing errors that should be converted to XRPC
11
8
  * error responses.
12
9
  */
13
- class LexServerError extends lex_data_1.LexError {
14
- status;
15
- body;
16
- name = 'LexServerError';
17
- headers;
10
+ export class LexServerError extends LexError {
18
11
  constructor(status, body, headers, options) {
19
12
  super(body.error, body.message, options);
20
13
  this.status = status;
21
14
  this.body = body;
15
+ this.name = 'LexServerError';
22
16
  this.headers = headers ? new Headers(headers) : undefined;
23
17
  }
24
18
  toJSON() {
@@ -34,18 +28,18 @@ class LexServerError extends lex_data_1.LexError {
34
28
  return cause;
35
29
  }
36
30
  // Convert @atproto/lex-client errors to downstream LexServerError
37
- if (cause instanceof lex_client_1.XrpcError) {
31
+ if (cause instanceof XrpcError) {
38
32
  const { status, body, headers } = cause.toDownstreamError();
39
33
  return new LexServerError(status, body, headers, { cause });
40
34
  }
41
35
  // Convert @atproto/lex-schema validation errors to 400 Bad Request
42
- if (cause instanceof lex_schema_1.LexValidationError) {
36
+ if (cause instanceof LexValidationError) {
43
37
  return new LexServerError(400, cause.toJSON(), undefined, {
44
38
  cause,
45
39
  });
46
40
  }
47
41
  // Any other error is treated as a generic 500 Internal Server Error
48
- if (cause instanceof lex_data_1.LexError) {
42
+ if (cause instanceof LexError) {
49
43
  return new LexServerError(500, cause.toJSON(), undefined, {
50
44
  cause,
51
45
  });
@@ -53,7 +47,6 @@ class LexServerError extends lex_data_1.LexError {
53
47
  return new LexServerError(500, { error: 'InternalServerError', message: 'An internal error occurred' }, undefined, { cause });
54
48
  }
55
49
  }
56
- exports.LexServerError = LexServerError;
57
50
  /**
58
51
  * Error class for authentication failures in XRPC server handlers.
59
52
  *
@@ -75,9 +68,7 @@ exports.LexServerError = LexServerError;
75
68
  * )
76
69
  * ```
77
70
  */
78
- class LexServerAuthError extends LexServerError {
79
- wwwAuthenticate;
80
- name = 'LexServerAuthError';
71
+ export class LexServerAuthError extends LexServerError {
81
72
  /**
82
73
  * Creates a new authentication error.
83
74
  *
@@ -89,12 +80,13 @@ class LexServerAuthError extends LexServerError {
89
80
  constructor(error, message, wwwAuthenticate = {}, options) {
90
81
  const headers = Object.keys(wwwAuthenticate).length
91
82
  ? new Headers({
92
- 'WWW-Authenticate': (0, www_authenticate_js_1.formatWWWAuthenticateHeader)(wwwAuthenticate),
83
+ 'WWW-Authenticate': formatWWWAuthenticateHeader(wwwAuthenticate),
93
84
  'Access-Control-Expose-Headers': 'WWW-Authenticate', // CORS
94
85
  })
95
86
  : undefined;
96
87
  super(401, { error, message }, headers, options);
97
88
  this.wwwAuthenticate = wwwAuthenticate;
89
+ this.name = 'LexServerAuthError';
98
90
  }
99
91
  /**
100
92
  * Creates a LexServerAuthError from an existing LexError.
@@ -123,11 +115,10 @@ class LexServerAuthError extends LexServerError {
123
115
  if (cause instanceof LexServerAuthError) {
124
116
  return cause;
125
117
  }
126
- if (cause instanceof lex_data_1.LexError) {
118
+ if (cause instanceof LexError) {
127
119
  return new LexServerAuthError(cause.error, cause.message, wwwAuthenticate, { cause });
128
120
  }
129
121
  return new LexServerAuthError('AuthenticationRequired', 'Authentication failed', wwwAuthenticate, { cause });
130
122
  }
131
123
  }
132
- exports.LexServerAuthError = LexServerAuthError;
133
124
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { XrpcError } from '@atproto/lex-client'\nimport { LexError, LexErrorCode, LexErrorData } from '@atproto/lex-data'\nimport { LexValidationError } from '@atproto/lex-schema'\nimport {\n WWWAuthenticate,\n formatWWWAuthenticateHeader,\n} from './lib/www-authenticate.js'\n\nexport { LexError }\nexport type { LexErrorCode, LexErrorData, WWWAuthenticate }\n\n/**\n * Base error class for representing errors that should be converted to XRPC\n * error responses.\n */\nexport class LexServerError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexError<N> {\n name = 'LexServerError'\n\n readonly headers?: Headers\n\n constructor(\n readonly status: number,\n readonly body: LexErrorData<N>,\n headers?: HeadersInit,\n options?: ErrorOptions,\n ) {\n super(body.error, body.message, options)\n this.headers = headers ? new Headers(headers) : undefined\n }\n\n override toJSON(): LexErrorData<N> {\n return this.body\n }\n\n public toResponse(): Response {\n const { status, headers } = this\n // @NOTE using this.toJSON() instead of this.body to allow overrides in subclasses\n return Response.json(this.toJSON(), { status, headers })\n }\n\n static from(cause: unknown): LexServerError {\n if (cause instanceof LexServerError) {\n return cause\n }\n\n // Convert @atproto/lex-client errors to downstream LexServerError\n if (cause instanceof XrpcError) {\n const { status, body, headers } = cause.toDownstreamError()\n return new LexServerError(status, body, headers, { cause })\n }\n\n // Convert @atproto/lex-schema validation errors to 400 Bad Request\n if (cause instanceof LexValidationError) {\n return new LexServerError(400, cause.toJSON(), undefined, {\n cause,\n })\n }\n\n // Any other error is treated as a generic 500 Internal Server Error\n if (cause instanceof LexError) {\n return new LexServerError(500, cause.toJSON(), undefined, {\n cause,\n })\n }\n\n return new LexServerError(\n 500,\n { error: 'InternalServerError', message: 'An internal error occurred' },\n undefined,\n { cause },\n )\n }\n}\n\n/**\n * Error class for authentication failures in XRPC server handlers.\n *\n * Extends {@link LexError} to include WWW-Authenticate header support,\n * which is required by HTTP authentication standards (RFC 7235).\n * The error automatically generates the appropriate 401 response with\n * the WWW-Authenticate header when converted to a Response.\n *\n * @typeParam N - The Lexicon error code type\n *\n * @example Throwing an auth error\n * ```typescript\n * import { LexServerAuthError } from '@atproto/lex-server'\n *\n * throw new LexServerAuthError(\n * 'AuthenticationRequired',\n * 'Invalid or expired token',\n * { Bearer: { error: 'InvalidToken', realm: 'api.example.com' } }\n * )\n * ```\n */\nexport class LexServerAuthError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexServerError<N> {\n name = 'LexServerAuthError'\n\n /**\n * Creates a new authentication error.\n *\n * @param error - The Lexicon error code (e.g., 'AuthenticationRequired')\n * @param message - Human-readable error message\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @param options - Standard Error options including `cause`\n */\n constructor(\n error: N,\n message: string,\n readonly wwwAuthenticate: WWWAuthenticate = {},\n options?: ErrorOptions,\n ) {\n const headers = Object.keys(wwwAuthenticate).length\n ? new Headers({\n 'WWW-Authenticate': formatWWWAuthenticateHeader(wwwAuthenticate),\n 'Access-Control-Expose-Headers': 'WWW-Authenticate', // CORS\n })\n : undefined\n super(401, { error, message }, headers, options)\n }\n\n /**\n * Creates a LexServerAuthError from an existing LexError.\n *\n * If the input is already a LexServerAuthError, returns it unchanged.\n * Otherwise, wraps the error with the provided WWW-Authenticate parameters.\n *\n * @param cause - The original LexError to wrap\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @returns A LexServerAuthError instance\n *\n * @example\n * ```typescript\n * function authenticate(token: string): Promise<User> {\n * try {\n * return await validateToken(token)\n * } catch (cause) {\n * throw LexServerAuthError.from(cause, {\n * Bearer: { error: 'InvalidToken' }\n * })\n * }\n * }\n * ```\n */\n static from(\n cause: unknown,\n wwwAuthenticate?: WWWAuthenticate,\n ): LexServerAuthError {\n if (cause instanceof LexServerAuthError) {\n return cause\n }\n\n if (cause instanceof LexError) {\n return new LexServerAuthError(\n cause.error,\n cause.message,\n wwwAuthenticate,\n { cause },\n )\n }\n\n return new LexServerAuthError(\n 'AuthenticationRequired',\n 'Authentication failed',\n wwwAuthenticate,\n { cause },\n )\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { XrpcError } from '@atproto/lex-client'\nimport { LexError, LexErrorCode, LexErrorData } from '@atproto/lex-data'\nimport { LexValidationError } from '@atproto/lex-schema'\nimport {\n WWWAuthenticate,\n formatWWWAuthenticateHeader,\n} from './lib/www-authenticate.js'\n\nexport { LexError }\nexport type { LexErrorCode, LexErrorData, WWWAuthenticate }\n\n/**\n * Base error class for representing errors that should be converted to XRPC\n * error responses.\n */\nexport class LexServerError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexError<N> {\n name = 'LexServerError'\n\n readonly headers?: Headers\n\n constructor(\n readonly status: number,\n readonly body: LexErrorData<N>,\n headers?: HeadersInit,\n options?: ErrorOptions,\n ) {\n super(body.error, body.message, options)\n this.headers = headers ? new Headers(headers) : undefined\n }\n\n override toJSON(): LexErrorData<N> {\n return this.body\n }\n\n public toResponse(): Response {\n const { status, headers } = this\n // @NOTE using this.toJSON() instead of this.body to allow overrides in subclasses\n return Response.json(this.toJSON(), { status, headers })\n }\n\n static from(cause: unknown): LexServerError {\n if (cause instanceof LexServerError) {\n return cause\n }\n\n // Convert @atproto/lex-client errors to downstream LexServerError\n if (cause instanceof XrpcError) {\n const { status, body, headers } = cause.toDownstreamError()\n return new LexServerError(status, body, headers, { cause })\n }\n\n // Convert @atproto/lex-schema validation errors to 400 Bad Request\n if (cause instanceof LexValidationError) {\n return new LexServerError(400, cause.toJSON(), undefined, {\n cause,\n })\n }\n\n // Any other error is treated as a generic 500 Internal Server Error\n if (cause instanceof LexError) {\n return new LexServerError(500, cause.toJSON(), undefined, {\n cause,\n })\n }\n\n return new LexServerError(\n 500,\n { error: 'InternalServerError', message: 'An internal error occurred' },\n undefined,\n { cause },\n )\n }\n}\n\n/**\n * Error class for authentication failures in XRPC server handlers.\n *\n * Extends {@link LexError} to include WWW-Authenticate header support,\n * which is required by HTTP authentication standards (RFC 7235).\n * The error automatically generates the appropriate 401 response with\n * the WWW-Authenticate header when converted to a Response.\n *\n * @typeParam N - The Lexicon error code type\n *\n * @example Throwing an auth error\n * ```typescript\n * import { LexServerAuthError } from '@atproto/lex-server'\n *\n * throw new LexServerAuthError(\n * 'AuthenticationRequired',\n * 'Invalid or expired token',\n * { Bearer: { error: 'InvalidToken', realm: 'api.example.com' } }\n * )\n * ```\n */\nexport class LexServerAuthError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexServerError<N> {\n name = 'LexServerAuthError'\n\n /**\n * Creates a new authentication error.\n *\n * @param error - The Lexicon error code (e.g., 'AuthenticationRequired')\n * @param message - Human-readable error message\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @param options - Standard Error options including `cause`\n */\n constructor(\n error: N,\n message: string,\n readonly wwwAuthenticate: WWWAuthenticate = {},\n options?: ErrorOptions,\n ) {\n const headers = Object.keys(wwwAuthenticate).length\n ? new Headers({\n 'WWW-Authenticate': formatWWWAuthenticateHeader(wwwAuthenticate),\n 'Access-Control-Expose-Headers': 'WWW-Authenticate', // CORS\n })\n : undefined\n super(401, { error, message }, headers, options)\n }\n\n /**\n * Creates a LexServerAuthError from an existing LexError.\n *\n * If the input is already a LexServerAuthError, returns it unchanged.\n * Otherwise, wraps the error with the provided WWW-Authenticate parameters.\n *\n * @param cause - The original LexError to wrap\n * @param wwwAuthenticate - WWW-Authenticate header parameters\n * @returns A LexServerAuthError instance\n *\n * @example\n * ```typescript\n * function authenticate(token: string): Promise<User> {\n * try {\n * return await validateToken(token)\n * } catch (cause) {\n * throw LexServerAuthError.from(cause, {\n * Bearer: { error: 'InvalidToken' }\n * })\n * }\n * }\n * ```\n */\n static from(\n cause: unknown,\n wwwAuthenticate?: WWWAuthenticate,\n ): LexServerAuthError {\n if (cause instanceof LexServerAuthError) {\n return cause\n }\n\n if (cause instanceof LexError) {\n return new LexServerAuthError(\n cause.error,\n cause.message,\n wwwAuthenticate,\n { cause },\n )\n }\n\n return new LexServerAuthError(\n 'AuthenticationRequired',\n 'Authentication failed',\n wwwAuthenticate,\n { cause },\n )\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./errors.js"), exports);
5
- tslib_1.__exportStar(require("./lex-router.js"), exports);
6
- tslib_1.__exportStar(require("./service-auth.js"), exports);
1
+ export * from './errors.js';
2
+ export * from './lex-router.js';
3
+ export * from './service-auth.js';
7
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,sDAA2B;AAC3B,0DAA+B;AAC/B,4DAAiC","sourcesContent":["export * from './errors.js'\nexport * from './lex-router.js'\nexport * from './service-auth.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA","sourcesContent":["export * from './errors.js'\nexport * from './lex-router.js'\nexport * from './service-auth.js'\n"]}
@@ -427,7 +427,7 @@ export type LexRouterOptions = {
427
427
  * ```typescript
428
428
  * import { LexRouter } from '@atproto/lex-server'
429
429
  * import { serve, upgradeWebSocket } from '@atproto/lex-server/nodejs'
430
- * import { getProfile, createPost, subscribeRepos } from './lexicons'
430
+ * import { getProfile, createPost, subscribeRepos } from './lexicons.js'
431
431
  *
432
432
  * const router = new LexRouter({ upgradeWebSocket })
433
433
  *
@@ -1 +1 @@
1
- {"version":3,"file":"lex-router.d.ts","sourceRoot":"","sources":["../src/lex-router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lex-router.d.ts","sourceRoot":"","sources":["../src/lex-router.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexRouter = void 0;
4
- const lex_cbor_1 = require("@atproto/lex-cbor");
5
- const lex_data_1 = require("@atproto/lex-data");
6
- const lex_json_1 = require("@atproto/lex-json");
7
- const lex_schema_1 = require("@atproto/lex-schema");
8
- const errors_js_1 = require("./errors.js");
9
- const drain_websocket_js_1 = require("./lib/drain-websocket.js");
1
+ import { encode } from '@atproto/lex-cbor';
2
+ import { LexError, isPlainObject, ui8Concat, } from '@atproto/lex-data';
3
+ import { lexParse, lexToJson } from '@atproto/lex-json';
4
+ import { getMain, isDidString, isNsidString, } from '@atproto/lex-schema';
5
+ import { LexServerError } from './errors.js';
6
+ import { drainWebsocket } from './lib/drain-websocket.js';
10
7
  const XRPC_PATH_PREFIX = '/xrpc/';
11
8
  const XRPC_HEALTH_CHECK_PATH = '/xrpc/_health';
12
9
  /**
@@ -20,7 +17,7 @@ const XRPC_HEALTH_CHECK_PATH = '/xrpc/_health';
20
17
  * ```typescript
21
18
  * import { LexRouter } from '@atproto/lex-server'
22
19
  * import { serve, upgradeWebSocket } from '@atproto/lex-server/nodejs'
23
- * import { getProfile, createPost, subscribeRepos } from './lexicons'
20
+ * import { getProfile, createPost, subscribeRepos } from './lexicons.js'
24
21
  *
25
22
  * const router = new LexRouter({ upgradeWebSocket })
26
23
  *
@@ -77,10 +74,7 @@ const XRPC_HEALTH_CHECK_PATH = '/xrpc/_health';
77
74
  * })
78
75
  * ```
79
76
  */
80
- class LexRouter {
81
- options;
82
- /** Map of NSID strings to their fetch handlers. */
83
- handlers = new Map();
77
+ export class LexRouter {
84
78
  /**
85
79
  * Creates a new XRPC router.
86
80
  *
@@ -88,9 +82,88 @@ class LexRouter {
88
82
  */
89
83
  constructor(options = {}) {
90
84
  this.options = options;
85
+ /** Map of NSID strings to their fetch handlers. */
86
+ this.handlers = new Map();
87
+ /**
88
+ * The main fetch handler for processing XRPC requests.
89
+ *
90
+ * Routes incoming requests to the appropriate method handler based on the
91
+ * NSID in the URL path. Returns appropriate error responses for invalid
92
+ * paths or unimplemented methods.
93
+ *
94
+ * This handler can be used directly with HTTP servers that support the
95
+ * fetch API pattern, or converted to a Node.js request listener using
96
+ * `toRequestListener()`.
97
+ *
98
+ * @param request - The incoming HTTP request
99
+ * @param connection - Optional connection metadata
100
+ * @returns A promise resolving to the HTTP response
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * // Use with Deno
105
+ * Deno.serve(router.fetch)
106
+ *
107
+ * // Use with Bun
108
+ * Bun.serve({ fetch: router.fetch })
109
+ *
110
+ * // Use with Node.js
111
+ * import { toRequestListener } from '@atproto/lex-server/nodejs'
112
+ * const listener = toRequestListener(router.fetch)
113
+ * http.createServer(listener).listen(3000)
114
+ * ```
115
+ */
116
+ this.fetch = async (request, connection) => {
117
+ const { pathname } = new URL(request.url);
118
+ const atprotoProxy = request.headers.get('atproto-proxy');
119
+ if (!pathname.startsWith(XRPC_PATH_PREFIX)) {
120
+ // Handle non XRPC paths
121
+ const { fallback } = this.options;
122
+ if (fallback)
123
+ return fallback(request, connection);
124
+ return new Response('Not Found', { status: 404 });
125
+ }
126
+ if (pathname === XRPC_HEALTH_CHECK_PATH) {
127
+ if (request.method !== 'GET') {
128
+ return invalidRequestResponse('Method not allowed', 405);
129
+ }
130
+ if (atprotoProxy != null) {
131
+ return invalidRequestResponse('atproto-proxy header is not allowed on health check endpoint');
132
+ }
133
+ const { healthCheck } = this.options;
134
+ const data = healthCheck ? await healthCheck(request) : { status: 'ok' };
135
+ return Response.json(data);
136
+ }
137
+ const subPath = pathname.slice(XRPC_PATH_PREFIX.length);
138
+ if (!isNsidString(subPath)) {
139
+ return invalidRequestResponse('Invalid NSID in URL path');
140
+ }
141
+ const nsid = normalizeNsid(subPath);
142
+ if (atprotoProxy == null) {
143
+ const handler = this.handlers.get(nsid);
144
+ if (handler)
145
+ return handler(request, connection);
146
+ }
147
+ else {
148
+ // Handle service proxying logic.
149
+ const proxyInfo = parseAtprotoProxyHeader(atprotoProxy);
150
+ if (!proxyInfo) {
151
+ return invalidRequestResponse(`Invalid atproto-proxy header value: ${atprotoProxy}`);
152
+ }
153
+ // @TODO actually implement service proxying logic here. The reason it was
154
+ // not done already is because we want to perform all the heavy lifting
155
+ // here, while still allowing the possibility to override the endpoint
156
+ // resolution, etc.
157
+ // @NOTE see ./service-auth.ts for potential common code (did resolver, etc.)
158
+ }
159
+ return Response.json({
160
+ error: 'MethodNotImplemented',
161
+ message: `XRPC method "${nsid}" not implemented on this server`,
162
+ }, { status: 501 });
163
+ };
91
164
  }
92
165
  add(ns, config) {
93
- const method = (0, lex_schema_1.getMain)(ns);
166
+ const method = getMain(ns);
94
167
  const nsid = normalizeNsid(method.nsid);
95
168
  if (this.handlers.has(nsid)) {
96
169
  throw new TypeError(`Method ${method.nsid} already registered`);
@@ -140,7 +213,7 @@ class LexRouter {
140
213
  return new Response(null, { status: 200, headers: output.headers });
141
214
  }
142
215
  if (method.output?.encoding === 'application/json') {
143
- return Response.json((0, lex_json_1.lexToJson)(output.body), {
216
+ return Response.json(lexToJson(output.body), {
144
217
  status: 200,
145
218
  headers: output.headers,
146
219
  });
@@ -227,7 +300,7 @@ class LexRouter {
227
300
  socket.send(data);
228
301
  // Apply backpressure by waiting for the buffered data to drain
229
302
  // before generating the next message
230
- await (0, drain_websocket_js_1.drainWebsocket)(socket, signal, this.options);
303
+ await drainWebsocket(socket, signal, this.options);
231
304
  }
232
305
  if (socket.readyState === 1) {
233
306
  socket.close(1000);
@@ -236,7 +309,7 @@ class LexRouter {
236
309
  catch (error) {
237
310
  // If the socket is still open, send an error frame before closing
238
311
  if (socket.readyState === 1) {
239
- const isLexError = error instanceof lex_data_1.LexError;
312
+ const isLexError = error instanceof LexError;
240
313
  // https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
241
314
  const code = isLexError && method.errors?.includes(error.error)
242
315
  ? 1008 // Policy Violation for known LexErrors
@@ -276,91 +349,13 @@ class LexRouter {
276
349
  if (isAbortReason(request.signal, cause)) {
277
350
  return Response.json({ error: 'RequestAborted' }, { status: 499 });
278
351
  }
279
- const error = errors_js_1.LexServerError.from(cause);
352
+ const error = LexServerError.from(cause);
280
353
  const { onHandlerError } = this.options;
281
354
  if (onHandlerError)
282
355
  await onHandlerError({ error, request, method });
283
356
  return error.toResponse();
284
357
  }
285
- /**
286
- * The main fetch handler for processing XRPC requests.
287
- *
288
- * Routes incoming requests to the appropriate method handler based on the
289
- * NSID in the URL path. Returns appropriate error responses for invalid
290
- * paths or unimplemented methods.
291
- *
292
- * This handler can be used directly with HTTP servers that support the
293
- * fetch API pattern, or converted to a Node.js request listener using
294
- * `toRequestListener()`.
295
- *
296
- * @param request - The incoming HTTP request
297
- * @param connection - Optional connection metadata
298
- * @returns A promise resolving to the HTTP response
299
- *
300
- * @example
301
- * ```typescript
302
- * // Use with Deno
303
- * Deno.serve(router.fetch)
304
- *
305
- * // Use with Bun
306
- * Bun.serve({ fetch: router.fetch })
307
- *
308
- * // Use with Node.js
309
- * import { toRequestListener } from '@atproto/lex-server/nodejs'
310
- * const listener = toRequestListener(router.fetch)
311
- * http.createServer(listener).listen(3000)
312
- * ```
313
- */
314
- fetch = async (request, connection) => {
315
- const { pathname } = new URL(request.url);
316
- const atprotoProxy = request.headers.get('atproto-proxy');
317
- if (!pathname.startsWith(XRPC_PATH_PREFIX)) {
318
- // Handle non XRPC paths
319
- const { fallback } = this.options;
320
- if (fallback)
321
- return fallback(request, connection);
322
- return new Response('Not Found', { status: 404 });
323
- }
324
- if (pathname === XRPC_HEALTH_CHECK_PATH) {
325
- if (request.method !== 'GET') {
326
- return invalidRequestResponse('Method not allowed', 405);
327
- }
328
- if (atprotoProxy != null) {
329
- return invalidRequestResponse('atproto-proxy header is not allowed on health check endpoint');
330
- }
331
- const { healthCheck } = this.options;
332
- const data = healthCheck ? await healthCheck(request) : { status: 'ok' };
333
- return Response.json(data);
334
- }
335
- const subPath = pathname.slice(XRPC_PATH_PREFIX.length);
336
- if (!(0, lex_schema_1.isNsidString)(subPath)) {
337
- return invalidRequestResponse('Invalid NSID in URL path');
338
- }
339
- const nsid = normalizeNsid(subPath);
340
- if (atprotoProxy == null) {
341
- const handler = this.handlers.get(nsid);
342
- if (handler)
343
- return handler(request, connection);
344
- }
345
- else {
346
- // Handle service proxying logic.
347
- const proxyInfo = parseAtprotoProxyHeader(atprotoProxy);
348
- if (!proxyInfo) {
349
- return invalidRequestResponse(`Invalid atproto-proxy header value: ${atprotoProxy}`);
350
- }
351
- // @TODO actually implement service proxying logic here. The reason it was
352
- // not done already is because we want to perform all the heavy lifting
353
- // here, while still allowing the possibility to override the endpoint
354
- // resolution, etc.
355
- // @NOTE see ./service-auth.ts for potential common code (did resolver, etc.)
356
- }
357
- return Response.json({
358
- error: 'MethodNotImplemented',
359
- message: `XRPC method "${nsid}" not implemented on this server`,
360
- }, { status: 501 });
361
- };
362
358
  }
363
- exports.LexRouter = LexRouter;
364
359
  async function getProcedureInput(request) {
365
360
  const encodingRaw = request.headers
366
361
  .get('content-type')
@@ -374,14 +369,14 @@ async function getProcedureInput(request) {
374
369
  ? 'application/octet-stream'
375
370
  : undefined);
376
371
  if (!this.input.matchesEncoding(encoding)) {
377
- throw new errors_js_1.LexServerError(400, {
372
+ throw new LexServerError(400, {
378
373
  error: 'InvalidRequest',
379
374
  message: `Invalid content-type: ${encoding}`,
380
375
  });
381
376
  }
382
377
  if (this.input.encoding === 'application/json') {
383
378
  // @TODO limit size?
384
- const data = (0, lex_json_1.lexParse)(await request.text());
379
+ const data = lexParse(await request.text());
385
380
  const body = this.input.schema ? this.input.schema.parse(data) : data;
386
381
  return { encoding, body };
387
382
  }
@@ -397,7 +392,7 @@ async function getQueryInput(request) {
397
392
  if (request.body ||
398
393
  request.headers.has('content-type') ||
399
394
  request.headers.has('content-length')) {
400
- throw new errors_js_1.LexServerError(400, {
395
+ throw new LexServerError(400, {
401
396
  error: 'InvalidRequest',
402
397
  message: 'GET requests must not have a body',
403
398
  });
@@ -415,17 +410,17 @@ function onMessage(_event) {
415
410
  this.close(1003, error);
416
411
  }
417
412
  // Pre-encoded frame header for error frames
418
- const ERROR_FRAME_HEADER = /*#__PURE__*/ (0, lex_cbor_1.encode)({ op: -1 });
413
+ const ERROR_FRAME_HEADER = /*#__PURE__*/ encode({ op: -1 });
419
414
  function encodeErrorFrame(errorData) {
420
- return (0, lex_data_1.ui8Concat)([ERROR_FRAME_HEADER, (0, lex_cbor_1.encode)(errorData)]);
415
+ return ui8Concat([ERROR_FRAME_HEADER, encode(errorData)]);
421
416
  }
422
417
  // Pre-encoded frame header for message frames with unknown type
423
- const UNKNOWN_MESSAGE_FRAME_HEADER = /*#__PURE__*/ (0, lex_cbor_1.encode)({ op: 1 });
418
+ const UNKNOWN_MESSAGE_FRAME_HEADER = /*#__PURE__*/ encode({ op: 1 });
424
419
  function encodeMessageFrame(method, value) {
425
- if ((0, lex_data_1.isPlainObject)(value) && typeof value.$type === 'string') {
420
+ if (isPlainObject(value) && typeof value.$type === 'string') {
426
421
  const { $type, ...rest } = value;
427
- return (0, lex_data_1.ui8Concat)([
428
- (0, lex_cbor_1.encode)({
422
+ return ui8Concat([
423
+ encode({
429
424
  op: 1,
430
425
  t:
431
426
  // If $type starts with `nsid#`, strip the NSID prefix
@@ -435,10 +430,10 @@ function encodeMessageFrame(method, value) {
435
430
  ? $type.slice(method.nsid.length)
436
431
  : $type,
437
432
  }),
438
- (0, lex_cbor_1.encode)(rest),
433
+ encode(rest),
439
434
  ]);
440
435
  }
441
- return (0, lex_data_1.ui8Concat)([UNKNOWN_MESSAGE_FRAME_HEADER, (0, lex_cbor_1.encode)(value)]);
436
+ return ui8Concat([UNKNOWN_MESSAGE_FRAME_HEADER, encode(value)]);
442
437
  }
443
438
  function isAbortReason(signal, error) {
444
439
  return (signal.aborted &&
@@ -464,7 +459,7 @@ function parseAtprotoProxyHeader(value) {
464
459
  if (value.includes(' ', fragmentIndex))
465
460
  return null;
466
461
  const did = value.slice(0, hashIndex);
467
- if (!(0, lex_schema_1.isDidString)(did))
462
+ if (!isDidString(did))
468
463
  return null;
469
464
  const serviceId = value.slice(fragmentIndex);
470
465
  return { did, serviceId };