@atproto/xrpc-server 0.10.21 → 0.11.0-next.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/auth.js +25 -65
  3. package/dist/auth.js.map +1 -1
  4. package/dist/errors.d.ts.map +1 -1
  5. package/dist/errors.js +59 -85
  6. package/dist/errors.js.map +1 -1
  7. package/dist/index.d.ts +8 -8
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +7 -28
  10. package/dist/index.js.map +1 -1
  11. package/dist/logger.js +4 -7
  12. package/dist/logger.js.map +1 -1
  13. package/dist/rate-limiter.d.ts +1 -1
  14. package/dist/rate-limiter.d.ts.map +1 -1
  15. package/dist/rate-limiter.js +27 -91
  16. package/dist/rate-limiter.js.map +1 -1
  17. package/dist/server.d.ts +4 -4
  18. package/dist/server.d.ts.map +1 -1
  19. package/dist/server.js +94 -178
  20. package/dist/server.js.map +1 -1
  21. package/dist/stream/frames.d.ts +1 -1
  22. package/dist/stream/frames.d.ts.map +1 -1
  23. package/dist/stream/frames.js +20 -50
  24. package/dist/stream/frames.js.map +1 -1
  25. package/dist/stream/index.d.ts +5 -5
  26. package/dist/stream/index.d.ts.map +1 -1
  27. package/dist/stream/index.js +5 -21
  28. package/dist/stream/index.js.map +1 -1
  29. package/dist/stream/logger.js +3 -6
  30. package/dist/stream/logger.js.map +1 -1
  31. package/dist/stream/server.d.ts +3 -2
  32. package/dist/stream/server.d.ts.map +1 -1
  33. package/dist/stream/server.js +12 -22
  34. package/dist/stream/server.js.map +1 -1
  35. package/dist/stream/stream.d.ts +2 -2
  36. package/dist/stream/stream.d.ts.map +1 -1
  37. package/dist/stream/stream.js +12 -18
  38. package/dist/stream/stream.js.map +1 -1
  39. package/dist/stream/subscription.d.ts +1 -1
  40. package/dist/stream/subscription.d.ts.map +1 -1
  41. package/dist/stream/subscription.js +9 -18
  42. package/dist/stream/subscription.js.map +1 -1
  43. package/dist/stream/types.js +12 -15
  44. package/dist/stream/types.js.map +1 -1
  45. package/dist/types.d.ts +2 -2
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/types.js +22 -29
  48. package/dist/types.js.map +1 -1
  49. package/dist/util.d.ts +2 -2
  50. package/dist/util.d.ts.map +1 -1
  51. package/dist/util.js +75 -116
  52. package/dist/util.js.map +1 -1
  53. package/{jest.config.js → jest.config.cjs} +8 -2
  54. package/package.json +28 -22
  55. package/src/auth.ts +1 -1
  56. package/src/errors.ts +4 -1
  57. package/src/index.ts +8 -8
  58. package/src/rate-limiter.ts +2 -2
  59. package/src/server.ts +11 -6
  60. package/src/stream/frames.ts +2 -2
  61. package/src/stream/index.ts +5 -5
  62. package/src/stream/server.ts +4 -3
  63. package/src/stream/stream.ts +1 -1
  64. package/src/stream/subscription.ts +2 -2
  65. package/src/types.ts +2 -2
  66. package/src/util.ts +6 -3
  67. package/tests/_util.ts +1 -1
  68. package/tests/auth.test.ts +6 -3
  69. package/tests/bodies.test.ts +4 -3
  70. package/tests/errors.test.ts +2 -2
  71. package/tests/frames.test.ts +1 -1
  72. package/tests/ipld.test.ts +2 -2
  73. package/tests/parameters.test.ts +2 -2
  74. package/tests/parsing.test.ts +1 -1
  75. package/tests/procedures.test.ts +2 -2
  76. package/tests/queries.test.ts +2 -2
  77. package/tests/rate-limiter.test.ts +3 -3
  78. package/tests/responses.test.ts +2 -2
  79. package/tests/stream.test.ts +1 -1
  80. package/tests/subscriptions.test.ts +11 -5
  81. package/tsconfig.build.json +1 -1
  82. package/tsconfig.build.tsbuildinfo +1 -1
  83. package/tsconfig.tests.json +1 -1
package/dist/server.js CHANGED
@@ -1,150 +1,67 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.Server = void 0;
40
- exports.createServer = createServer;
41
- const node_assert_1 = __importDefault(require("node:assert"));
42
- const node_stream_1 = require("node:stream");
43
- const promises_1 = require("node:stream/promises");
44
- const express_1 = __importStar(require("express"));
45
- const lex_schema_1 = require("@atproto/lex-schema");
46
- const lexicon_1 = require("@atproto/lexicon");
47
- const errors_1 = require("./errors");
48
- const logger_1 = __importStar(require("./logger"));
49
- const rate_limiter_1 = require("./rate-limiter");
50
- const stream_1 = require("./stream");
51
- const types_1 = require("./types");
52
- const util_1 = require("./util");
53
- function createServer(lexicons, options) {
1
+ import assert from 'node:assert';
2
+ import { Readable } from 'node:stream';
3
+ import { pipeline } from 'node:stream/promises';
4
+ import express, { Router, } from 'express';
5
+ import { l } from '@atproto/lex-schema';
6
+ import { Lexicons, lexToJson, } from '@atproto/lexicon';
7
+ import { InternalServerError, InvalidRequestError, MethodNotImplementedError, XRPCError, excludeErrorResult, } from './errors.js';
8
+ import log, { LOGGER_NAME } from './logger.js';
9
+ import { RouteRateLimiter, WrappedRateLimiter, } from './rate-limiter.js';
10
+ import { ErrorFrame, Frame, MessageFrame, XrpcStreamServer, } from './stream/index.js';
11
+ import { isHandlerPipeThroughBuffer, isHandlerPipeThroughStream, isHandlerSuccess, isSharedRateLimitOpts, } from './types.js';
12
+ import { asArray, createLexiconInputVerifier, createLexiconOutputVerifier, createLexiconParamsVerifier, createSchemaInputVerifier, createSchemaOutputVerifier, createSchemaParamsVerifier, extractUrlNsid, setHeaders, } from './util.js';
13
+ export function createServer(lexicons, options) {
54
14
  return new Server(lexicons, options);
55
15
  }
56
- class Server {
16
+ export class Server {
57
17
  constructor(lexicons, opts = {}) {
58
- Object.defineProperty(this, "router", {
59
- enumerable: true,
60
- configurable: true,
61
- writable: true,
62
- value: (0, express_1.default)()
63
- });
64
- Object.defineProperty(this, "routes", {
65
- enumerable: true,
66
- configurable: true,
67
- writable: true,
68
- value: (0, express_1.Router)()
69
- });
70
- Object.defineProperty(this, "subscriptions", {
71
- enumerable: true,
72
- configurable: true,
73
- writable: true,
74
- value: new Map()
75
- });
76
- Object.defineProperty(this, "lex", {
77
- enumerable: true,
78
- configurable: true,
79
- writable: true,
80
- value: new lexicon_1.Lexicons()
81
- });
82
- Object.defineProperty(this, "options", {
83
- enumerable: true,
84
- configurable: true,
85
- writable: true,
86
- value: void 0
87
- });
88
- Object.defineProperty(this, "globalRateLimiter", {
89
- enumerable: true,
90
- configurable: true,
91
- writable: true,
92
- value: void 0
93
- });
94
- Object.defineProperty(this, "sharedRateLimiters", {
95
- enumerable: true,
96
- configurable: true,
97
- writable: true,
98
- value: void 0
99
- });
100
- Object.defineProperty(this, "catchall", {
101
- enumerable: true,
102
- configurable: true,
103
- writable: true,
104
- value: async (req, res, next) => {
105
- // catchall handler only applies to XRPC routes
106
- if (!req.url.startsWith('/xrpc/'))
107
- return next();
108
- // Validate the NSID
109
- const nsid = (0, util_1.extractUrlNsid)(req.url);
110
- if (!nsid) {
111
- return next(new errors_1.InvalidRequestError('invalid xrpc path'));
112
- }
113
- if (this.globalRateLimiter) {
114
- try {
115
- await this.globalRateLimiter.handle({
116
- req,
117
- res,
118
- auth: undefined,
119
- params: {},
120
- input: undefined,
121
- async resetRouteRateLimits() { },
122
- });
123
- }
124
- catch (err) {
125
- return next(err);
126
- }
127
- }
128
- // Ensure that known XRPC methods are only called with the correct HTTP
129
- // method.
130
- const def = this.lex.getDef(nsid);
131
- if (def) {
132
- const expectedMethod = def.type === 'procedure' ? 'POST' : def.type === 'query' ? 'GET' : null;
133
- if (expectedMethod != null && expectedMethod !== req.method) {
134
- return next(new errors_1.InvalidRequestError(`Incorrect HTTP method (${req.method}) expected ${expectedMethod}`));
135
- }
136
- }
137
- if (this.options.catchall) {
138
- this.options.catchall.call(null, req, res, next);
18
+ this.router = express();
19
+ this.routes = Router();
20
+ this.subscriptions = new Map();
21
+ this.lex = new Lexicons();
22
+ this.catchall = async (req, res, next) => {
23
+ // catchall handler only applies to XRPC routes
24
+ if (!req.url.startsWith('/xrpc/'))
25
+ return next();
26
+ // Validate the NSID
27
+ const nsid = extractUrlNsid(req.url);
28
+ if (!nsid) {
29
+ return next(new InvalidRequestError('invalid xrpc path'));
30
+ }
31
+ if (this.globalRateLimiter) {
32
+ try {
33
+ await this.globalRateLimiter.handle({
34
+ req,
35
+ res,
36
+ auth: undefined,
37
+ params: {},
38
+ input: undefined,
39
+ async resetRouteRateLimits() { },
40
+ });
139
41
  }
140
- else if (!def) {
141
- next(new errors_1.MethodNotImplementedError());
42
+ catch (err) {
43
+ return next(err);
142
44
  }
143
- else {
144
- next();
45
+ }
46
+ // Ensure that known XRPC methods are only called with the correct HTTP
47
+ // method.
48
+ const def = this.lex.getDef(nsid);
49
+ if (def) {
50
+ const expectedMethod = def.type === 'procedure' ? 'POST' : def.type === 'query' ? 'GET' : null;
51
+ if (expectedMethod != null && expectedMethod !== req.method) {
52
+ return next(new InvalidRequestError(`Incorrect HTTP method (${req.method}) expected ${expectedMethod}`));
145
53
  }
146
54
  }
147
- });
55
+ if (this.options.catchall) {
56
+ this.options.catchall.call(null, req, res, next);
57
+ }
58
+ else if (!def) {
59
+ next(new MethodNotImplementedError());
60
+ }
61
+ else {
62
+ next();
63
+ }
64
+ };
148
65
  if (lexicons) {
149
66
  this.addLexicons(lexicons);
150
67
  }
@@ -158,7 +75,7 @@ class Server {
158
75
  if (opts.rateLimits) {
159
76
  const { global, shared, creator, bypass } = opts.rateLimits;
160
77
  if (global) {
161
- this.globalRateLimiter = rate_limiter_1.RouteRateLimiter.from(global.map((options) => creator(buildRateLimiterOptions(options))), { bypass });
78
+ this.globalRateLimiter = RouteRateLimiter.from(global.map((options) => creator(buildRateLimiterOptions(options))), { bypass });
162
79
  }
163
80
  if (shared) {
164
81
  this.sharedRateLimiters = new Map(shared.map((options) => [
@@ -172,7 +89,7 @@ class Server {
172
89
  return this.router.listen(port, callback);
173
90
  }
174
91
  add(ns, configOfHandler) {
175
- const schema = lex_schema_1.l.getMain(ns);
92
+ const schema = l.getMain(ns);
176
93
  const config = typeof configOfHandler === 'function'
177
94
  ? { handler: configOfHandler }
178
95
  : configOfHandler;
@@ -204,7 +121,7 @@ class Server {
204
121
  messageSchema
205
122
  ? async function* (ctx) {
206
123
  for await (const item of handler(ctx)) {
207
- if (item instanceof stream_1.Frame) {
124
+ if (item instanceof Frame) {
208
125
  messageSchema.validate(item.body);
209
126
  yield item;
210
127
  }
@@ -298,31 +215,31 @@ class Server {
298
215
  res.status(200);
299
216
  res.end();
300
217
  }
301
- else if ((0, types_1.isHandlerPipeThroughStream)(output)) {
302
- (0, util_1.setHeaders)(res, output.headers);
218
+ else if (isHandlerPipeThroughStream(output)) {
219
+ setHeaders(res, output.headers);
303
220
  res.status(200);
304
221
  res.header('Content-Type', output.encoding);
305
- await (0, promises_1.pipeline)(output.stream, res);
222
+ await pipeline(output.stream, res);
306
223
  }
307
- else if ((0, types_1.isHandlerPipeThroughBuffer)(output)) {
308
- (0, util_1.setHeaders)(res, output.headers);
224
+ else if (isHandlerPipeThroughBuffer(output)) {
225
+ setHeaders(res, output.headers);
309
226
  res.status(200);
310
227
  res.header('Content-Type', output.encoding);
311
228
  res.end(output.buffer);
312
229
  }
313
- else if ((0, types_1.isHandlerSuccess)(output)) {
230
+ else if (isHandlerSuccess(output)) {
314
231
  validateResOutput?.(output);
315
232
  res.status(200);
316
- (0, util_1.setHeaders)(res, output.headers);
233
+ setHeaders(res, output.headers);
317
234
  const encoding = output.encoding === 'json' ? 'application/json' : output.encoding;
318
235
  res.header('Content-Type', encoding);
319
- if (output.body instanceof node_stream_1.Readable) {
236
+ if (output.body instanceof Readable) {
320
237
  // The "Readable" check comes first to avoid calling "lexToJson" on
321
238
  // a stream, which would be a bug.
322
- await (0, promises_1.pipeline)(output.body, res);
239
+ await pipeline(output.body, res);
323
240
  }
324
241
  else if (encoding === 'application/json') {
325
- const json = (0, lexicon_1.lexToJson)(output.body);
242
+ const json = lexToJson(output.body);
326
243
  res.json(json);
327
244
  }
328
245
  else {
@@ -334,7 +251,7 @@ class Server {
334
251
  }
335
252
  }
336
253
  else {
337
- next(errors_1.XRPCError.fromError(output));
254
+ next(XRPCError.fromError(output));
338
255
  }
339
256
  }
340
257
  catch (err) {
@@ -342,7 +259,7 @@ class Server {
342
259
  // if the value passed to next is false-y (e.g. null, undefined, 0).
343
260
  // Hence we replace it with an InternalServerError.
344
261
  if (!err) {
345
- next(new errors_1.InternalServerError());
262
+ next(new InternalServerError());
346
263
  }
347
264
  else {
348
265
  next(err);
@@ -357,7 +274,7 @@ class Server {
357
274
  cfg.handler);
358
275
  }
359
276
  addSubscriptionInternal(nsid, paramsVerifier, authVerifier, handler) {
360
- this.subscriptions.set(nsid, new stream_1.XrpcStreamServer({
277
+ this.subscriptions.set(nsid, new XrpcStreamServer({
361
278
  noServer: true,
362
279
  handler: async function* (req, signal) {
363
280
  try {
@@ -369,13 +286,13 @@ class Server {
369
286
  : undefined;
370
287
  // stream
371
288
  for await (const item of handler({ req, params, auth, signal })) {
372
- yield item instanceof stream_1.Frame
289
+ yield item instanceof Frame
373
290
  ? item
374
- : stream_1.MessageFrame.fromLexValue(item, nsid);
291
+ : MessageFrame.fromLexValue(item, nsid);
375
292
  }
376
293
  }
377
294
  catch (err) {
378
- yield stream_1.ErrorFrame.fromError(err);
295
+ yield ErrorFrame.fromError(err);
379
296
  }
380
297
  },
381
298
  }));
@@ -386,14 +303,14 @@ class Server {
386
303
  return null;
387
304
  return async (ctx) => {
388
305
  const result = await auth(ctx);
389
- return (0, errors_1.excludeErrorResult)(result);
306
+ return excludeErrorResult(result);
390
307
  };
391
308
  }
392
309
  createLexiconParamsVerifier(nsid, def) {
393
- return (0, util_1.createLexiconParamsVerifier)(nsid, def, this.lex);
310
+ return createLexiconParamsVerifier(nsid, def, this.lex);
394
311
  }
395
312
  createLexiconInputVerifier(nsid, def, opts) {
396
- return (0, util_1.createLexiconInputVerifier)(nsid, def, {
313
+ return createLexiconInputVerifier(nsid, def, {
397
314
  blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,
398
315
  jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,
399
316
  textLimit: opts?.textLimit ?? this.options.payload?.textLimit,
@@ -403,13 +320,13 @@ class Server {
403
320
  if (this.options.validateResponse === false) {
404
321
  return null;
405
322
  }
406
- return (0, util_1.createLexiconOutputVerifier)(nsid, def, this.lex);
323
+ return createLexiconOutputVerifier(nsid, def, this.lex);
407
324
  }
408
325
  createSchemaParamsVerifier(ns, opts) {
409
- return (0, util_1.createSchemaParamsVerifier)(ns, opts);
326
+ return createSchemaParamsVerifier(ns, opts);
410
327
  }
411
328
  createSchemaInputVerifier(ns, opts) {
412
- return (0, util_1.createSchemaInputVerifier)(ns, {
329
+ return createSchemaInputVerifier(ns, {
413
330
  blobLimit: opts?.blobLimit ?? this.options.payload?.blobLimit,
414
331
  jsonLimit: opts?.jsonLimit ?? this.options.payload?.jsonLimit,
415
332
  textLimit: opts?.textLimit ?? this.options.payload?.textLimit,
@@ -419,7 +336,7 @@ class Server {
419
336
  if (this.options.validateResponse === false) {
420
337
  return null;
421
338
  }
422
- return (0, util_1.createSchemaOutputVerifier)(ns);
339
+ return createSchemaOutputVerifier(ns);
423
340
  }
424
341
  enableStreamingOnListen(app) {
425
342
  const _listen = app.listen;
@@ -427,7 +344,7 @@ class Server {
427
344
  // @ts-ignore the args spread
428
345
  const httpServer = _listen.call(app, ...args);
429
346
  httpServer.on('upgrade', (req, socket, head) => {
430
- const nsid = req.url ? (0, util_1.extractUrlNsid)(req.url) : undefined;
347
+ const nsid = req.url ? extractUrlNsid(req.url) : undefined;
431
348
  const sub = nsid ? this.subscriptions.get(nsid) : undefined;
432
349
  if (!sub)
433
350
  return socket.destroy();
@@ -451,13 +368,13 @@ class Server {
451
368
  if (!rateLimits)
452
369
  return globalRateLimiter;
453
370
  const { creator, bypass } = rateLimits;
454
- const rateLimiters = (0, util_1.asArray)(config.rateLimit).map((options, i) => {
455
- if ((0, types_1.isSharedRateLimitOpts)(options)) {
371
+ const rateLimiters = asArray(config.rateLimit).map((options, i) => {
372
+ if (isSharedRateLimitOpts(options)) {
456
373
  const rateLimiter = this.sharedRateLimiters?.get(options.name);
457
374
  // The route config references a shared rate limiter that does not
458
375
  // exist. This is a configuration error.
459
- (0, node_assert_1.default)(rateLimiter, `Shared rate limiter "${options.name}" not defined`);
460
- return rate_limiter_1.WrappedRateLimiter.from(rateLimiter, options);
376
+ assert(rateLimiter, `Shared rate limiter "${options.name}" not defined`);
377
+ return WrappedRateLimiter.from(rateLimiter, options);
461
378
  }
462
379
  else {
463
380
  return creator({
@@ -475,18 +392,17 @@ class Server {
475
392
  // the route specific rate limiters.
476
393
  if (globalRateLimiter)
477
394
  rateLimiters.push(globalRateLimiter);
478
- return rate_limiter_1.RouteRateLimiter.from(rateLimiters, { bypass });
395
+ return RouteRateLimiter.from(rateLimiters, { bypass });
479
396
  }
480
397
  }
481
- exports.Server = Server;
482
- function createErrorMiddleware({ errorParser = (err) => errors_1.XRPCError.fromError(err), }) {
398
+ function createErrorMiddleware({ errorParser = (err) => XRPCError.fromError(err), }) {
483
399
  return (err, req, res, next) => {
484
- const nsid = (0, util_1.extractUrlNsid)(req.originalUrl);
400
+ const nsid = extractUrlNsid(req.originalUrl);
485
401
  const xrpcError = errorParser(err);
486
402
  // Use the request's logger (if available) to benefit from request context
487
403
  // (id, timing) and logging configuration (serialization, etc.).
488
- const logger = isPinoHttpRequest(req) ? req.log : logger_1.default;
489
- const isInternalError = xrpcError instanceof errors_1.InternalServerError;
404
+ const logger = isPinoHttpRequest(req) ? req.log : log;
405
+ const isInternalError = xrpcError instanceof InternalServerError;
490
406
  const msgPrefix = isInternalError ? 'unhandled exception' : 'error';
491
407
  const msgSuffix = nsid ? `xrpc method ${nsid}` : `${req.method} ${req.url}`;
492
408
  const msg = `${msgPrefix} in ${msgSuffix}`;
@@ -503,7 +419,7 @@ function createErrorMiddleware({ errorParser = (err) => errors_1.XRPCError.fromE
503
419
  payload: xrpcError.payload,
504
420
  // Ensure that the logged item's name is set to LOGGER_NAME, instead of
505
421
  // the name of the pino-http logger, to ensure consistency across logs.
506
- name: logger_1.LOGGER_NAME,
422
+ name: LOGGER_NAME,
507
423
  }, msg);
508
424
  if (res.headersSent) {
509
425
  return next(err);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFA,oCAEC;AAxFD,8DAAgC;AAEhC,6CAAsC;AACtC,mDAA+C;AAC/C,mDAMgB;AAEhB,oDAAuC;AACvC,8CAOyB;AACzB,qCAMiB;AACjB,mDAA2C;AAC3C,iDAOuB;AACvB,qCAA4E;AAC5E,mCA+BgB;AAChB,iCAce;AAEf,SAAgB,YAAY,CAAC,QAAuB,EAAE,OAAiB;IACrE,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED,MAAa,MAAM;IASjB,YAAY,QAAuB,EAAE,OAAgB,EAAE;QARvD;;;;mBAAkB,IAAA,iBAAO,GAAE;WAAA;QAC3B;;;;mBAAiB,IAAA,gBAAM,GAAE;WAAA;QACzB;;;;mBAAgB,IAAI,GAAG,EAA4B;WAAA;QACnD;;;;mBAAM,IAAI,kBAAQ,EAAE;WAAA;QACpB;;;;;WAAgB;QAChB;;;;;WAAoD;QACpD;;;;;WAA8D;QAwP9D;;;;mBAA4B,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;gBACnD,+CAA+C;gBAC/C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,OAAO,IAAI,EAAE,CAAA;gBAEhD,oBAAoB;gBACpB,MAAM,IAAI,GAAG,IAAA,qBAAc,EAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACpC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO,IAAI,CAAC,IAAI,4BAAmB,CAAC,mBAAmB,CAAC,CAAC,CAAA;gBAC3D,CAAC;gBAED,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC3B,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;4BAClC,GAAG;4BACH,GAAG;4BACH,IAAI,EAAE,SAAS;4BACf,MAAM,EAAE,EAAE;4BACV,KAAK,EAAE,SAAS;4BAChB,KAAK,CAAC,oBAAoB,KAAI,CAAC;yBAChC,CAAC,CAAA;oBACJ,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;oBAClB,CAAC;gBACH,CAAC;gBAED,uEAAuE;gBACvE,UAAU;gBACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACjC,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,cAAc,GAClB,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;oBACzE,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;wBAC5D,OAAO,IAAI,CACT,IAAI,4BAAmB,CACrB,0BAA0B,GAAG,CAAC,MAAM,cAAc,cAAc,EAAE,CACnE,CACF,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;gBAClD,CAAC;qBAAM,IAAI,CAAC,GAAG,EAAE,CAAC;oBAChB,IAAI,CAAC,IAAI,kCAAyB,EAAE,CAAC,CAAA;gBACvC,CAAC;qBAAM,CAAC;oBACN,IAAI,EAAE,CAAA;gBACR,CAAC;YACH,CAAC;WAAA;QApSC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;QAC5B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC9B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAgB,EAAE,EAAE;YAC7C,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAEnB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAA;YAE3D,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,iBAAiB,GAAG,+BAAgB,CAAC,IAAI,CAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,EAClE,EAAE,MAAM,EAAE,CACX,CAAA;YACH,CAAC;YAED,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,kBAAkB,GAAG,IAAI,GAAG,CAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;oBACtB,OAAO,CAAC,IAAI;oBACZ,OAAO,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;iBAC1C,CAAC,CACH,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,QAAqB;QACxC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAC3C,CAAC;IAuBD,GAAG,CACD,EAAa,EACb,eAIW;QAEX,MAAM,MAAM,GAAG,cAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC5B,MAAM,MAAM,GACV,OAAO,eAAe,KAAK,UAAU;YACnC,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE;YAC9B,CAAC,CAAC,eAAe,CAAA;QACrB,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,kBAAkB,CAC5B,MAAM,EACN,MAAyC,CAC1C,CAAA;YACH,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,cAAc,CACxB,MAAM,EACN,MAAqC,CACtC,CAAA;YACH,KAAK,cAAc;gBACjB,OAAO,IAAI,CAAC,qBAAqB,CAC/B,MAAM,EACN,MAAkD,CACnD,CAAA;YACH;gBACE,MAAM,IAAI,SAAS;gBACjB,uCAAuC;gBACvC,sBAAsB,MAAM,CAAC,IAAI,YAAY,MAAM,CAAC,IAAI,EAAE,CAC3D,CAAA;QACL,CAAC;IACH,CAAC;IAES,kBAAkB,CAC1B,MAAS,EACT,MAA6B;QAE7B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,SAAS,MAAM,CAAC,IAAI,EAAE,EACtB,IAAI,CAAC,qBAAqB,CAMxB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EACpD,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EACnD,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAChD,MAAM,CAAC,OAAO,EACd,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CACxC,CACF,CAAA;IACH,CAAC;IAES,cAAc,CACtB,MAAS,EACT,MAA6B;QAE7B,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,SAAS,MAAM,CAAC,IAAI,EAAE,EACtB,IAAI,CAAC,qBAAqB,CAMxB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAC/B,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EACpD,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EACnD,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAChD,MAAM,CAAC,OAAO,EACd,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CACxC,CACF,CAAA;IACH,CAAC;IAES,qBAAqB,CAG7B,MAAS,EAAE,MAAmC;QAC9C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAA;QAC1B,MAAM,aAAa,GACjB,IAAI,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAA;QAEtE,OAAO,IAAI,CAAC,uBAAuB,CACjC,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,EACvC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC/B,qEAAqE;QACrE,eAAe;QACf,aAAa;YACX,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,GAAG;gBAClB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtC,IAAI,IAAI,YAAY,cAAK,EAAE,CAAC;wBAC1B,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;wBACjC,MAAM,IAAI,CAAA;oBACZ,CAAC;yBAAM,CAAC;wBACN,MAAM,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;YACH,CAAC,CAAC,OAAO,CACZ,CAAA;IACH,CAAC;IAED,MAAM,CACJ,IAAY,EACZ,UAAoC;QAEpC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAClC,CAAC;IAED,SAAS,CACP,IAAY,EACZ,UAAoC;QAEpC,MAAM,MAAM,GACV,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QACzE,IAAI,MAAM,CAAC,IAAI,IAAI,kBAAkB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAA;QACH,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,GAAG,EAAE,IAAI,KAAK,OAAO,IAAI,GAAG,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YACvD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,gCAAgC,CAAC,CAAA;QACtE,CAAC;IACH,CAAC;IAED,YAAY,CACV,IAAY,EACZ,UAA4C;QAE5C,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACxC,CAAC;IAED,eAAe,CACb,IAAY,EACZ,UAA4C;QAE5C,MAAM,MAAM,GACV,OAAO,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,GAAG,EAAE,IAAI,KAAK,cAAc,EAAE,CAAC;YACjC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,UAAU;IACV,IAAI;IAEJ,UAAU,CAAC,GAAe;QACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC;IAED,WAAW,CAAC,IAAkB;QAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,OAAO;IACP,IAAI;IAEM,KAAK,CAAC,QAAQ,CACtB,IAAY,EACZ,GAAoC,EACpC,MAAuB;QAEvB,MAAM,IAAI,GAAG,SAAS,IAAI,EAAE,CAAA;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QAErD,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAmDD,aAAa,CAMX,IAAY,EACZ,GAAoC,EACpC,GAA6B;QAE7B,OAAO,IAAI,CAAC,qBAAqB,CAC/B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAC5B,IAAI,CAAC,2BAA2B,CAAI,IAAI,EAAE,GAAG,CAAC,EAC9C,IAAI,CAAC,0BAA0B,CAAI,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EACvD,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,EACtC,GAAG,CAAC,OAAO,EACX,IAAI,CAAC,2BAA2B,CAAI,IAAI,EAAE,GAAG,CAAC,CAC/C,CAAA;IACH,CAAC;IAES,qBAAqB,CAM7B,YAAkE,EAClE,cAAyC,EACzC,aAAuC,EACvC,YAAmE,EACnE,OAAkC,EAClC,iBAAmD;QAEnD,OAAO,KAAK,WAAW,GAAG,EAAE,GAAG,EAAE,IAAI;YACnC,IAAI,CAAC;gBACH,0BAA0B;gBAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;gBAElC,uBAAuB;gBACvB,MAAM,IAAI,GAAM,YAAY;oBAC1B,CAAC,CAAC,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;oBAC1C,CAAC,CAAE,SAAe,CAAA;gBAEpB,yBAAyB;gBACzB,MAAM,KAAK,GAAM,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;gBAE9C,MAAM,GAAG,GAA4B;oBACnC,MAAM;oBACN,KAAK;oBACL,IAAI;oBACJ,GAAG;oBACH,GAAG;oBACH,oBAAoB,EAAE,KAAK,IAAI,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC;iBAC3D,CAAA;gBAED,qBAAqB;gBACrB,IAAI,YAAY;oBAAE,MAAM,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAEhD,kBAAkB;gBAClB,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAM,CAAA;gBAExC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,iBAAiB,EAAE,CAAC,MAAM,CAAC,CAAA;oBAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACf,GAAG,CAAC,GAAG,EAAE,CAAA;gBACX,CAAC;qBAAM,IAAI,IAAA,kCAA0B,EAAC,MAAM,CAAC,EAAE,CAAC;oBAC9C,IAAA,iBAAU,EAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;oBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACf,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;oBAC3C,MAAM,IAAA,mBAAQ,EAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;gBACpC,CAAC;qBAAM,IAAI,IAAA,kCAA0B,EAAC,MAAM,CAAC,EAAE,CAAC;oBAC9C,IAAA,iBAAU,EAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;oBAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACf,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;oBAC3C,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBACxB,CAAC;qBAAM,IAAI,IAAA,wBAAgB,EAAC,MAAM,CAAC,EAAE,CAAC;oBACpC,iBAAiB,EAAE,CAAC,MAAM,CAAC,CAAA;oBAE3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACf,IAAA,iBAAU,EAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;oBAE/B,MAAM,QAAQ,GACZ,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;oBAEnE,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;oBAEpC,IAAI,MAAM,CAAC,IAAI,YAAY,sBAAQ,EAAE,CAAC;wBACpC,mEAAmE;wBACnE,kCAAkC;wBAClC,MAAM,IAAA,mBAAQ,EAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;oBAClC,CAAC;yBAAM,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;wBAC3C,MAAM,IAAI,GAAG,IAAA,mBAAS,EAAC,MAAM,CAAC,IAAI,CAAC,CAAA;wBACnC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBAChB,CAAC;yBAAM,CAAC;wBACN,GAAG,CAAC,IAAI,CACN,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;4BAC1B,CAAC,CAAC,MAAM,CAAC,IAAI;4BACb,CAAC,CAAC,MAAM,CAAC,IAAI,YAAY,UAAU;gCACjC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gCAC1B,CAAC,CAAC,MAAM,CAAC,IAAI,CAClB,CAAA;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,kBAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;gBACnC,CAAC;YACH,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,2EAA2E;gBAC3E,oEAAoE;gBACpE,mDAAmD;gBACnD,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,IAAI,CAAC,IAAI,4BAAmB,EAAE,CAAC,CAAA;gBACjC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,GAAG,CAAC,CAAA;gBACX,CAAC;YACH,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAES,KAAK,CAAC,eAAe,CAC7B,IAAY,EACZ,GAAwB,EACxB,GAA4B;QAE5B,IAAI,CAAC,uBAAuB,CAC1B,IAAI,EACJ,IAAI,CAAC,2BAA2B,CAAC,IAAI,EAAE,GAAG,CAAC,EAC3C,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC;QAC5B,uEAAuE;QACvE,6DAA6D;QAC7D,GAAG,CAAC,OAAO,CACZ,CAAA;IACH,CAAC;IAES,uBAAuB,CAC/B,IAAY,EACZ,cAAyC,EACzC,YAAkE,EAClE,OAA6D;QAE7D,IAAI,CAAC,aAAa,CAAC,GAAG,CACpB,IAAI,EACJ,IAAI,yBAAgB,CAAC;YACnB,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,KAAK,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM;gBACnC,IAAI,CAAC;oBACH,mBAAmB;oBACnB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;oBAElC,uBAAuB;oBACvB,MAAM,IAAI,GAAG,YAAY;wBACvB,CAAC,CAAC,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;wBACrC,CAAC,CAAE,SAAe,CAAA;oBAEpB,SAAS;oBACT,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;wBAChE,MAAM,IAAI,YAAY,cAAK;4BACzB,CAAC,CAAC,IAAI;4BACN,CAAC,CAAC,qBAAY,CAAC,YAAY,CAAC,IAAgB,EAAE,IAAI,CAAC,CAAA;oBACvD,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,mBAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;gBACjC,CAAC;YACH,CAAC;SACF,CAAC,CACH,CAAA;IACH,CAAC;IAEO,kBAAkB,CAA0B,GAEnD;QACC,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAA;QACpB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QAEtB,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAA;YAC9B,OAAO,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAA;QACnC,CAAC,CAAA;IACH,CAAC;IAEO,2BAA2B,CACjC,IAAY,EACZ,GAA0D;QAE1D,OAAO,IAAA,kCAA2B,EAAI,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5D,CAAC;IAEO,0BAA0B,CAChC,IAAY,EACZ,GAAoC,EACpC,IAAmB;QAEnB,OAAO,IAAA,iCAA0B,EAC/B,IAAI,EACJ,GAAG,EACH;YACE,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;YAC7D,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;YAC7D,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;SAC9D,EACD,IAAI,CAAC,GAAG,CACT,CAAA;IACH,CAAC;IAEO,2BAA2B,CACjC,IAAY,EACZ,GAAoC;QAEpC,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,IAAA,kCAA2B,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IACzD,CAAC;IAEO,0BAA0B,CAGhC,EAAa,EACb,IAAmB;QAEnB,OAAO,IAAA,iCAA0B,EAAI,EAAE,EAAE,IAAI,CAAC,CAAA;IAChD,CAAC;IAEO,yBAAyB,CAC/B,EAAa,EACb,IAAmB;QAEnB,OAAO,IAAA,gCAAyB,EAAI,EAAE,EAAE;YACtC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;YAC7D,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;YAC7D,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS;SAC9D,CAAC,CAAA;IACJ,CAAC;IAEO,0BAA0B,CAChC,EAAa;QAEb,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,IAAA,iCAA0B,EAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;IAEO,uBAAuB,CAAC,GAAgB;QAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAA;QAC1B,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE;YACvB,6BAA6B;YAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;YAC7C,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;gBAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAA,qBAAc,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC3D,IAAI,CAAC,GAAG;oBAAE,OAAO,MAAM,CAAC,OAAO,EAAE,CAAA;gBACjC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAC9C,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,CACpC,CAAA;YACH,CAAC,CAAC,CAAA;YACF,OAAO,UAAU,CAAA;QACnB,CAAC,CAAA;IACH,CAAC;IAEO,sBAAsB,CAM5B,IAAY,EACZ,MAAgC;QAEhC,yEAAyE;QACzE,wEAAwE;QACxE,uEAAuE;QACvE,mCAAmC;QAEnC,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAElB,CAAA;QAEb,2EAA2E;QAC3E,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,iBAAiB,CAAA;QAE/C,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAEnC,uEAAuE;QACvE,4DAA4D;QAC5D,IAAI,CAAC,UAAU;YAAE,OAAO,iBAAiB,CAAA;QAEzC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAEtC,MAAM,YAAY,GAAG,IAAA,cAAO,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;YAChE,IAAI,IAAA,6BAAqB,EAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAE9D,kEAAkE;gBAClE,wCAAwC;gBACxC,IAAA,qBAAM,EAAC,WAAW,EAAE,wBAAwB,OAAO,CAAC,IAAI,eAAe,CAAC,CAAA;gBAExE,OAAO,iCAAkB,CAAC,IAAI,CAAM,WAAW,EAAE,OAAO,CAAC,CAAA;YAC3D,CAAC;iBAAM,CAAC;gBACN,OAAO,OAAO,CAAC;oBACb,GAAG,OAAO;oBACV,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;oBACtC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,aAAa;oBAC/C,SAAS,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE;iBAC1B,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,wEAAwE;QACxE,IAAI,CAAC,YAAY,CAAC,MAAM;YAAE,OAAO,iBAAiB,CAAA;QAElD,wEAAwE;QACxE,oCAAoC;QACpC,IAAI,iBAAiB;YAAE,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAE3D,OAAO,+BAAgB,CAAC,IAAI,CAAM,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IAC7D,CAAC;CACF;AA5mBD,wBA4mBC;AAED,SAAS,qBAAqB,CAAC,EAC7B,WAAW,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAS,CAAC,SAAS,CAAC,GAAG,CAAC,GACvC;IACR,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,IAAA,qBAAc,EAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAC5C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QAElC,0EAA0E;QAC1E,gEAAgE;QAChE,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAG,CAAA;QAErD,MAAM,eAAe,GAAG,SAAS,YAAY,4BAAmB,CAAA;QAEhE,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAA;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAA;QAC3E,MAAM,GAAG,GAAG,GAAG,SAAS,OAAO,SAAS,EAAE,CAAA;QAE1C,MAAM,CAAC,KAAK,CACV;YACE,iEAAiE;YACjE,mCAAmC;YACnC,GAAG,EACD,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;gBACvD,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,qBAAqB,CAAC,GAAG,CAAC;YAEhC,wDAAwD;YACxD,IAAI;YACJ,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,MAAM,EAAE,SAAS,CAAC,UAAU;YAC5B,OAAO,EAAE,SAAS,CAAC,OAAO;YAE1B,uEAAuE;YACvE,uEAAuE;YACvE,IAAI,EAAE,oBAAW;SAClB,EACD,GAAG,CACJ,CAAA;QAED,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;QAClB,CAAC;QAED,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IACjE,CAAC,CAAA;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAoB;IAG7C,OAAO,OAAQ,GAAqB,CAAC,GAAG,EAAE,KAAK,KAAK,UAAU,CAAA;AAChE,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,gEAAgE;QAChE,OAAO;YACL,GAAG,GAAG;YACN,uCAAuC;YACvC,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,IAAI,EACF,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC;gBAC3B,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,mBAAmB;gBACrE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,kDAAkD;gBACzE,CAAC,CAAC,GAAG,CAAC,IAAI;YACd,kEAAkE;YAClE,iEAAiE;SAClE,CAAA;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,uBAAuB,CAA4C,EAC1E,IAAI,EACJ,OAAO,GAAG,UAAU,EACpB,UAAU,GAAG,aAAa,EAC1B,GAAG,IAAI,EACuB;IAC9B,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,EAAE,EAAE,CAAA;AAClE,CAAC;AAED,MAAM,aAAa,GAAiB,GAAG,EAAE,CAAC,CAAC,CAAA;AAE3C;;;;;GAKG;AACH,MAAM,UAAU,GAA8B,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAA","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'\nimport log, { LOGGER_NAME } from './logger'\nimport {\n CalcKeyFn,\n CalcPointsFn,\n RateLimiterI,\n RateLimiterOptions,\n RouteRateLimiter,\n WrappedRateLimiter,\n} from './rate-limiter'\nimport { ErrorFrame, Frame, MessageFrame, XrpcStreamServer } from './stream'\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'\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'\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 {\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,5 +1,5 @@
1
1
  import { LexValue } from '@atproto/lex-data';
2
- import { ErrorFrameBody, ErrorFrameHeader, FrameHeader, FrameType, MessageFrameHeader } from './types';
2
+ import { ErrorFrameBody, ErrorFrameHeader, FrameHeader, FrameType, MessageFrameHeader } from './types.js';
3
3
  export declare abstract class Frame<T extends LexValue = LexValue> {
4
4
  abstract header: FrameHeader;
5
5
  abstract body: T;