UNPKG

fastify-rabbitmq

Version:

A Fastify RabbitMQ Plugin Developed in Pure TypeScript.

86 lines (85 loc) 3.96 kB
import fp from "fastify-plugin"; import { AMQPChannelError, AMQPConnectionError, AMQPError, Connection, ConsumerStatus } from "rabbitmq-client"; import createError from "@fastify/error"; //#region src/errors.ts const errors = { /** Error if there is an invalid option used during registration. */ FASTIFY_RABBIT_MQ_ERR_INVALID_OPTS: createError("FASTIFY_RABBIT_MQ_ERR_INVALID_OPTS", "Invalid options: %s"), /** Error if there is an setup error of the plugin itself. */ FASTIFY_RABBIT_MQ_ERR_SETUP_ERRORS: createError("FASTIFY_RABBIT_MQ_ERR_SETUP_ERRORS", "Setup error: %s"), /** If an invalid usage error was done, this error would pop up. */ FASTIFY_RABBIT_MQ_ERR_USAGE: createError("FASTIFY_RABBIT_MQ_ERR_USAGE", "Usage error: %s") }; //#endregion //#region src/validation.ts /** * Validate Options * * The plugin validates only the *shape* of `connection` -- that it is a * non-empty connection string or a `ConnectionOptions` object. Parsing the URL * and validating the broker options (hosts, TLS, reconnect, etc.) is delegated * to `rabbitmq-client`. The shape guard exists because `new Connection(...)` * accepts garbage (a number, an array, `null`, `{}`) without throwing and then * silently fails to connect at runtime; rejecting it here surfaces a clear * registration-time error instead. * @since 1.0.0 * @param options */ const validateOpts = async (options) => { const { connection } = options; if (connection === void 0) throw new errors.FASTIFY_RABBIT_MQ_ERR_INVALID_OPTS("connection must be defined."); if (typeof connection === "string") { if (connection.length === 0) throw new errors.FASTIFY_RABBIT_MQ_ERR_INVALID_OPTS("connection string must not be empty."); return; } if (!(typeof connection === "object" && connection !== null && !Array.isArray(connection))) throw new errors.FASTIFY_RABBIT_MQ_ERR_INVALID_OPTS("connection must be a connection string or a ConnectionOptions object."); }; //#endregion //#region src/index.ts /** * How we talk with Fastify * @since 1.0.0 * @param fastify * @param options * @param connection */ const decorateFastifyInstance = (fastify, options, connection) => { const { namespace = "" } = options; if (namespace !== void 0 && namespace !== "") fastify.log.debug("[fastify-rabbitmq] Namespace Attempt: %s", namespace); if (namespace !== void 0 && namespace !== "") { if (fastify.rabbitmq === void 0) fastify.decorate("rabbitmq", Object.create(null)); if (fastify.rabbitmq[namespace] !== void 0) throw new errors.FASTIFY_RABBIT_MQ_ERR_SETUP_ERRORS(`Already registered with namespace: ${namespace}`); fastify.log.trace(`[fastify-rabbitmq] Decorate Fastify with Namespace: ${namespace}`); fastify.rabbitmq[namespace] = connection; } else if (fastify.rabbitmq !== void 0) throw new errors.FASTIFY_RABBIT_MQ_ERR_SETUP_ERRORS("Already registered."); if (fastify.rabbitmq === void 0) { fastify.log.trace("[fastify-rabbitmq] Decorate Fastify"); fastify.decorate("rabbitmq", connection); } }; /** * Main Function * @since 1.0.0 * @example * This is the basics on how to use this plugin: * ```js * app.register(fastifyRabbit, { * connection: 'amqp://guest:guest@localhost' * }) * ``` * This will allow you to read from your Fastify "object" and * use this plugin at the "rabbitmq" level. From there you can execute and maintain * the RabbitMQ Connection using the 'rabbitmq-client' package, which is wrapping around * this plugin to execute functions it provides. * * @see [https://cody-greene.github.io/node-rabbitmq-client/latest/index.html](https://cody-greene.github.io/node-rabbitmq-client/latest/index.html) * */ const fastifyRabbit = fp(async (fastify, opts) => { await validateOpts(opts); const { connection } = opts; decorateFastifyInstance(fastify, opts, new Connection(connection)); }); //#endregion export { AMQPChannelError, AMQPConnectionError, AMQPError, ConsumerStatus, decorateFastifyInstance, fastifyRabbit as default }; //# sourceMappingURL=index.mjs.map