@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
JavaScript
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