trpc-rabbitmq
Version:
tRPC adapter for RabbitMQ
131 lines • 4.98 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRMQHandler = void 0;
const server_1 = require("@trpc/server");
const amqp = __importStar(require("amqp-connection-manager"));
const errors_1 = require("./errors");
const AMQP_METHOD_PROCEDURE_TYPE_MAP = {
query: 'query',
mutation: 'mutation'
};
const createRMQHandler = (opts) => {
const { url, queue, router, durable, onError } = opts;
const connection = amqp.connect(url);
connection.createChannel({
setup: async (channel) => {
await channel.assertQueue(queue, { durable });
void channel.consume(opts.queue, async (msg) => {
if (!msg)
return;
channel.ack(msg);
const { correlationId, replyTo } = msg.properties;
if (!correlationId || !replyTo)
return;
const res = await handleMessage(router, msg, onError);
if (!res)
return;
void channel.sendToQueue(replyTo, Buffer.from(JSON.stringify({ trpc: res })), {
correlationId: correlationId
});
});
}
});
return { close: () => connection.close() };
};
exports.createRMQHandler = createRMQHandler;
async function handleMessage(router, msg, onError) {
var _a;
const { transformer } = router._def._config;
try {
const message = JSON.parse(msg.content.toString('utf-8'));
if (!('trpc' in message))
return;
const { trpc } = message;
if (!('id' in trpc) || trpc.id === null || trpc.id === undefined)
return;
if (!trpc)
return;
const { id, params } = trpc;
const type = (_a = AMQP_METHOD_PROCEDURE_TYPE_MAP[trpc.method]) !== null && _a !== void 0 ? _a : 'query';
const ctx = undefined;
try {
const path = params.path;
if (!path) {
throw new Error('No path provided');
}
if (type === 'subscription') {
throw new server_1.TRPCError({
message: 'RabbitMQ link does not support subscriptions (yet?)',
code: 'METHOD_NOT_SUPPORTED'
});
}
const deserializeInputValue = (rawValue) => {
return typeof rawValue !== 'undefined' ? transformer.input.deserialize(rawValue) : rawValue;
};
const input = deserializeInputValue(params.input);
const output = await (0, server_1.callProcedure)({
procedures: router._def.procedures,
path,
rawInput: input,
ctx,
type
});
return {
id,
result: {
type: 'data',
data: output
}
};
}
catch (cause) {
const error = (0, errors_1.getErrorFromUnknown)(cause);
onError === null || onError === void 0 ? void 0 : onError({
error,
type,
path: trpc === null || trpc === void 0 ? void 0 : trpc.path,
input: trpc === null || trpc === void 0 ? void 0 : trpc.input,
ctx,
req: msg
});
return {
id,
error: router.getErrorShape({
error,
type,
path: trpc === null || trpc === void 0 ? void 0 : trpc.path,
input: trpc === null || trpc === void 0 ? void 0 : trpc.input,
ctx
})
};
}
}
catch (cause) {
// TODO: Assume json parsing error (so shouldn't happen), but we need to handle this better
return {};
}
}
//# sourceMappingURL=index.js.map