173 lines
5.2 KiB
JavaScript
173 lines
5.2 KiB
JavaScript
const express = require('express');
|
|
|
|
const router = express.Router();
|
|
|
|
function normalizeText(value) {
|
|
return typeof value === 'string' ? value.trim() : '';
|
|
}
|
|
|
|
function normalizeScopeId(value) {
|
|
if (typeof value === 'string') return value.trim();
|
|
if (typeof value === 'number' && Number.isFinite(value)) return String(value);
|
|
return '';
|
|
}
|
|
|
|
function normalizeDomainName(value) {
|
|
const rawValue = normalizeText(value);
|
|
if (!rawValue) return '';
|
|
|
|
return rawValue
|
|
.replace(/^https?:\/\//i, '')
|
|
.replace(/\/.*$/, '')
|
|
.trim();
|
|
}
|
|
|
|
function normalizeWebsiteUrl(value) {
|
|
const domain = normalizeDomainName(value);
|
|
if (!domain) return '';
|
|
|
|
try {
|
|
return new URL(`https://${domain}`).toString().replace(/\/$/, '');
|
|
} catch {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function normalizeDomainRecord(domain = {}) {
|
|
const name = normalizeDomainName(
|
|
domain?.name
|
|
|| domain?.domain_url
|
|
|| domain?.url
|
|
|| domain?.host
|
|
);
|
|
|
|
if (!name) return null;
|
|
|
|
return {
|
|
name,
|
|
verified: Boolean(domain?.verified),
|
|
is_primary: Boolean(domain?.is_primary),
|
|
is_shortlink: Boolean(domain?.is_shortlink),
|
|
};
|
|
}
|
|
|
|
function rankDomain(domain) {
|
|
if (!domain) return -1;
|
|
|
|
let score = 0;
|
|
if (domain.is_primary) score += 4;
|
|
if (domain.verified) score += 2;
|
|
if (!domain.is_shortlink) score += 1;
|
|
return score;
|
|
}
|
|
|
|
function pickPreferredDomain(domains = []) {
|
|
const normalizedDomains = domains.map(normalizeDomainRecord).filter(Boolean);
|
|
if (!normalizedDomains.length) return { domain: '', domains: [] };
|
|
|
|
normalizedDomains.sort((left, right) => rankDomain(right) - rankDomain(left));
|
|
|
|
return {
|
|
domain: normalizedDomains[0]?.name || '',
|
|
domains: normalizedDomains,
|
|
};
|
|
}
|
|
|
|
function getImageUrl(value) {
|
|
if (!value) return '';
|
|
if (typeof value === 'string') return normalizeText(value);
|
|
return normalizeText(value?.secure_url || value?.url);
|
|
}
|
|
|
|
async function listAllApplications(platformClient) {
|
|
const pageSize = 100;
|
|
let pageNo = 1;
|
|
const items = [];
|
|
|
|
while (pageNo <= 20) {
|
|
const response = await platformClient.configuration.getApplications({ pageNo, pageSize });
|
|
const pageItems = Array.isArray(response?.items) ? response.items : [];
|
|
items.push(...pageItems);
|
|
|
|
if (!response?.page?.has_next || !pageItems.length) break;
|
|
pageNo += 1;
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
async function enrichApplication(platformClient, application) {
|
|
const applicationId = normalizeScopeId(application?._id);
|
|
if (!applicationId) return null;
|
|
|
|
let detail = application;
|
|
let domains = Array.isArray(application?.domains) ? application.domains : [];
|
|
const needsDetails = !normalizeText(application?.description) || !getImageUrl(application?.logo);
|
|
const needsDomains = !domains.length;
|
|
|
|
if (needsDetails || needsDomains) {
|
|
const configurationClient = platformClient.application(applicationId).configuration;
|
|
const [detailResult, domainsResult] = await Promise.allSettled([
|
|
needsDetails ? configurationClient.getApplicationById() : Promise.resolve(null),
|
|
needsDomains ? configurationClient.getDomains() : Promise.resolve(null),
|
|
]);
|
|
|
|
if (detailResult.status === 'fulfilled' && detailResult.value) {
|
|
detail = { ...application, ...detailResult.value };
|
|
}
|
|
|
|
if (domainsResult.status === 'fulfilled' && Array.isArray(domainsResult.value?.domains)) {
|
|
domains = domainsResult.value.domains;
|
|
}
|
|
}
|
|
|
|
const { domain, domains: normalizedDomains } = pickPreferredDomain(
|
|
domains.length ? domains : [detail?.domain]
|
|
);
|
|
|
|
return {
|
|
_id: applicationId,
|
|
id: applicationId,
|
|
applicationId,
|
|
salesChannelId: applicationId,
|
|
name: normalizeText(detail?.name || application?.name) || `Sales Channel ${applicationId}`,
|
|
description: normalizeText(detail?.description || application?.description),
|
|
domain,
|
|
domains: normalizedDomains,
|
|
websiteUrl: normalizeWebsiteUrl(domain),
|
|
is_active: detail?.is_active !== false && application?.is_active !== false,
|
|
logoUrl: getImageUrl(detail?.logo || application?.logo || detail?.mobile_logo || application?.mobile_logo),
|
|
bannerUrl: getImageUrl(detail?.banner || application?.banner),
|
|
appType: normalizeText(detail?.app_type || application?.app_type),
|
|
channelType: normalizeText(detail?.channel_type || application?.channel_type),
|
|
createdAt: normalizeText(detail?.created_at || application?.created_at),
|
|
updatedAt: normalizeText(detail?.modified_at || application?.modified_at),
|
|
};
|
|
}
|
|
|
|
router.get('/sales-channels', async (req, res) => {
|
|
try {
|
|
if (!req.platformClient) {
|
|
return res.status(503).json({ error: 'Platform client is unavailable for sales-channel fetch' });
|
|
}
|
|
console.log("req.platformClient", req.platformClient);
|
|
|
|
const applications = await listAllApplications(req.platformClient);
|
|
const channels = [];
|
|
|
|
for (const application of applications) {
|
|
const enrichedChannel = await enrichApplication(req.platformClient, application);
|
|
if (enrichedChannel?.is_active) {
|
|
channels.push(enrichedChannel);
|
|
}
|
|
}
|
|
|
|
res.json({ salesChannels: channels });
|
|
} catch (error) {
|
|
console.error('Sales-channel fetch error:', error.message);
|
|
res.status(502).json({ error: error.message || 'Failed to fetch sales channels' });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|