import GuJumpgate snapshot from GitHub
This commit is contained in:
+192
@@ -0,0 +1,192 @@
|
||||
(function icloudUtilsModule(root, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = factory();
|
||||
return;
|
||||
}
|
||||
|
||||
root.IcloudUtils = factory();
|
||||
})(typeof self !== 'undefined' ? self : globalThis, function createIcloudUtils() {
|
||||
function normalizeIcloudHost(rawHost) {
|
||||
let host = String(rawHost || '').trim().toLowerCase();
|
||||
if (!host) return '';
|
||||
try {
|
||||
if (host.includes('://')) {
|
||||
host = new URL(host).hostname.toLowerCase();
|
||||
}
|
||||
} catch {}
|
||||
host = host.split('/')[0].split('?')[0].split('#')[0];
|
||||
host = host.replace(/:\d+$/, '').replace(/\.$/, '');
|
||||
if (host === 'icloud.com' || host.endsWith('.icloud.com')) return 'icloud.com';
|
||||
if (host === 'icloud.com.cn' || host.endsWith('.icloud.com.cn')) return 'icloud.com.cn';
|
||||
return '';
|
||||
}
|
||||
|
||||
function getConfiguredIcloudHostPreference(stateOrValue = '') {
|
||||
const preference = typeof stateOrValue === 'object'
|
||||
? String(stateOrValue?.icloudHostPreference || '').trim().toLowerCase()
|
||||
: String(stateOrValue || '').trim().toLowerCase();
|
||||
if (!preference || preference === 'auto') return '';
|
||||
return normalizeIcloudHost(preference);
|
||||
}
|
||||
|
||||
function getIcloudLoginUrlForHost(host) {
|
||||
const normalizedHost = normalizeIcloudHost(host);
|
||||
if (normalizedHost === 'icloud.com') return 'https://www.icloud.com/';
|
||||
if (normalizedHost === 'icloud.com.cn') return 'https://www.icloud.com.cn/';
|
||||
return '';
|
||||
}
|
||||
|
||||
function getIcloudMailUrlForHost(host) {
|
||||
const normalizedHost = normalizeIcloudHost(host);
|
||||
if (normalizedHost === 'icloud.com') return 'https://www.icloud.com/mail/';
|
||||
if (normalizedHost === 'icloud.com.cn') return 'https://www.icloud.com.cn/mail/';
|
||||
return '';
|
||||
}
|
||||
|
||||
function getIcloudSetupUrlForHost(host) {
|
||||
const normalizedHost = normalizeIcloudHost(host);
|
||||
if (normalizedHost === 'icloud.com') return 'https://setup.icloud.com/setup/ws/1';
|
||||
if (normalizedHost === 'icloud.com.cn') return 'https://setup.icloud.com.cn/setup/ws/1';
|
||||
return '';
|
||||
}
|
||||
|
||||
function getIcloudHostHintFromMessage(message) {
|
||||
const lower = String(message || '').toLowerCase();
|
||||
if (lower.includes('setup.icloud.com.cn') || lower.includes('www.icloud.com.cn') || lower.includes('icloud.com.cn')) {
|
||||
return 'icloud.com.cn';
|
||||
}
|
||||
if (lower.includes('setup.icloud.com') || lower.includes('www.icloud.com') || lower.includes('icloud.com')) {
|
||||
return 'icloud.com';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function normalizeBooleanMap(rawValue = {}) {
|
||||
if (!rawValue || typeof rawValue !== 'object' || Array.isArray(rawValue)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Object.entries(rawValue).reduce((result, [key, value]) => {
|
||||
const normalizedKey = String(key || '').trim().toLowerCase();
|
||||
if (!normalizedKey) {
|
||||
return result;
|
||||
}
|
||||
result[normalizedKey] = Boolean(value);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function toNormalizedEmailSet(values = []) {
|
||||
if (values instanceof Set) {
|
||||
return new Set(Array.from(values, (item) => String(item || '').trim().toLowerCase()).filter(Boolean));
|
||||
}
|
||||
if (Array.isArray(values)) {
|
||||
return new Set(values.map((item) => String(item || '').trim().toLowerCase()).filter(Boolean));
|
||||
}
|
||||
if (values && typeof values === 'object') {
|
||||
const normalizedMap = normalizeBooleanMap(values);
|
||||
return new Set(Object.entries(normalizedMap)
|
||||
.filter(([, value]) => value)
|
||||
.map(([email]) => email));
|
||||
}
|
||||
return new Set();
|
||||
}
|
||||
|
||||
function findIcloudAliasArray(node, depth = 0) {
|
||||
if (!node || depth > 4) return null;
|
||||
if (Array.isArray(node)) {
|
||||
return node.some((item) => item && typeof item === 'object') ? node : null;
|
||||
}
|
||||
if (typeof node !== 'object') return null;
|
||||
|
||||
const priorityKeys = ['hmeEmails', 'hmeEmailList', 'hmeList', 'hmes', 'aliases', 'items'];
|
||||
for (const key of priorityKeys) {
|
||||
if (Array.isArray(node[key])) return node[key];
|
||||
}
|
||||
|
||||
for (const value of Object.values(node)) {
|
||||
const nested = findIcloudAliasArray(value, depth + 1);
|
||||
if (nested) return nested;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function normalizeIcloudAliasRecord(raw, options = {}) {
|
||||
const usedEmails = toNormalizedEmailSet(options.usedEmails);
|
||||
const preservedEmails = toNormalizedEmailSet(options.preservedEmails);
|
||||
const anonymousId = String(raw?.anonymousId || raw?.id || '').trim();
|
||||
const email = String(
|
||||
raw?.hme
|
||||
|| raw?.email
|
||||
|| raw?.alias
|
||||
|| raw?.address
|
||||
|| raw?.metaData?.hme
|
||||
|| ''
|
||||
).trim().toLowerCase();
|
||||
|
||||
if (!email || !email.includes('@')) return null;
|
||||
|
||||
const label = String(raw?.label || raw?.metaData?.label || '').trim();
|
||||
const note = String(raw?.note || raw?.metaData?.note || '').trim();
|
||||
const state = String(raw?.state || raw?.status || '').trim().toLowerCase();
|
||||
const createdAt = raw?.createTimestamp
|
||||
|| raw?.createTime
|
||||
|| raw?.createdAt
|
||||
|| raw?.createdDate
|
||||
|| null;
|
||||
|
||||
return {
|
||||
anonymousId,
|
||||
email,
|
||||
label,
|
||||
note,
|
||||
state,
|
||||
active: raw?.active !== false && raw?.isActive !== false && state !== 'inactive' && state !== 'deleted',
|
||||
used: usedEmails.has(email),
|
||||
preserved: preservedEmails.has(email),
|
||||
createdAt,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeIcloudAliasList(response, options = {}) {
|
||||
const aliases = findIcloudAliasArray(response);
|
||||
if (!aliases) return [];
|
||||
|
||||
return aliases
|
||||
.map((alias) => normalizeIcloudAliasRecord(alias, options))
|
||||
.filter(Boolean)
|
||||
.sort((left, right) => {
|
||||
if (left.active !== right.active) return left.active ? -1 : 1;
|
||||
if (left.used !== right.used) return left.used ? 1 : -1;
|
||||
return String(left.email).localeCompare(String(right.email));
|
||||
});
|
||||
}
|
||||
|
||||
function pickReusableIcloudAlias(aliases = []) {
|
||||
return (Array.isArray(aliases) ? aliases : []).find((alias) => alias?.active && !alias?.used) || null;
|
||||
}
|
||||
|
||||
function findIcloudAliasByEmail(aliases = [], email = '') {
|
||||
const normalizedEmail = String(email || '').trim().toLowerCase();
|
||||
if (!normalizedEmail) return null;
|
||||
return (Array.isArray(aliases) ? aliases : [])
|
||||
.find((alias) => String(alias?.email || '').trim().toLowerCase() === normalizedEmail) || null;
|
||||
}
|
||||
|
||||
return {
|
||||
findIcloudAliasArray,
|
||||
findIcloudAliasByEmail,
|
||||
getConfiguredIcloudHostPreference,
|
||||
getIcloudHostHintFromMessage,
|
||||
getIcloudLoginUrlForHost,
|
||||
getIcloudMailUrlForHost,
|
||||
getIcloudSetupUrlForHost,
|
||||
normalizeBooleanMap,
|
||||
normalizeIcloudAliasList,
|
||||
normalizeIcloudAliasRecord,
|
||||
normalizeIcloudHost,
|
||||
pickReusableIcloudAlias,
|
||||
toNormalizedEmailSet,
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user