UNPKG

@shopify/shopify-api

Version:

Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks

88 lines (85 loc) 3.38 kB
import { InvalidDeliveryMethodError } from '../error.mjs'; import { logger } from '../logger/index.mjs'; import { DeliveryMethod } from './types.mjs'; function registry() { return {}; } function topicForStorage(topic) { return topic.toUpperCase().replace(/\/|\./g, '_'); } function addHandlers(config, webhookRegistry) { return function addHandlers(handlersToAdd) { for (const [topic, handlers] of Object.entries(handlersToAdd)) { const topicKey = topicForStorage(topic); if (Array.isArray(handlers)) { for (const handler of handlers) { mergeOrAddHandler(config, webhookRegistry, topicKey, handler); } } else { mergeOrAddHandler(config, webhookRegistry, topicKey, handlers); } } }; } function getTopicsAdded(webhookRegistry) { return function getTopicsAdded() { return Object.keys(webhookRegistry); }; } function getHandlers(webhookRegistry) { return function getHandlers(topic) { return webhookRegistry[topicForStorage(topic)] || []; }; } function handlerIdentifier(config, handler) { const prefix = handler.deliveryMethod; switch (handler.deliveryMethod) { case DeliveryMethod.Http: return `${prefix}_${addHostToCallbackUrl(config, handler.callbackUrl)}`; case DeliveryMethod.EventBridge: return `${prefix}_${handler.arn}`; case DeliveryMethod.PubSub: return `${prefix}_${handler.pubSubProject}:${handler.pubSubTopic}`; default: throw new InvalidDeliveryMethodError(`Unrecognized delivery method '${handler.deliveryMethod}'`); } } function addHostToCallbackUrl(config, callbackUrl) { if (callbackUrl.startsWith('/')) { return `${config.hostScheme}://${config.hostName}${callbackUrl}`; } else { return callbackUrl; } } function mergeOrAddHandler(config, webhookRegistry, topic, handler) { const log = logger(config); handler.includeFields?.sort(); handler.metafieldNamespaces?.sort(); if (!(topic in webhookRegistry)) { webhookRegistry[topic] = [handler]; return; } const identifier = handlerIdentifier(config, handler); for (const index in webhookRegistry[topic]) { if (!Object.prototype.hasOwnProperty.call(webhookRegistry[topic], index)) { continue; } const existingHandler = webhookRegistry[topic][index]; const existingIdentifier = handlerIdentifier(config, existingHandler); if (identifier !== existingIdentifier) { continue; } if (handler.deliveryMethod === DeliveryMethod.Http) { log.info(`Detected multiple handlers for '${topic}', webhooks.process will call them sequentially`); break; } else { throw new InvalidDeliveryMethodError(`Can only add multiple handlers for a topic when deliveryMethod is Http. Please be sure that you used addHandler method once after creating ShopifyApi instance in your app. Invalid handler: ${JSON.stringify(handler)}`); } } webhookRegistry[topic].push(handler); } export { addHandlers, addHostToCallbackUrl, getHandlers, getTopicsAdded, handlerIdentifier, registry, topicForStorage }; //# sourceMappingURL=registry.mjs.map