@atproto/xrpc-server 0.9.5 → 0.10.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 +26 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +7 -8
- package/dist/auth.js.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/rate-limiter.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -2
- package/dist/server.js.map +1 -1
- package/dist/stream/frames.d.ts +7 -6
- package/dist/stream/frames.d.ts.map +1 -1
- package/dist/stream/frames.js +7 -54
- package/dist/stream/frames.js.map +1 -1
- package/dist/stream/index.d.ts +0 -1
- package/dist/stream/index.d.ts.map +1 -1
- package/dist/stream/index.js +0 -1
- package/dist/stream/index.js.map +1 -1
- package/dist/stream/logger.js.map +1 -1
- package/dist/stream/server.d.ts.map +1 -1
- package/dist/stream/server.js +4 -4
- package/dist/stream/server.js.map +1 -1
- package/dist/stream/stream.d.ts +3 -3
- package/dist/stream/stream.d.ts.map +1 -1
- package/dist/stream/stream.js.map +1 -1
- package/dist/stream/subscription.d.ts.map +1 -1
- package/dist/stream/subscription.js +13 -8
- package/dist/stream/subscription.js.map +1 -1
- package/dist/stream/types.d.ts +0 -10
- package/dist/stream/types.d.ts.map +1 -1
- package/dist/stream/types.js +1 -26
- package/dist/stream/types.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js.map +1 -1
- package/dist/util.js.map +1 -1
- package/package.json +7 -6
- package/src/auth.ts +7 -8
- package/src/server.ts +3 -3
- package/src/stream/frames.ts +19 -20
- package/src/stream/index.ts +0 -1
- package/src/stream/server.ts +1 -1
- package/src/stream/stream.ts +1 -1
- package/src/stream/subscription.ts +14 -7
- package/src/stream/types.ts +0 -16
- package/tests/auth.test.ts +5 -2
- package/tests/bodies.test.ts +2 -0
- package/tests/frames.test.ts +16 -18
- package/tests/subscriptions.test.ts +1 -57
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/stream/websocket-keepalive.d.ts +0 -24
- package/dist/stream/websocket-keepalive.d.ts.map +0 -1
- package/dist/stream/websocket-keepalive.js +0 -160
- package/dist/stream/websocket-keepalive.js.map +0 -1
- package/src/stream/websocket-keepalive.ts +0 -152
package/dist/stream/server.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.XrpcStreamServer = void 0;
|
|
4
4
|
const ws_1 = require("ws");
|
|
5
|
+
const ws_client_1 = require("@atproto/ws-client");
|
|
5
6
|
const frames_1 = require("./frames");
|
|
6
7
|
const logger_1 = require("./logger");
|
|
7
|
-
const types_1 = require("./types");
|
|
8
8
|
class XrpcStreamServer {
|
|
9
9
|
constructor(opts) {
|
|
10
10
|
Object.defineProperty(this, "wss", {
|
|
@@ -36,12 +36,12 @@ class XrpcStreamServer {
|
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
if (frame instanceof frames_1.ErrorFrame) {
|
|
39
|
-
throw new
|
|
39
|
+
throw new ws_client_1.DisconnectError(ws_client_1.CloseCode.Policy, frame.body.error);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
catch (err) {
|
|
44
|
-
if (err instanceof
|
|
44
|
+
if (err instanceof ws_client_1.DisconnectError) {
|
|
45
45
|
return socket.close(err.wsCode, err.xrpcCode);
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
@@ -49,7 +49,7 @@ class XrpcStreamServer {
|
|
|
49
49
|
return socket.terminate();
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
socket.close(
|
|
52
|
+
socket.close(ws_client_1.CloseCode.Normal);
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/stream/server.ts"],"names":[],"mappings":";;;AACA,2BAA8D;AAC9D,qCAA4C;AAC5C,qCAAiC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/stream/server.ts"],"names":[],"mappings":";;;AACA,2BAA8D;AAC9D,kDAA+D;AAC/D,qCAA4C;AAC5C,qCAAiC;AAEjC,MAAa,gBAAgB;IAE3B,YAAY,IAA0C;QADtD;;;;;WAAoB;QAElB,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,GAAG,IAAI,CAAA;QACvC,IAAI,CAAC,GAAG,GAAG,IAAI,oBAAe,CAAC,UAAU,CAAC,CAAA;QAC1C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YAC9C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,eAAM,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAA;YACjE,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAA;gBAChC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;gBACtE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACxB,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAA;oBACnB,EAAE,CAAC,KAAK,EAAE,CAAA;gBACZ,CAAC,CAAC,CAAA;gBACF,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;gBACzC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBAC7B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;4BACrD,oEAAoE;4BACpE,4DAA4D;4BAC5D,IAAI,GAAG;gCAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAA;4BACxB,GAAG,CAAC,SAAS,CAAC,CAAA;wBAChB,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAA;oBACF,IAAI,KAAK,YAAY,mBAAU,EAAE,CAAC;wBAChC,MAAM,IAAI,2BAAe,CAAC,qBAAS,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;oBAC/D,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,2BAAe,EAAE,CAAC;oBACnC,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;gBAC/C,CAAC;qBAAM,CAAC;oBACN,eAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,wBAAwB,CAAC,CAAA;oBAC/C,OAAO,MAAM,CAAC,SAAS,EAAE,CAAA;gBAC3B,CAAC;YACH,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,qBAAS,CAAC,MAAM,CAAC,CAAA;QAChC,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAvCD,4CAuCC;AASD,SAAS,cAAc,CAAI,QAA0B;IACnD,OAAO,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAA;AACzC,CAAC;AAED,SAAS,YAAY,CAAI,QAA0B;IACjD,OAAO;QACL,CAAC,MAAM,CAAC,aAAa,CAAC;YACpB,OAAO,QAAQ,CAAA;QACjB,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import { IncomingMessage } from 'node:http'\nimport { ServerOptions, WebSocket, WebSocketServer } from 'ws'\nimport { CloseCode, DisconnectError } from '@atproto/ws-client'\nimport { ErrorFrame, Frame } from './frames'\nimport { logger } from './logger'\n\nexport class XrpcStreamServer {\n wss: WebSocketServer\n constructor(opts: ServerOptions & { handler: Handler }) {\n const { handler, ...serverOpts } = opts\n this.wss = new WebSocketServer(serverOpts)\n this.wss.on('connection', async (socket, req) => {\n socket.on('error', (err) => logger.error(err, 'websocket error'))\n try {\n const ac = new AbortController()\n const iterator = unwrapIterator(handler(req, ac.signal, socket, this))\n socket.once('close', () => {\n iterator.return?.()\n ac.abort()\n })\n const safeFrames = wrapIterator(iterator)\n for await (const frame of safeFrames) {\n await new Promise((res, rej) => {\n socket.send(frame.toBytes(), { binary: true }, (err) => {\n // @TODO this callback may give more aggressive on backpressure than\n // we ultimately want, but trying it out for the time being.\n if (err) return rej(err)\n res(undefined)\n })\n })\n if (frame instanceof ErrorFrame) {\n throw new DisconnectError(CloseCode.Policy, frame.body.error)\n }\n }\n } catch (err) {\n if (err instanceof DisconnectError) {\n return socket.close(err.wsCode, err.xrpcCode)\n } else {\n logger.error({ err }, 'websocket server error')\n return socket.terminate()\n }\n }\n socket.close(CloseCode.Normal)\n })\n }\n}\n\nexport type Handler = (\n req: IncomingMessage,\n signal: AbortSignal,\n socket: WebSocket,\n server: XrpcStreamServer,\n) => AsyncIterable<Frame>\n\nfunction unwrapIterator<T>(iterable: AsyncIterable<T>): AsyncIterator<T> {\n return iterable[Symbol.asyncIterator]()\n}\n\nfunction wrapIterator<T>(iterator: AsyncIterator<T>): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator]() {\n return iterator\n },\n }\n}\n"]}
|
package/dist/stream/stream.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { DuplexOptions } from 'node:stream';
|
|
|
2
2
|
import { WebSocket } from 'ws';
|
|
3
3
|
import { MessageFrame } from './frames';
|
|
4
4
|
export declare function streamByteChunks(ws: WebSocket, options?: DuplexOptions): import("stream").Duplex;
|
|
5
|
-
export declare function byFrame(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<
|
|
6
|
-
export declare function byMessage(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<
|
|
7
|
-
export declare function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame
|
|
5
|
+
export declare function byFrame(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<import("@atproto/lex-data").LexValue> | import("./frames").ErrorFrame<string>, void, unknown>;
|
|
6
|
+
export declare function byMessage(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<import("@atproto/lex-data").LexValue>, void, unknown>;
|
|
7
|
+
export declare function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame;
|
|
8
8
|
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAyB,MAAM,IAAI,CAAA;AAErD,OAAO,EAAS,YAAY,EAAE,MAAM,UAAU,CAAA;AAE9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,2BAKtE;AAED,wBAAuB,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAyB,MAAM,IAAI,CAAA;AAErD,OAAO,EAAS,YAAY,EAAE,MAAM,UAAU,CAAA;AAE9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,2BAKtE;AAED,wBAAuB,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,6HAKpE;AAED,wBAAuB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,qFAMtE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CAWpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream/stream.ts"],"names":[],"mappings":";;AAKA,4CAKC;AAED,0BAKC;AAED,8BAMC;AAED,oDAWC;AArCD,2BAAqD;AACrD,wCAAuD;AACvD,qCAA8C;AAE9C,SAAgB,gBAAgB,CAAC,EAAa,EAAE,OAAuB;IACrE,OAAO,IAAA,0BAAqB,EAAC,EAAE,EAAE;QAC/B,GAAG,OAAO;QACV,kBAAkB,EAAE,IAAI,EAAE,2DAA2D;KACtF,CAAC,CAAA;AACJ,CAAC;AAEM,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,EAAa,EAAE,OAAuB;IACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,cAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAEM,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,EAAa,EAAE,OAAuB;IACrE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,KAAiB;IACpD,MAAM,KAAK,GAAG,cAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3B,0CAA0C;QAC1C,aAAa;QACb,MAAM,IAAI,gBAAS,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IACpD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,gBAAS,CAAC,mBAAY,CAAC,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream/stream.ts"],"names":[],"mappings":";;AAKA,4CAKC;AAED,0BAKC;AAED,8BAMC;AAED,oDAWC;AArCD,2BAAqD;AACrD,wCAAuD;AACvD,qCAA8C;AAE9C,SAAgB,gBAAgB,CAAC,EAAa,EAAE,OAAuB;IACrE,OAAO,IAAA,0BAAqB,EAAC,EAAE,EAAE;QAC/B,GAAG,OAAO;QACV,kBAAkB,EAAE,IAAI,EAAE,2DAA2D;KACtF,CAAC,CAAA;AACJ,CAAC;AAEM,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,EAAa,EAAE,OAAuB;IACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,cAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAEM,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,EAAa,EAAE,OAAuB;IACrE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAgB,oBAAoB,CAAC,KAAiB;IACpD,MAAM,KAAK,GAAG,cAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3B,0CAA0C;QAC1C,aAAa;QACb,MAAM,IAAI,gBAAS,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IACpD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,gBAAS,CAAC,mBAAY,CAAC,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC","sourcesContent":["import { DuplexOptions } from 'node:stream'\nimport { WebSocket, createWebSocketStream } from 'ws'\nimport { ResponseType, XRPCError } from '@atproto/xrpc'\nimport { Frame, MessageFrame } from './frames'\n\nexport function streamByteChunks(ws: WebSocket, options?: DuplexOptions) {\n return createWebSocketStream(ws, {\n ...options,\n readableObjectMode: true, // Ensures frame bytes don't get buffered/combined together\n })\n}\n\nexport async function* byFrame(ws: WebSocket, options?: DuplexOptions) {\n const wsStream = streamByteChunks(ws, options)\n for await (const chunk of wsStream) {\n yield Frame.fromBytes(chunk)\n }\n}\n\nexport async function* byMessage(ws: WebSocket, options?: DuplexOptions) {\n const wsStream = streamByteChunks(ws, options)\n for await (const chunk of wsStream) {\n const msg = ensureChunkIsMessage(chunk)\n yield msg\n }\n}\n\nexport function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame {\n const frame = Frame.fromBytes(chunk)\n if (frame.isMessage()) {\n return frame\n } else if (frame.isError()) {\n // @TODO work -1 error code into XRPCError\n // @ts-ignore\n throw new XRPCError(-1, frame.code, frame.message)\n } else {\n throw new XRPCError(ResponseType.Unknown, undefined, 'Unknown frame type')\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAKlC,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IAE1B,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd;gBAhBM,IAAI,EAAE,aAAa,GAAG;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;QAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,SAAS,CAAA;QACzC,gBAAgB,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,MAAM,EACT,YAAY,EAAE,OAAO,KAClB,IAAI,CAAA;QACT,SAAS,CAAC,EAAE,MACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,GAC5C,SAAS,CAAA;KACd;IAGI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC;CA4BnD;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Subscription = void 0;
|
|
4
|
+
const lex_data_1 = require("@atproto/lex-data");
|
|
5
|
+
const ws_client_1 = require("@atproto/ws-client");
|
|
4
6
|
const stream_1 = require("./stream");
|
|
5
|
-
const websocket_keepalive_1 = require("./websocket-keepalive");
|
|
6
7
|
class Subscription {
|
|
7
8
|
constructor(opts) {
|
|
8
9
|
Object.defineProperty(this, "opts", {
|
|
@@ -13,7 +14,7 @@ class Subscription {
|
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
16
|
async *[Symbol.asyncIterator]() {
|
|
16
|
-
const ws = new
|
|
17
|
+
const ws = new ws_client_1.WebSocketKeepAlive({
|
|
17
18
|
...this.opts,
|
|
18
19
|
getUrl: async () => {
|
|
19
20
|
const params = (await this.opts.getParams?.()) ?? {};
|
|
@@ -22,13 +23,17 @@ class Subscription {
|
|
|
22
23
|
},
|
|
23
24
|
});
|
|
24
25
|
for await (const chunk of ws) {
|
|
25
|
-
const message =
|
|
26
|
+
const message = (0, stream_1.ensureChunkIsMessage)(chunk);
|
|
26
27
|
const t = message.header.t;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const typedBody = (0, lex_data_1.isPlainObject)(message.body)
|
|
29
|
+
? t !== undefined
|
|
30
|
+
? {
|
|
31
|
+
...message.body,
|
|
32
|
+
$type: t.startsWith('#') ? this.opts.method + t : t,
|
|
33
|
+
}
|
|
34
|
+
: message.body
|
|
35
|
+
: undefined;
|
|
36
|
+
const result = this.opts.validate(typedBody);
|
|
32
37
|
if (result !== undefined) {
|
|
33
38
|
yield result;
|
|
34
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":";;;AACA,qCAA+C;
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../src/stream/subscription.ts"],"names":[],"mappings":";;;AACA,gDAAiD;AACjD,kDAAuD;AACvD,qCAA+C;AAE/C,MAAa,YAAY;IACvB,YACS,IAgBN;QAhBD;;;;mBAAO,IAAI;WAgBV;IACA,CAAC;IAEJ,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,MAAM,EAAE,GAAG,IAAI,8BAAkB,CAAC;YAChC,GAAG,IAAI,CAAC,IAAI;YACZ,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;gBACpD,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBACvC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAA;YACjE,CAAC;SACF,CAAC,CAAA;QACF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,IAAA,6BAAoB,EAAC,KAAK,CAAC,CAAA;YAC3C,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YAE1B,MAAM,SAAS,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,IAAI,CAAC;gBAC3C,CAAC,CAAC,CAAC,KAAK,SAAS;oBACf,CAAC,CAAC;wBACE,GAAG,OAAO,CAAC,IAAI;wBACf,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;qBACpD;oBACH,CAAC,CAAC,OAAO,CAAC,IAAI;gBAChB,CAAC,CAAC,SAAS,CAAA;YAEb,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YAC5C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,MAAM,CAAA;YACd,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAjDD,oCAiDC;AAED,kBAAe,YAAY,CAAA;AAE3B,SAAS,iBAAiB,CAAC,GAA4B;IACrD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IACpC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAA;AAC1B,CAAC;AAED,4DAA4D;AAC5D,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACzB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IACjC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,WAAW,EAAE,CAAA;QAC5B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACxC,CAAC;aAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,OAAO,KAAK,qBAAqB,CAAC,CAAA;AACrE,CAAC","sourcesContent":["import { ClientOptions } from 'ws'\nimport { isPlainObject } from '@atproto/lex-data'\nimport { WebSocketKeepAlive } from '@atproto/ws-client'\nimport { ensureChunkIsMessage } from './stream'\n\nexport class Subscription<T = unknown> {\n constructor(\n public opts: ClientOptions & {\n service: string\n method: string\n maxReconnectSeconds?: number\n heartbeatIntervalMs?: number\n signal?: AbortSignal\n validate: (obj: unknown) => T | undefined\n onReconnectError?: (\n error: unknown,\n n: number,\n initialSetup: boolean,\n ) => void\n getParams?: () =>\n | Record<string, unknown>\n | Promise<Record<string, unknown> | undefined>\n | undefined\n },\n ) {}\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n const ws = new WebSocketKeepAlive({\n ...this.opts,\n getUrl: async () => {\n const params = (await this.opts.getParams?.()) ?? {}\n const query = encodeQueryParams(params)\n return `${this.opts.service}/xrpc/${this.opts.method}?${query}`\n },\n })\n for await (const chunk of ws) {\n const message = ensureChunkIsMessage(chunk)\n const t = message.header.t\n\n const typedBody = isPlainObject(message.body)\n ? t !== undefined\n ? {\n ...message.body,\n $type: t.startsWith('#') ? this.opts.method + t : t,\n }\n : message.body\n : undefined\n\n const result = this.opts.validate(typedBody)\n if (result !== undefined) {\n yield result\n }\n }\n }\n}\n\nexport default Subscription\n\nfunction encodeQueryParams(obj: Record<string, unknown>): string {\n const params = new URLSearchParams()\n Object.entries(obj).forEach(([key, value]) => {\n const encoded = encodeQueryParam(value)\n if (Array.isArray(encoded)) {\n encoded.forEach((enc) => params.append(key, enc))\n } else {\n params.set(key, encoded)\n }\n })\n return params.toString()\n}\n\n// Adapted from xrpc, but without any lex-specific knowledge\nfunction encodeQueryParam(value: unknown): string | string[] {\n if (typeof value === 'string') {\n return value\n }\n if (typeof value === 'number') {\n return value.toString()\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'undefined') {\n return ''\n }\n if (typeof value === 'object') {\n if (value instanceof Date) {\n return value.toISOString()\n } else if (Array.isArray(value)) {\n return value.flatMap(encodeQueryParam)\n } else if (!value) {\n return ''\n }\n }\n throw new Error(`Cannot encode ${typeof value}s into query params`)\n}\n"]}
|
package/dist/stream/types.d.ts
CHANGED
|
@@ -52,14 +52,4 @@ export declare const frameHeader: z.ZodUnion<[z.ZodObject<{
|
|
|
52
52
|
op: FrameType.Error;
|
|
53
53
|
}>]>;
|
|
54
54
|
export type FrameHeader = z.infer<typeof frameHeader>;
|
|
55
|
-
export declare class DisconnectError extends Error {
|
|
56
|
-
wsCode: CloseCode;
|
|
57
|
-
xrpcCode?: string | undefined;
|
|
58
|
-
constructor(wsCode?: CloseCode, xrpcCode?: string | undefined);
|
|
59
|
-
}
|
|
60
|
-
export declare enum CloseCode {
|
|
61
|
-
Normal = 1000,
|
|
62
|
-
Abnormal = 1006,
|
|
63
|
-
Policy = 1008
|
|
64
|
-
}
|
|
65
55
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,oBAAY,SAAS;IACnB,OAAO,IAAI;IACX,KAAK,KAAK;CACX;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,eAAO,MAAM,gBAAgB;;;;;;EAE3B,CAAA;AACF,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG,CAAC,CAAC,KAAK,CAC5E,OAAO,cAAc,CACtB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;IAAkD,CAAA;AAC1E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,oBAAY,SAAS;IACnB,OAAO,IAAI;IACX,KAAK,KAAK;CACX;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAA;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEnE,eAAO,MAAM,gBAAgB;;;;;;EAE3B,CAAA;AACF,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAA;AACF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG,CAAC,CAAC,KAAK,CAC5E,OAAO,cAAc,CACtB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;IAAkD,CAAA;AAC1E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA"}
|
package/dist/stream/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.frameHeader = exports.errorFrameBody = exports.errorFrameHeader = exports.messageFrameHeader = exports.FrameType = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
var FrameType;
|
|
6
6
|
(function (FrameType) {
|
|
@@ -19,29 +19,4 @@ exports.errorFrameBody = zod_1.z.object({
|
|
|
19
19
|
message: zod_1.z.string().optional(), // Error message
|
|
20
20
|
});
|
|
21
21
|
exports.frameHeader = zod_1.z.union([exports.messageFrameHeader, exports.errorFrameHeader]);
|
|
22
|
-
class DisconnectError extends Error {
|
|
23
|
-
constructor(wsCode = CloseCode.Policy, xrpcCode) {
|
|
24
|
-
super();
|
|
25
|
-
Object.defineProperty(this, "wsCode", {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
configurable: true,
|
|
28
|
-
writable: true,
|
|
29
|
-
value: wsCode
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(this, "xrpcCode", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
configurable: true,
|
|
34
|
-
writable: true,
|
|
35
|
-
value: xrpcCode
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.DisconnectError = DisconnectError;
|
|
40
|
-
// https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
|
|
41
|
-
var CloseCode;
|
|
42
|
-
(function (CloseCode) {
|
|
43
|
-
CloseCode[CloseCode["Normal"] = 1000] = "Normal";
|
|
44
|
-
CloseCode[CloseCode["Abnormal"] = 1006] = "Abnormal";
|
|
45
|
-
CloseCode[CloseCode["Policy"] = 1008] = "Policy";
|
|
46
|
-
})(CloseCode || (exports.CloseCode = CloseCode = {}));
|
|
47
22
|
//# sourceMappingURL=types.js.map
|
package/dist/stream/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEvB,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,+CAAW,CAAA;IACX,4CAAU,CAAA;AACZ,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAEY,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,WAAW;IAC7C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,kCAAkC;CAC7D,CAAC,CAAA;AAGW,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;CAC/B,CAAC,CAAA;AACW,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,aAAa;IAChC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,gBAAgB;CACjD,CAAC,CAAA;AAMW,QAAA,WAAW,GAAG,OAAC,CAAC,KAAK,CAAC,CAAC,0BAAkB,EAAE,wBAAgB,CAAC,CAAC,CAAA
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEvB,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,+CAAW,CAAA;IACX,4CAAU,CAAA;AACZ,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAEY,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,WAAW;IAC7C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,kCAAkC;CAC7D,CAAC,CAAA;AAGW,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;CAC/B,CAAC,CAAA;AACW,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,aAAa;IAChC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,gBAAgB;CACjD,CAAC,CAAA;AAMW,QAAA,WAAW,GAAG,OAAC,CAAC,KAAK,CAAC,CAAC,0BAAkB,EAAE,wBAAgB,CAAC,CAAC,CAAA","sourcesContent":["import { z } from 'zod'\n\nexport enum FrameType {\n Message = 1,\n Error = -1,\n}\n\nexport const messageFrameHeader = z.object({\n op: z.literal(FrameType.Message), // Frame op\n t: z.string().optional(), // Message body type discriminator\n})\nexport type MessageFrameHeader = z.infer<typeof messageFrameHeader>\n\nexport const errorFrameHeader = z.object({\n op: z.literal(FrameType.Error),\n})\nexport const errorFrameBody = z.object({\n error: z.string(), // Error code\n message: z.string().optional(), // Error message\n})\nexport type ErrorFrameHeader = z.infer<typeof errorFrameHeader>\nexport type ErrorFrameBody<T extends string = string> = { error: T } & z.infer<\n typeof errorFrameBody\n>\n\nexport const frameHeader = z.union([messageFrameHeader, errorFrameHeader])\nexport type FrameHeader = z.infer<typeof frameHeader>\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -49,12 +49,12 @@ export declare const handlerSuccess: z.ZodObject<{
|
|
|
49
49
|
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
50
50
|
}, "strip", z.ZodTypeAny, {
|
|
51
51
|
encoding: string;
|
|
52
|
-
headers?: Record<string, string> | undefined;
|
|
53
52
|
body?: any;
|
|
53
|
+
headers?: Record<string, string> | undefined;
|
|
54
54
|
}, {
|
|
55
55
|
encoding: string;
|
|
56
|
-
headers?: Record<string, string> | undefined;
|
|
57
56
|
body?: any;
|
|
57
|
+
headers?: Record<string, string> | undefined;
|
|
58
58
|
}>;
|
|
59
59
|
export type HandlerSuccess = z.infer<typeof handlerSuccess>;
|
|
60
60
|
export declare const handlerPipeThroughBuffer: z.ZodObject<{
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAmKA,sDAIC;AAoED,gEAKC;AAED,gEAKC;AAtPD,6CAAsC;AAEtC,6BAAuB;AAkDV,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAA;AAIpC,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,IAAI,EAAE,OAAC,CAAC,GAAG,EAAE;IACb,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,OAAC,CAAC,UAAU,CAAC,MAAM,CAAC;IAC5B,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,OAAC,CAAC,UAAU,CAAC,sBAAQ,CAAC;IAC9B,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,kBAAkB,GAAG,OAAC,CAAC,KAAK,CAAC;IACxC,gCAAwB;IACxB,gCAAwB;CACzB,CAAC,CAAA;AA+EF,SAAgB,qBAAqB,CAEnC,IAAsB;IACtB,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAA;AACzC,CAAC;AAoED,SAAgB,0BAA0B,CACxC,MAAc;IAEd,8DAA8D;IAC9D,OAAO,MAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAA;AAC/E,CAAC;AAED,SAAgB,0BAA0B,CACxC,MAAc;IAEd,8DAA8D;IAC9D,OAAO,MAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAA;AAC/E,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAmKA,sDAIC;AAoED,gEAKC;AAED,gEAKC;AAtPD,6CAAsC;AAEtC,6BAAuB;AAkDV,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAA;AAIpC,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,IAAI,EAAE,OAAC,CAAC,GAAG,EAAE;IACb,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,OAAC,CAAC,UAAU,CAAC,MAAM,CAAC;IAC5B,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,OAAC,CAAC,UAAU,CAAC,sBAAQ,CAAC;IAC9B,OAAO,EAAE,qBAAa,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAA;AAIW,QAAA,kBAAkB,GAAG,OAAC,CAAC,KAAK,CAAC;IACxC,gCAAwB;IACxB,gCAAwB;CACzB,CAAC,CAAA;AA+EF,SAAgB,qBAAqB,CAEnC,IAAsB;IACtB,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAA;AACzC,CAAC;AAoED,SAAgB,0BAA0B,CACxC,MAAc;IAEd,8DAA8D;IAC9D,OAAO,MAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAA;AAC/E,CAAC;AAED,SAAgB,0BAA0B,CACxC,MAAc;IAEd,8DAA8D;IAC9D,OAAO,MAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAA;AAC/E,CAAC","sourcesContent":["import { IncomingMessage } from 'node:http'\nimport { Readable } from 'node:stream'\nimport { NextFunction, Request, Response } from 'express'\nimport { z } from 'zod'\nimport { ErrorResult, XRPCError } from './errors'\nimport { CalcKeyFn, CalcPointsFn, RateLimiterI } from './rate-limiter'\n\nexport type Awaitable<T> = T | Promise<T>\n\nexport type CatchallHandler = (\n req: Request,\n res: Response,\n next: NextFunction,\n) => unknown\n\nexport type Options = {\n validateResponse?: boolean\n catchall?: CatchallHandler\n payload?: RouteOptions\n rateLimits?: {\n creator: RateLimiterCreator<HandlerContext>\n global?: ServerRateLimitDescription<HandlerContext>[]\n shared?: ServerRateLimitDescription<HandlerContext>[]\n bypass?: (ctx: HandlerContext) => boolean\n }\n /**\n * By default, errors are converted to {@link XRPCError} using\n * {@link XRPCError.fromError} before being rendered. If method handlers throw\n * error objects that are not properly rendered in the HTTP response, this\n * function can be used to properly convert them to {@link XRPCError}. The\n * provided function will typically fallback to the default error conversion\n * (`return XRPCError.fromError(err)`) if the error is not recognized.\n *\n * @note This function should not throw errors.\n */\n errorParser?: (err: unknown) => XRPCError\n}\n\nexport type UndecodedParams = Request['query']\n\nexport type Primitive = string | number | boolean\nexport type Params = { [P in string]?: undefined | Primitive | Primitive[] }\n\nexport type HandlerInput = {\n encoding: string\n body: unknown\n}\n\nexport type AuthResult = {\n credentials: unknown\n artifacts?: unknown\n}\n\nexport const headersSchema = z.record(z.string())\n\nexport type Headers = z.infer<typeof headersSchema>\n\nexport const handlerSuccess = z.object({\n encoding: z.string(),\n body: z.any(),\n headers: headersSchema.optional(),\n})\n\nexport type HandlerSuccess = z.infer<typeof handlerSuccess>\n\nexport const handlerPipeThroughBuffer = z.object({\n encoding: z.string(),\n buffer: z.instanceof(Buffer),\n headers: headersSchema.optional(),\n})\n\nexport type HandlerPipeThroughBuffer = z.infer<typeof handlerPipeThroughBuffer>\n\nexport const handlerPipeThroughStream = z.object({\n encoding: z.string(),\n stream: z.instanceof(Readable),\n headers: headersSchema.optional(),\n})\n\nexport type HandlerPipeThroughStream = z.infer<typeof handlerPipeThroughStream>\n\nexport const handlerPipeThrough = z.union([\n handlerPipeThroughBuffer,\n handlerPipeThroughStream,\n])\n\nexport type HandlerPipeThrough = z.infer<typeof handlerPipeThrough>\n\nexport type Auth = void | AuthResult\nexport type Input = void | HandlerInput\nexport type Output = void | HandlerSuccess | ErrorResult\n\nexport type AuthVerifier<C, A extends AuthResult = AuthResult> =\n | ((ctx: C) => Awaitable<A | ErrorResult>)\n | ((ctx: C) => Awaitable<A>)\n\nexport type MethodAuthContext<P extends Params = Params> = {\n params: P\n req: Request\n res: Response\n}\n\nexport type MethodAuthVerifier<\n A extends AuthResult = AuthResult,\n P extends Params = Params,\n> = AuthVerifier<MethodAuthContext<P>, A>\n\nexport type HandlerContext<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n> = MethodAuthContext<P> & {\n auth: A\n input: I\n resetRouteRateLimits: () => Promise<void>\n}\n\nexport type MethodHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n O extends Output = Output,\n> = (ctx: HandlerContext<A, P, I>) => Awaitable<O | HandlerPipeThrough>\n\nexport type RateLimiterCreator<T extends HandlerContext = HandlerContext> = <\n C extends T = T,\n>(opts: {\n keyPrefix: string\n durationMs: number\n points: number\n calcKey: CalcKeyFn<C>\n calcPoints: CalcPointsFn<C>\n failClosed?: boolean\n}) => RateLimiterI<C>\n\nexport type ServerRateLimitDescription<\n C extends HandlerContext = HandlerContext,\n> = {\n name: string\n durationMs: number\n points: number\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n failClosed?: boolean\n}\n\nexport type SharedRateLimitOpts<C extends HandlerContext = HandlerContext> = {\n name: string\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\nexport type RouteRateLimitOpts<C extends HandlerContext = HandlerContext> = {\n durationMs: number\n points: number\n calcKey?: CalcKeyFn<C>\n calcPoints?: CalcPointsFn<C>\n}\n\nexport type RateLimitOpts<C extends HandlerContext = HandlerContext> =\n | SharedRateLimitOpts<C>\n | RouteRateLimitOpts<C>\n\nexport function isSharedRateLimitOpts<\n C extends HandlerContext = HandlerContext,\n>(opts: RateLimitOpts<C>): opts is SharedRateLimitOpts<C> {\n return typeof opts['name'] === 'string'\n}\n\nexport type RouteOptions = {\n blobLimit?: number\n jsonLimit?: number\n textLimit?: number\n}\n\nexport type MethodConfig<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n O extends Output = Output,\n> = {\n handler: MethodHandler<A, P, I, O>\n auth?: MethodAuthVerifier<Extract<A, AuthResult>, P>\n opts?: RouteOptions\n rateLimit?:\n | RateLimitOpts<HandlerContext<A, P, I>>\n | RateLimitOpts<HandlerContext<A, P, I>>[]\n}\n\nexport type MethodConfigOrHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n I extends Input = Input,\n O extends Output = Output,\n> = MethodHandler<A, P, I, O> | MethodConfig<A, P, I, O>\n\nexport type StreamAuthContext<P extends Params = Params> = {\n params: P\n req: IncomingMessage\n}\n\nexport type StreamAuthVerifier<\n A extends AuthResult = AuthResult,\n P extends Params = Params,\n> = AuthVerifier<StreamAuthContext<P>, A>\n\nexport type StreamContext<\n A extends Auth = Auth,\n P extends Params = Params,\n> = StreamAuthContext<P> & {\n auth: A\n signal: AbortSignal\n}\n\nexport type StreamHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n O = unknown,\n> = (ctx: StreamContext<A, P>) => AsyncIterable<O>\n\nexport type StreamConfig<\n A extends Auth = Auth,\n P extends Params = Params,\n O = unknown,\n> = {\n auth?: StreamAuthVerifier<Extract<A, AuthResult>, P>\n handler: StreamHandler<A, P, O>\n}\n\nexport type StreamConfigOrHandler<\n A extends Auth = Auth,\n P extends Params = Params,\n O = unknown,\n> = StreamHandler<A, P, O> | StreamConfig<A, P, O>\n\nexport function isHandlerPipeThroughBuffer(\n output: Output,\n): output is HandlerPipeThroughBuffer {\n // We only need to discriminate between possible Output values\n return output != null && 'buffer' in output && output['buffer'] !== undefined\n}\n\nexport function isHandlerPipeThroughStream(\n output: Output,\n): output is HandlerPipeThroughStream {\n // We only need to discriminate between possible Output values\n return output != null && 'stream' in output && output['stream'] !== undefined\n}\n"]}
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { IncomingMessage, OutgoingMessage } from 'node:http'\nimport { Duplex, Readable, pipeline } from 'node:stream'\nimport { Request, Response, json, text } from 'express'\nimport { contentType } from 'mime-types'\nimport { MaxSizeChecker, createDecoders } from '@atproto/common'\nimport {\n LexXrpcBody,\n LexXrpcProcedure,\n LexXrpcQuery,\n LexXrpcSubscription,\n Lexicons,\n jsonToLex,\n} from '@atproto/lexicon'\nimport { ResponseType } from '@atproto/xrpc'\nimport { InternalServerError, InvalidRequestError, XRPCError } from './errors'\nimport {\n Awaitable,\n HandlerSuccess,\n Input,\n Params,\n RouteOptions,\n UndecodedParams,\n handlerSuccess,\n} from './types'\n\nexport const asArray = <T>(arr: T | T[]): T[] =>\n Array.isArray(arr) ? arr : [arr]\n\nexport function setHeaders(\n res: OutgoingMessage,\n headers?: Record<string, string | number>,\n) {\n if (headers) {\n for (const [name, val] of Object.entries(headers)) {\n if (val != null) res.setHeader(name, val)\n }\n }\n}\n\nexport function decodeQueryParams(\n def: LexXrpcProcedure | LexXrpcQuery | LexXrpcSubscription,\n params: UndecodedParams,\n): Params {\n const decoded: Params = {}\n for (const k in params) {\n const val = params[k]\n const property = def.parameters?.properties?.[k]\n if (property) {\n if (property.type === 'array') {\n const vals: (typeof val)[] = []\n decoded[k] = val\n ? vals\n .concat(val) // Cast to array\n .flatMap((v) => decodeQueryParam(property.items.type, v) ?? [])\n : undefined\n } else {\n decoded[k] = decodeQueryParam(property.type, val)\n }\n }\n }\n return decoded\n}\n\nexport function decodeQueryParam(\n type: string,\n value: unknown,\n): string | number | boolean | undefined {\n if (!value) {\n return undefined\n }\n if (type === 'string' || type === 'datetime') {\n return String(value)\n }\n if (type === 'float') {\n return Number(String(value))\n } else if (type === 'integer') {\n return parseInt(String(value), 10) || 0\n } else if (type === 'boolean') {\n return value === 'true'\n }\n}\n\nexport type QueryParams = Record<string, undefined | string | string[]>\nexport function getQueryParams(url = ''): QueryParams {\n const result: QueryParams = Object.create(null)\n\n const queryStringIdx = url.indexOf('?')\n if (queryStringIdx === -1) return result\n\n const queryString = url.slice(queryStringIdx + 1)\n if (queryString === '') return result\n\n const searchParams = new URLSearchParams(queryString)\n for (const key of searchParams.keys()) {\n if (key === '__proto__') {\n // Prevent prototype pollution\n throw new InvalidRequestError(\n `Invalid query parameter: ${key}`,\n 'InvalidQueryParameter',\n )\n }\n\n const values = searchParams.getAll(key)\n result[key] = values.length === 1 ? values[0] : values\n }\n\n return result\n}\n\nexport function createInputVerifier(\n nsid: string,\n def: LexXrpcProcedure | LexXrpcQuery,\n options: RouteOptions,\n lexicons: Lexicons,\n): (req: Request, res: Response) => Awaitable<Input> {\n if (def.type === 'query' || !def.input) {\n return (req) => {\n // @NOTE We allow (and ignore) \"empty\" bodies\n if (getBodyPresence(req) === 'present') {\n throw new InvalidRequestError(\n `A request body was provided when none was expected`,\n )\n }\n\n return undefined\n }\n }\n\n // Lexicon definition expects a request body\n\n const { input } = def\n const { blobLimit } = options\n\n const allowedEncodings = parseDefEncoding(input)\n const checkEncoding = allowedEncodings.includes(ENCODING_ANY)\n ? undefined // No need to check\n : (encoding: string) => allowedEncodings.includes(encoding)\n\n const bodyParser = createBodyParser(input.encoding, options)\n\n return async (req, res) => {\n if (getBodyPresence(req) === 'missing') {\n throw new InvalidRequestError(\n `A request body is expected but none was provided`,\n )\n }\n\n const reqEncoding = parseReqEncoding(req)\n if (checkEncoding && !checkEncoding(reqEncoding)) {\n throw new InvalidRequestError(\n `Wrong request encoding (Content-Type): ${reqEncoding}`,\n )\n }\n\n if (bodyParser) {\n await bodyParser(req, res)\n }\n\n if (input.schema) {\n try {\n const lexBody = req.body ? jsonToLex(req.body) : req.body\n req.body = lexicons.assertValidXrpcInput(nsid, lexBody)\n } catch (e) {\n throw new InvalidRequestError(\n e instanceof Error ? e.message : String(e),\n )\n }\n }\n\n // if middleware already got the body, we pass that along as input\n // otherwise, we pass along a decoded readable stream\n const body = req.readableEnded ? req.body : decodeBodyStream(req, blobLimit)\n\n return { encoding: reqEncoding, body }\n }\n}\n\nexport function validateOutput(\n nsid: string,\n def: LexXrpcProcedure | LexXrpcQuery,\n output: HandlerSuccess | void,\n lexicons: Lexicons,\n): void {\n if (def.output) {\n // An output is expected\n if (output === undefined) {\n throw new InternalServerError(\n `A response body is expected but none was provided`,\n )\n }\n\n // Fool-proofing (should not be necessary due to type system)\n const result = handlerSuccess.safeParse(output)\n if (!result.success) {\n throw new InternalServerError(`Invalid handler output`, undefined, {\n cause: result.error,\n })\n }\n\n // output mime\n const { encoding } = output\n if (!encoding || !isValidEncoding(def.output, encoding)) {\n throw new InternalServerError(`Invalid response encoding: ${encoding}`)\n }\n\n // output schema\n if (def.output.schema) {\n try {\n output.body = lexicons.assertValidXrpcOutput(nsid, output.body)\n } catch (e) {\n throw new InternalServerError(\n e instanceof Error ? e.message : String(e),\n )\n }\n }\n } else {\n // Expects no output\n if (output !== undefined) {\n throw new InternalServerError(\n `A response body was provided when none was expected`,\n )\n }\n }\n}\n\nexport function parseReqEncoding(req: IncomingMessage): string {\n const encoding = normalizeMime(req.headers['content-type'])\n if (encoding) return encoding\n throw new InvalidRequestError(\n `Request encoding (Content-Type) required but not provided`,\n )\n}\n\nfunction normalizeMime(v?: string): string | null {\n if (!v) return null\n const fullType = contentType(v)\n if (!fullType) return null\n const shortType = fullType.split(';')[0]\n if (!shortType) return null\n return shortType\n}\n\nconst ENCODING_ANY = '*/*'\n\nfunction parseDefEncoding({ encoding }: LexXrpcBody) {\n return encoding.split(',').map(trimString)\n}\n\nfunction trimString(str: string): string {\n return str.trim()\n}\n\nfunction isValidEncoding(output: LexXrpcBody, encoding: string) {\n const normalized = normalizeMime(encoding)\n if (!normalized) return false\n\n const allowed = parseDefEncoding(output)\n return allowed.includes(ENCODING_ANY) || allowed.includes(normalized)\n}\n\ntype BodyPresence = 'missing' | 'empty' | 'present'\n\nfunction getBodyPresence(req: IncomingMessage): BodyPresence {\n if (req.headers['transfer-encoding'] != null) return 'present'\n if (req.headers['content-length'] === '0') return 'empty'\n if (req.headers['content-length'] != null) return 'present'\n return 'missing'\n}\n\nfunction createBodyParser(inputEncoding: string, options: RouteOptions) {\n if (inputEncoding === ENCODING_ANY) {\n // When the lexicon's input encoding is */*, the handler will determine how to process it\n return\n }\n const { jsonLimit, textLimit } = options\n const jsonParser = json({ limit: jsonLimit })\n const textParser = text({ limit: textLimit })\n // Transform json and text parser middlewares into a single function\n return (req: Request, res: Response) => {\n return new Promise<void>((resolve, reject) => {\n jsonParser(req, res, (err) => {\n if (err) return reject(XRPCError.fromError(err))\n textParser(req, res, (err) => {\n if (err) return reject(XRPCError.fromError(err))\n resolve()\n })\n })\n })\n }\n}\n\nfunction decodeBodyStream(\n req: IncomingMessage,\n maxSize: number | undefined,\n): Readable {\n const contentEncoding = req.headers['content-encoding']\n const contentLength = req.headers['content-length']\n\n const contentLengthParsed = contentLength\n ? parseInt(contentLength, 10)\n : undefined\n\n if (Number.isNaN(contentLengthParsed)) {\n throw new XRPCError(ResponseType.InvalidRequest, 'invalid content-length')\n }\n\n if (\n maxSize !== undefined &&\n contentLengthParsed !== undefined &&\n contentLengthParsed > maxSize\n ) {\n throw new XRPCError(\n ResponseType.PayloadTooLarge,\n 'request entity too large',\n )\n }\n\n let transforms: Duplex[]\n try {\n transforms = createDecoders(contentEncoding)\n } catch (cause) {\n throw new XRPCError(\n ResponseType.UnsupportedMediaType,\n 'unsupported content-encoding',\n undefined,\n { cause },\n )\n }\n\n if (maxSize !== undefined) {\n const maxSizeChecker = new MaxSizeChecker(\n maxSize,\n () =>\n new XRPCError(ResponseType.PayloadTooLarge, 'request entity too large'),\n )\n transforms.push(maxSizeChecker)\n }\n\n return transforms.length > 0\n ? (pipeline([req, ...transforms], () => {}) as Duplex)\n : req\n}\n\nexport function serverTimingHeader(timings: ServerTiming[]) {\n return timings\n .map((timing) => {\n let header = timing.name\n if (timing.duration) header += `;dur=${timing.duration}`\n if (timing.description) header += `;desc=\"${timing.description}\"`\n return header\n })\n .join(', ')\n}\n\nexport class ServerTimer implements ServerTiming {\n public duration?: number\n private startMs?: number\n constructor(\n public name: string,\n public description?: string,\n ) {}\n start() {\n this.startMs = Date.now()\n return this\n }\n stop() {\n assert(this.startMs, \"timer hasn't been started\")\n this.duration = Date.now() - this.startMs\n return this\n }\n}\n\nexport interface ServerTiming {\n name: string\n duration?: number\n description?: string\n}\n\nexport const parseReqNsid = (req: Request | IncomingMessage) =>\n parseUrlNsid('originalUrl' in req ? req.originalUrl : req.url || '/')\n\n/**\n * Validates and extracts the nsid from an xrpc path\n */\nexport const parseUrlNsid = (url: string): string => {\n const nsid = extractUrlNsid(url)\n if (nsid) return nsid\n throw new InvalidRequestError('invalid xrpc path')\n}\n\nexport const extractUrlNsid = (url: string): string | undefined => {\n // /!\\ Hot path\n\n if (\n // Ordered by likelihood of failure\n url.length <= 6 ||\n url[5] !== '/' ||\n url[4] !== 'c' ||\n url[3] !== 'p' ||\n url[2] !== 'r' ||\n url[1] !== 'x' ||\n url[0] !== '/'\n ) {\n return undefined\n }\n\n const startOfNsid = 6\n\n let curr = startOfNsid\n let char: number\n let alphaNumRequired = true\n for (; curr < url.length; curr++) {\n char = url.charCodeAt(curr)\n if (\n (char >= 48 && char <= 57) || // 0-9\n (char >= 65 && char <= 90) || // A-Z\n (char >= 97 && char <= 122) // a-z\n ) {\n alphaNumRequired = false\n } else if (char === 45 /* \"-\" */ || char === 46 /* \".\" */) {\n if (alphaNumRequired) {\n return undefined\n }\n alphaNumRequired = true\n } else if (char === 47 /* \"/\" */) {\n // Allow trailing slash (next char is either EOS or \"?\")\n if (curr === url.length - 1 || url.charCodeAt(curr + 1) === 63) {\n break\n }\n return undefined\n } else if (char === 63 /* \"?\"\" */) {\n break\n } else {\n return undefined\n }\n }\n\n // last char was one of: '-', '.', '/'\n if (alphaNumRequired) {\n return undefined\n }\n\n // A domain name consists of minimum two characters\n if (curr - startOfNsid < 2) {\n return undefined\n }\n\n // @TODO check max length of nsid\n\n return url.slice(startOfNsid, curr)\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/xrpc-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "atproto HTTP API (XRPC) server library",
|
|
6
6
|
"keywords": [
|
|
@@ -19,18 +19,19 @@
|
|
|
19
19
|
"main": "dist/index.js",
|
|
20
20
|
"types": "dist/index.d.ts",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"cbor-x": "^1.5.1",
|
|
23
22
|
"express": "^4.17.2",
|
|
24
23
|
"http-errors": "^2.0.0",
|
|
25
24
|
"mime-types": "^2.1.35",
|
|
26
25
|
"rate-limiter-flexible": "^2.4.1",
|
|
27
|
-
"uint8arrays": "3.0.0",
|
|
28
26
|
"ws": "^8.12.0",
|
|
29
27
|
"zod": "^3.23.8",
|
|
30
|
-
"@atproto/common": "^0.
|
|
28
|
+
"@atproto/common": "^0.5.0",
|
|
31
29
|
"@atproto/crypto": "^0.4.4",
|
|
32
|
-
"@atproto/
|
|
33
|
-
"@atproto/
|
|
30
|
+
"@atproto/lex-data": "0.0.0",
|
|
31
|
+
"@atproto/lex-cbor": "0.0.0",
|
|
32
|
+
"@atproto/lexicon": "^0.5.2",
|
|
33
|
+
"@atproto/ws-client": "^0.0.3",
|
|
34
|
+
"@atproto/xrpc": "^0.7.6"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/express": "^4.17.13",
|
package/src/auth.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as ui8 from 'uint8arrays'
|
|
2
1
|
import * as common from '@atproto/common'
|
|
3
2
|
import { MINUTE } from '@atproto/common'
|
|
4
3
|
import * as crypto from '@atproto/crypto'
|
|
@@ -46,9 +45,9 @@ export const createServiceJwt = async (
|
|
|
46
45
|
jti,
|
|
47
46
|
})
|
|
48
47
|
const toSignStr = `${jsonToB64Url(header)}.${jsonToB64Url(payload)}`
|
|
49
|
-
const toSign =
|
|
50
|
-
const sig = await keypair.sign(toSign)
|
|
51
|
-
return `${toSignStr}.${
|
|
48
|
+
const toSign = Buffer.from(toSignStr, 'utf8')
|
|
49
|
+
const sig = Buffer.from(await keypair.sign(toSign))
|
|
50
|
+
return `${toSignStr}.${sig.toString('base64url')}`
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
export const createServiceAuthHeaders = async (params: ServiceJwtParams) => {
|
|
@@ -59,7 +58,7 @@ export const createServiceAuthHeaders = async (params: ServiceJwtParams) => {
|
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
const jsonToB64Url = (json: Record<string, unknown>): string => {
|
|
62
|
-
return
|
|
61
|
+
return Buffer.from(JSON.stringify(json)).toString('base64url')
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
export type VerifySignatureWithKeyFn = (
|
|
@@ -122,8 +121,8 @@ export const verifyJwt = async (
|
|
|
122
121
|
)
|
|
123
122
|
}
|
|
124
123
|
|
|
125
|
-
const msgBytes =
|
|
126
|
-
const sigBytes =
|
|
124
|
+
const msgBytes = Buffer.from(parts.slice(0, 2).join('.'), 'utf8')
|
|
125
|
+
const sigBytes = Buffer.from(sig, 'base64url')
|
|
127
126
|
|
|
128
127
|
const signingKey = await getSigningKey(payload.iss, false)
|
|
129
128
|
const { alg } = header
|
|
@@ -182,7 +181,7 @@ export const cryptoVerifySignatureWithKey: VerifySignatureWithKeyFn = async (
|
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
const parseB64UrlToJson = (b64: string) => {
|
|
185
|
-
return JSON.parse(
|
|
184
|
+
return JSON.parse(Buffer.from(b64, 'base64url').toString('utf8'))
|
|
186
185
|
}
|
|
187
186
|
|
|
188
187
|
const parseHeader = (b64: string): ServiceJwtHeaders => {
|
package/src/server.ts
CHANGED
|
@@ -11,6 +11,7 @@ import express, {
|
|
|
11
11
|
Router,
|
|
12
12
|
} from 'express'
|
|
13
13
|
import { check, schema } from '@atproto/common'
|
|
14
|
+
import { LexMap, LexValue } from '@atproto/lex-data'
|
|
14
15
|
import {
|
|
15
16
|
LexXrpcProcedure,
|
|
16
17
|
LexXrpcQuery,
|
|
@@ -406,7 +407,7 @@ export class Server {
|
|
|
406
407
|
}
|
|
407
408
|
const type = item?.['$type']
|
|
408
409
|
if (!check.is(item, schema.map) || typeof type !== 'string') {
|
|
409
|
-
yield new MessageFrame(item)
|
|
410
|
+
yield new MessageFrame(item as LexValue)
|
|
410
411
|
continue
|
|
411
412
|
}
|
|
412
413
|
const split = type.split('#')
|
|
@@ -419,8 +420,7 @@ export class Server {
|
|
|
419
420
|
} else {
|
|
420
421
|
t = type
|
|
421
422
|
}
|
|
422
|
-
const clone =
|
|
423
|
-
delete clone['$type']
|
|
423
|
+
const { $type: _, ...clone } = item as LexMap
|
|
424
424
|
yield new MessageFrame(clone, { type: t })
|
|
425
425
|
}
|
|
426
426
|
} catch (err) {
|
package/src/stream/frames.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/* eslint-disable import/no-deprecated */
|
|
2
|
+
|
|
3
|
+
import { LexValue, decodeAll, encode } from '@atproto/lex-cbor'
|
|
3
4
|
import {
|
|
4
5
|
ErrorFrameBody,
|
|
5
6
|
ErrorFrameHeader,
|
|
@@ -10,38 +11,34 @@ import {
|
|
|
10
11
|
frameHeader,
|
|
11
12
|
} from './types'
|
|
12
13
|
|
|
13
|
-
export abstract class Frame {
|
|
14
|
+
export abstract class Frame<T extends LexValue = LexValue> {
|
|
14
15
|
abstract header: FrameHeader
|
|
15
|
-
body:
|
|
16
|
+
abstract body: T
|
|
17
|
+
|
|
16
18
|
get op(): FrameType {
|
|
17
19
|
return this.header.op
|
|
18
20
|
}
|
|
19
21
|
toBytes(): Uint8Array {
|
|
20
|
-
return
|
|
22
|
+
return Buffer.concat([encode(this.header), encode(this.body)])
|
|
21
23
|
}
|
|
22
|
-
isMessage(): this is MessageFrame
|
|
24
|
+
isMessage(): this is MessageFrame {
|
|
23
25
|
return this.op === FrameType.Message
|
|
24
26
|
}
|
|
25
27
|
isError(): this is ErrorFrame {
|
|
26
28
|
return this.op === FrameType.Error
|
|
27
29
|
}
|
|
28
30
|
static fromBytes(bytes: Uint8Array) {
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
+
const [header, body, ...rest] = decodeAll(bytes)
|
|
32
|
+
if (rest.length) {
|
|
31
33
|
throw new Error('Too many CBOR data items in frame')
|
|
34
|
+
} else if (body === undefined) {
|
|
35
|
+
throw new Error('Missing frame body')
|
|
32
36
|
}
|
|
33
|
-
|
|
34
|
-
let body: unknown = kUnset
|
|
35
|
-
if (decoded.length > 1) {
|
|
36
|
-
body = decoded[1]
|
|
37
|
-
}
|
|
37
|
+
|
|
38
38
|
const parsedHeader = frameHeader.safeParse(header)
|
|
39
39
|
if (!parsedHeader.success) {
|
|
40
40
|
throw new Error(`Invalid frame header: ${parsedHeader.error.message}`)
|
|
41
41
|
}
|
|
42
|
-
if (body === kUnset) {
|
|
43
|
-
throw new Error('Missing frame body')
|
|
44
|
-
}
|
|
45
42
|
const frameOp = parsedHeader.data.op
|
|
46
43
|
if (frameOp === FrameType.Message) {
|
|
47
44
|
return new MessageFrame(body, {
|
|
@@ -60,9 +57,10 @@ export abstract class Frame {
|
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
export class MessageFrame<T =
|
|
60
|
+
export class MessageFrame<T extends LexValue = LexValue> extends Frame<T> {
|
|
64
61
|
header: MessageFrameHeader
|
|
65
62
|
body: T
|
|
63
|
+
|
|
66
64
|
constructor(body: T, opts?: { type?: string }) {
|
|
67
65
|
super()
|
|
68
66
|
this.header =
|
|
@@ -76,9 +74,12 @@ export class MessageFrame<T = Record<string, unknown>> extends Frame {
|
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
export class ErrorFrame<T extends string = string> extends Frame
|
|
77
|
+
export class ErrorFrame<T extends string = string> extends Frame<
|
|
78
|
+
ErrorFrameBody<T>
|
|
79
|
+
> {
|
|
80
80
|
header: ErrorFrameHeader
|
|
81
81
|
body: ErrorFrameBody<T>
|
|
82
|
+
|
|
82
83
|
constructor(body: ErrorFrameBody<T>) {
|
|
83
84
|
super()
|
|
84
85
|
this.header = { op: FrameType.Error }
|
|
@@ -91,5 +92,3 @@ export class ErrorFrame<T extends string = string> extends Frame {
|
|
|
91
92
|
return this.body.message
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
-
const kUnset = Symbol('unset')
|
package/src/stream/index.ts
CHANGED
package/src/stream/server.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IncomingMessage } from 'node:http'
|
|
2
2
|
import { ServerOptions, WebSocket, WebSocketServer } from 'ws'
|
|
3
|
+
import { CloseCode, DisconnectError } from '@atproto/ws-client'
|
|
3
4
|
import { ErrorFrame, Frame } from './frames'
|
|
4
5
|
import { logger } from './logger'
|
|
5
|
-
import { CloseCode, DisconnectError } from './types'
|
|
6
6
|
|
|
7
7
|
export class XrpcStreamServer {
|
|
8
8
|
wss: WebSocketServer
|
package/src/stream/stream.ts
CHANGED
|
@@ -25,7 +25,7 @@ export async function* byMessage(ws: WebSocket, options?: DuplexOptions) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame
|
|
28
|
+
export function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame {
|
|
29
29
|
const frame = Frame.fromBytes(chunk)
|
|
30
30
|
if (frame.isMessage()) {
|
|
31
31
|
return frame
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ClientOptions } from 'ws'
|
|
2
|
+
import { isPlainObject } from '@atproto/lex-data'
|
|
3
|
+
import { WebSocketKeepAlive } from '@atproto/ws-client'
|
|
2
4
|
import { ensureChunkIsMessage } from './stream'
|
|
3
|
-
import { WebSocketKeepAlive } from './websocket-keepalive'
|
|
4
5
|
|
|
5
6
|
export class Subscription<T = unknown> {
|
|
6
7
|
constructor(
|
|
@@ -33,13 +34,19 @@ export class Subscription<T = unknown> {
|
|
|
33
34
|
},
|
|
34
35
|
})
|
|
35
36
|
for await (const chunk of ws) {
|
|
36
|
-
const message =
|
|
37
|
+
const message = ensureChunkIsMessage(chunk)
|
|
37
38
|
const t = message.header.t
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
|
|
40
|
+
const typedBody = isPlainObject(message.body)
|
|
41
|
+
? t !== undefined
|
|
42
|
+
? {
|
|
43
|
+
...message.body,
|
|
44
|
+
$type: t.startsWith('#') ? this.opts.method + t : t,
|
|
45
|
+
}
|
|
46
|
+
: message.body
|
|
47
|
+
: undefined
|
|
48
|
+
|
|
49
|
+
const result = this.opts.validate(typedBody)
|
|
43
50
|
if (result !== undefined) {
|
|
44
51
|
yield result
|
|
45
52
|
}
|