@shopify/shopify-api
Version:
Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks
107 lines (104 loc) • 4.05 kB
JavaScript
import { logger } from '../logger/index.mjs';
/**
* Applies configured domain transformations to a shop URL.
* Returns transformed domain or original if no transformation matches.
*
* @param shopUrl - The shop URL to transform
* @param config - Configuration object containing domain transformations
* @returns Transformed shop URL or original if no transformation matches
*
* @example
* const config = {
* domainTransformations: [{
* match: /^([a-zA-Z0-9-_]+)\.my\.shop\.dev$/,
* transform: '$1.dev-api.shop.dev'
* }]
* };
* applyDomainTransformations('shop1.my.shop.dev', config);
* // Returns: 'shop1.dev-api.shop.dev'
*/
function applyDomainTransformations(shopUrl, config) {
if (!config.domainTransformations ||
config.domainTransformations.length === 0) {
return shopUrl;
}
for (const transformation of config.domainTransformations) {
const regex = typeof transformation.match === 'string'
? new RegExp(transformation.match)
: transformation.match;
const matches = shopUrl.match(regex);
if (!matches) {
continue;
}
if (typeof transformation.transform === 'function') {
return transformation.transform(matches);
}
let result = transformation.transform;
matches.forEach((match, index) => {
result = result.replace(new RegExp(`\\$${index}`, 'g'), match || '');
});
return result;
}
return shopUrl;
}
/**
* Extracts all domains (source and target) from transformations for validation.
* Uses heuristics to extract domain patterns from regex source.
*
* **Supported regex patterns:**
* - Simple literal domains with escaped dots: `\.example\.com`
* - Patterns with anchors: `^([a-zA-Z0-9-_]+)\.example\.com$`
* - Character classes in subdomains: `^[a-z0-9-]+\.example\.com$`
*
* **Unsupported regex patterns:**
* - Optional groups: `(\.staging)?\.example\.com$` - May not extract correctly
* - Character classes in domain part: `\.api[0-9]\.example\.com$` - May not extract correctly
* - Complex alternations: `\.(dev|staging)\.example\.com$` - May not extract correctly
* - Nested groups in domain part - May not extract correctly
*
* When using unsupported patterns, domain extraction will fail and be logged at debug level.
*
* @param config - Configuration object containing domain transformations
* @returns Array of domain regex patterns
*
* @example
* const config = {
* domainTransformations: [{
* match: /^([a-zA-Z0-9-_]+)\.my\.shop\.dev$/,
* transform: '$1.dev-api.shop.dev'
* }]
* };
* getTransformationDomains(config);
* // Returns: ['my\\.shop\\.dev', 'dev-api\\.shop\\.dev']
*/
function getTransformationDomains(config) {
const domains = [];
const log = logger(config);
if (!config.domainTransformations) {
return domains;
}
const transformations = config.domainTransformations;
for (const transformation of transformations) {
const regex = typeof transformation.match === 'string'
? new RegExp(transformation.match)
: transformation.match;
const domainPattern = regex.source.match(/\\\.([\\.\w-]+)\$?$/);
if (domainPattern) {
domains.push(domainPattern[1]);
}
else {
log.debug(`Failed to extract domain pattern from regex: ${regex.source}. This may indicate an unsupported regex pattern (e.g., optional groups, character classes in domain part, complex alternations).`);
}
if (typeof transformation.transform !== 'string') {
continue;
}
const templateDomainMatch = transformation.transform.match(/\$\d+\.([.\w-]+)$/);
if (templateDomainMatch) {
const escapedDomain = templateDomainMatch[1].replace(/\./g, '\\.');
domains.push(escapedDomain);
}
}
return domains;
}
export { applyDomainTransformations, getTransformationDomains };
//# sourceMappingURL=domain-transformer.mjs.map