diff --git a/background.js b/background.js
index faf1d9b..a411008 100644
--- a/background.js
+++ b/background.js
@@ -1453,6 +1453,7 @@ const PERSISTED_SETTING_DEFAULTS = {
madaoRoutingPlanId: '',
madaoProviderId: '',
madaoCountry: '',
+ madaoOperator: '',
madaoAutoPickCountry: true,
madaoReusePhone: true,
madaoMinPrice: '',
@@ -2245,6 +2246,13 @@ function normalizeMaDaoPrice(value = '') {
return normalizeHeroSmsMaxPrice(value);
}
+function normalizeMaDaoOperator(value = '') {
+ return String(value || '')
+ .trim()
+ .toLowerCase()
+ .replace(/[^a-z0-9_-]+/g, '');
+}
+
function normalizePhonePreferredActivation(value) {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return null;
@@ -3595,6 +3603,8 @@ function normalizePersistentSettingValue(key, value) {
return normalizeMaDaoProviderId(value);
case 'madaoCountry':
return normalizeMaDaoCountry(value);
+ case 'madaoOperator':
+ return normalizeMaDaoOperator(value);
case 'madaoAutoPickCountry':
case 'madaoReusePhone':
return Boolean(value);
diff --git a/phone-sms/providers/madao.js b/phone-sms/providers/madao.js
index b4185c2..c3a0320 100644
--- a/phone-sms/providers/madao.js
+++ b/phone-sms/providers/madao.js
@@ -255,6 +255,7 @@
service: normalizeText(options?.service || state?.madaoServiceName, DEFAULT_SERVICE),
};
const country = normalizeCountry(options?.country || state?.madaoCountry);
+ const operator = normalizeProviderId(options?.operator || state?.madaoOperator);
const minPrice = normalizePrice(options?.minPrice ?? state?.madaoMinPrice);
const maxPrice = normalizePrice(options?.maxPrice ?? state?.madaoMaxPrice);
@@ -268,6 +269,9 @@
if (country) {
request.country = country;
}
+ if (operator) {
+ request.metadata = { operator };
+ }
if (minPrice !== null) {
request.min_price = minPrice;
}
diff --git a/sidepanel/sidepanel.html b/sidepanel/sidepanel.html
index d3e2af7..1374717 100644
--- a/sidepanel/sidepanel.html
+++ b/sidepanel/sidepanel.html
@@ -1565,6 +1565,33 @@
+
MaDao 价格
diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js
index fcd6f84..a8e38ea 100644
--- a/sidepanel/sidepanel.js
+++ b/sidepanel/sidepanel.js
@@ -460,6 +460,7 @@ const rowMaDaoMode = document.getElementById('row-madao-mode');
const rowMaDaoRoutingPlanId = document.getElementById('row-madao-routing-plan-id');
const rowMaDaoProviderId = document.getElementById('row-madao-provider-id');
const rowMaDaoCountry = document.getElementById('row-madao-country');
+const rowMaDaoOperator = document.getElementById('row-madao-operator');
const rowMaDaoAutoPickCountry = document.getElementById('row-madao-auto-pick-country');
const rowMaDaoReusePhone = document.getElementById('row-madao-reuse-phone');
const rowMaDaoPriceRange = document.getElementById('row-madao-price-range');
@@ -496,8 +497,12 @@ const btnToggleMaDaoHttpSecret = document.getElementById('btn-toggle-madao-http-
const selectMaDaoMode = document.getElementById('select-madao-mode');
const selectMaDaoRoutingPlanId = document.getElementById('select-madao-routing-plan-id');
const btnMaDaoRefreshRoutingPlans = document.getElementById('btn-madao-refresh-routing-plans');
-const inputMaDaoProviderId = document.getElementById('input-madao-provider-id');
-const inputMaDaoCountry = document.getElementById('input-madao-country');
+const selectMaDaoProviderId = document.getElementById('select-madao-provider-id');
+const btnMaDaoRefreshProviders = document.getElementById('btn-madao-refresh-providers');
+const selectMaDaoCountry = document.getElementById('select-madao-country');
+const btnMaDaoRefreshCountries = document.getElementById('btn-madao-refresh-countries');
+const selectMaDaoOperator = document.getElementById('select-madao-operator');
+const btnMaDaoRefreshOperators = document.getElementById('btn-madao-refresh-operators');
const inputMaDaoAutoPickCountry = document.getElementById('input-madao-auto-pick-country');
const inputMaDaoReusePhone = document.getElementById('input-madao-reuse-phone');
const inputMaDaoMinPrice = document.getElementById('input-madao-min-price');
@@ -691,6 +696,9 @@ const MADAO_MODE_ROUTING_PLAN = 'routing_plan';
const MADAO_MODE_DIRECT = 'direct';
const DEFAULT_MADAO_MODE = MADAO_MODE_ROUTING_PLAN;
let maDaoRoutingPlanOptions = [];
+let maDaoProviderOptions = [];
+let maDaoCountryOptions = [];
+let maDaoOperatorOptions = [];
const PHONE_SMS_PROVIDER_UI_DESCRIPTORS = Object.freeze({
[PHONE_SMS_PROVIDER_HERO]: Object.freeze({
rowKeys: Object.freeze([
@@ -734,6 +742,9 @@ const PHONE_SMS_PROVIDER_UI_DESCRIPTORS = Object.freeze({
'rowMaDaoRoutingPlanId',
]),
directRowKeys: Object.freeze([
+ 'rowMaDaoProviderId',
+ 'rowMaDaoCountry',
+ 'rowMaDaoOperator',
'rowMaDaoPriceRange',
]),
}),
@@ -763,6 +774,7 @@ function getPhoneSmsProviderUiRowMap() {
rowMaDaoRoutingPlanId,
rowMaDaoProviderId,
rowMaDaoCountry,
+ rowMaDaoOperator,
rowMaDaoAutoPickCountry,
rowMaDaoReusePhone,
rowMaDaoPriceRange,
@@ -4453,6 +4465,9 @@ function collectSettingsPayload() {
const normalizeMaDaoProviderIdSafe = typeof normalizeMaDaoProviderIdValue === 'function'
? normalizeMaDaoProviderIdValue
: ((value = '') => String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''));
+ const normalizeMaDaoOperatorSafe = typeof normalizeMaDaoOperatorValue === 'function'
+ ? normalizeMaDaoOperatorValue
+ : ((value = '') => String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''));
const normalizeMaDaoCountrySafe = typeof normalizeMaDaoCountry === 'function'
? normalizeMaDaoCountry
: ((value = '') => {
@@ -4639,12 +4654,16 @@ function collectSettingsPayload() {
const maDaoRoutingPlanIdValue = typeof selectMaDaoRoutingPlanId !== 'undefined' && selectMaDaoRoutingPlanId
? normalizeMaDaoIdentifierSafe(selectMaDaoRoutingPlanId.value || '')
: normalizeMaDaoIdentifierSafe(latestState?.madaoRoutingPlanId || '');
- const maDaoProviderIdValue = typeof inputMaDaoProviderId !== 'undefined' && inputMaDaoProviderId
- ? normalizeMaDaoProviderIdSafe(inputMaDaoProviderId.value || '')
+ const shouldReadMaDaoDirectControls = maDaoModeValue === MADAO_MODE_DIRECT;
+ const maDaoProviderIdValue = shouldReadMaDaoDirectControls && typeof selectMaDaoProviderId !== 'undefined' && selectMaDaoProviderId
+ ? normalizeMaDaoProviderIdSafe(selectMaDaoProviderId.value || '')
: normalizeMaDaoProviderIdSafe(latestState?.madaoProviderId || '');
- const maDaoCountryValue = typeof inputMaDaoCountry !== 'undefined' && inputMaDaoCountry
- ? normalizeMaDaoCountrySafe(inputMaDaoCountry.value || '')
+ const maDaoCountryValue = shouldReadMaDaoDirectControls && typeof selectMaDaoCountry !== 'undefined' && selectMaDaoCountry
+ ? normalizeMaDaoCountrySafe(selectMaDaoCountry.value || '')
: normalizeMaDaoCountrySafe(latestState?.madaoCountry || '');
+ const maDaoOperatorValue = shouldReadMaDaoDirectControls && typeof selectMaDaoOperator !== 'undefined' && selectMaDaoOperator
+ ? normalizeMaDaoOperatorSafe(selectMaDaoOperator.value || '')
+ : normalizeMaDaoOperatorSafe(latestState?.madaoOperator || '');
const maDaoAutoPickCountryValue = typeof inputMaDaoAutoPickCountry !== 'undefined' && inputMaDaoAutoPickCountry
? Boolean(inputMaDaoAutoPickCountry.checked)
: (latestState?.madaoAutoPickCountry !== undefined ? Boolean(latestState.madaoAutoPickCountry) : true);
@@ -5271,6 +5290,7 @@ function collectSettingsPayload() {
madaoRoutingPlanId: maDaoRoutingPlanIdValue,
madaoProviderId: maDaoProviderIdValue,
madaoCountry: maDaoCountryValue,
+ madaoOperator: maDaoOperatorValue,
madaoAutoPickCountry: maDaoAutoPickCountryValue,
madaoReusePhone: maDaoReusePhoneValue,
madaoMinPrice: maDaoMinPriceValue,
@@ -5681,6 +5701,10 @@ function normalizeMaDaoProviderIdValue(value = '') {
return String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, '');
}
+function normalizeMaDaoOperatorValue(value = '') {
+ return String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, '');
+}
+
function normalizeMaDaoCountry(value = '') {
const trimmed = String(value || '').trim();
if (!trimmed) {
@@ -5811,6 +5835,85 @@ function setMaDaoRoutingPlanSelectOptions(selectedValue = latestState?.madaoRout
});
}
+function normalizeMaDaoOptionListItems(items = [], selectedValue = '', normalizeValue = normalizeMaDaoIdentifierValue, selectedHint = '已保存的选项') {
+ const normalizedSelected = normalizeValue(selectedValue);
+ const seen = new Set();
+ const normalizedItems = [];
+ (Array.isArray(items) ? items : []).forEach((item) => {
+ const value = normalizeValue(
+ item?.value
+ || item?.id
+ || item?.provider
+ || item?.provider_value
+ || item?.providerValue
+ || item?.country
+ || item?.operator
+ || ''
+ );
+ if (!value || seen.has(value)) {
+ return;
+ }
+ seen.add(value);
+ normalizedItems.push({
+ value,
+ label: String(item?.label || item?.name || item?.display_name || item?.displayName || value).trim() || value,
+ hint: String(item?.hint || item?.description || item?.provider_value || item?.providerValue || '').trim(),
+ enabled: item?.enabled !== false,
+ });
+ });
+ if (normalizedSelected && !seen.has(normalizedSelected)) {
+ normalizedItems.unshift({
+ value: normalizedSelected,
+ label: normalizedSelected,
+ hint: selectedHint,
+ enabled: true,
+ });
+ }
+ return normalizedItems.filter((item) => item.enabled !== false);
+}
+
+function setMaDaoProviderSelectOptions(selectedValue = latestState?.madaoProviderId || '') {
+ const normalizedSelected = normalizeMaDaoProviderIdValue(selectedValue);
+ const options = normalizeMaDaoOptionListItems(
+ maDaoProviderOptions,
+ normalizedSelected,
+ normalizeMaDaoProviderIdValue,
+ '已保存的服务商'
+ );
+ setSelectOptions(selectMaDaoProviderId, options, {
+ placeholder: '请先刷新服务商',
+ value: normalizedSelected,
+ });
+}
+
+function setMaDaoCountrySelectOptions(selectedValue = latestState?.madaoCountry || '') {
+ const normalizedSelected = normalizeMaDaoCountry(selectedValue);
+ const options = normalizeMaDaoOptionListItems(
+ maDaoCountryOptions,
+ normalizedSelected,
+ normalizeMaDaoCountry,
+ '已保存的国家'
+ );
+ setSelectOptions(selectMaDaoCountry, options, {
+ placeholder: '请先选择服务商',
+ value: normalizedSelected,
+ });
+}
+
+function setMaDaoOperatorSelectOptions(selectedValue = latestState?.madaoOperator || '') {
+ const normalizedSelected = normalizeMaDaoOperatorValue(selectedValue);
+ const options = normalizeMaDaoOptionListItems(
+ maDaoOperatorOptions,
+ normalizedSelected,
+ normalizeMaDaoOperatorValue,
+ '已保存的线路'
+ );
+ setSelectOptions(selectMaDaoOperator, options, {
+ placeholder: '任意线路',
+ value: normalizedSelected,
+ });
+}
+
function buildMaDaoRequestUrl(path = '', baseUrl = '') {
const normalizedBaseUrl = normalizeMaDaoBaseUrlValue(baseUrl || latestState?.madaoBaseUrl || DEFAULT_MADAO_BASE_URL);
return new URL(String(path || '').replace(/^\/+/, ''), `${normalizedBaseUrl.replace(/\/+$/, '')}/`).toString();
@@ -5876,6 +5979,57 @@ function getMaDaoRoutingPlansFromPayload(payload = {}) {
return [];
}
+function getMaDaoProvidersFromPayload(payload = {}) {
+ if (Array.isArray(payload)) {
+ return payload;
+ }
+ if (Array.isArray(payload?.providers)) {
+ return payload.providers;
+ }
+ if (Array.isArray(payload?.data?.providers)) {
+ return payload.data.providers;
+ }
+ if (Array.isArray(payload?.data)) {
+ return payload.data;
+ }
+ if (Array.isArray(payload?.items)) {
+ return payload.items;
+ }
+ return [];
+}
+
+function getMaDaoOptionItemsFromPayload(payload = {}) {
+ if (Array.isArray(payload)) {
+ return payload;
+ }
+ if (Array.isArray(payload?.items)) {
+ return payload.items;
+ }
+ if (Array.isArray(payload?.data?.items)) {
+ return payload.data.items;
+ }
+ if (Array.isArray(payload?.data)) {
+ return payload.data;
+ }
+ return [];
+}
+
+function getSelectedMaDaoProviderId() {
+ return normalizeMaDaoProviderIdValue(
+ typeof selectMaDaoProviderId !== 'undefined' && selectMaDaoProviderId
+ ? selectMaDaoProviderId.value
+ : latestState?.madaoProviderId
+ );
+}
+
+function getSelectedMaDaoCountry() {
+ return normalizeMaDaoCountry(
+ typeof selectMaDaoCountry !== 'undefined' && selectMaDaoCountry
+ ? selectMaDaoCountry.value
+ : latestState?.madaoCountry
+ );
+}
+
async function loadMaDaoRoutingPlans(options = {}) {
const selectedValue = normalizeMaDaoRoutingPlanIdValue(
typeof selectMaDaoRoutingPlanId !== 'undefined' && selectMaDaoRoutingPlanId
@@ -5905,6 +6059,93 @@ async function loadMaDaoRoutingPlans(options = {}) {
return maDaoRoutingPlanOptions;
}
+async function loadMaDaoProviders(options = {}) {
+ const selectedValue = normalizeMaDaoProviderIdValue(
+ (typeof selectMaDaoProviderId !== 'undefined' && selectMaDaoProviderId
+ ? selectMaDaoProviderId.value
+ : '')
+ || latestState?.madaoProviderId
+ );
+ const payload = await fetchMaDaoJson('/api/providers');
+ maDaoProviderOptions = getMaDaoProvidersFromPayload(payload)
+ .filter((provider) => provider?.enabled !== false)
+ .map((provider) => ({
+ value: normalizeMaDaoProviderIdValue(provider?.id || provider?.value || provider?.provider || ''),
+ label: String(provider?.name || provider?.label || provider?.id || provider?.value || '').trim(),
+ hint: String(provider?.description || provider?.hint || provider?.protocol_label || provider?.protocolLabel || provider?.kind || '').trim(),
+ enabled: provider?.enabled !== false,
+ }))
+ .filter((provider) => provider.value);
+ setMaDaoProviderSelectOptions(selectedValue);
+ if (!options.skipChildren && getSelectedMaDaoProviderId()) {
+ await loadMaDaoCountries({ silent: true }).catch(() => {
+ setMaDaoCountrySelectOptions(latestState?.madaoCountry || '');
+ setMaDaoOperatorSelectOptions(latestState?.madaoOperator || '');
+ });
+ }
+ updateHeroSmsPlatformDisplay();
+ if (!options.silent && typeof showToast === 'function') {
+ showToast('已刷新 MaDao 服务商。', 'info', 1600);
+ }
+ return maDaoProviderOptions;
+}
+
+async function loadMaDaoCountries(options = {}) {
+ const providerId = getSelectedMaDaoProviderId();
+ const selectedValue = normalizeMaDaoCountry(
+ (typeof selectMaDaoCountry !== 'undefined' && selectMaDaoCountry
+ ? selectMaDaoCountry.value
+ : '')
+ || latestState?.madaoCountry
+ );
+ if (!providerId) {
+ maDaoCountryOptions = [];
+ maDaoOperatorOptions = [];
+ setMaDaoCountrySelectOptions(selectedValue);
+ setMaDaoOperatorSelectOptions(latestState?.madaoOperator || '');
+ return maDaoCountryOptions;
+ }
+ const payload = await fetchMaDaoJson(`/api/providers/${encodeURIComponent(providerId)}/countries`);
+ maDaoCountryOptions = getMaDaoOptionItemsFromPayload(payload);
+ setMaDaoCountrySelectOptions(selectedValue);
+ if (!options.skipChildren) {
+ await loadMaDaoOperators({ silent: true }).catch(() => {
+ setMaDaoOperatorSelectOptions(latestState?.madaoOperator || '');
+ });
+ }
+ updateHeroSmsPlatformDisplay();
+ if (!options.silent && typeof showToast === 'function') {
+ showToast('已刷新 MaDao 国家。', 'info', 1600);
+ }
+ return maDaoCountryOptions;
+}
+
+async function loadMaDaoOperators(options = {}) {
+ const providerId = getSelectedMaDaoProviderId();
+ const country = getSelectedMaDaoCountry();
+ const selectedValue = normalizeMaDaoOperatorValue(
+ typeof selectMaDaoOperator !== 'undefined' && selectMaDaoOperator
+ ? selectMaDaoOperator.value
+ : latestState?.madaoOperator
+ );
+ if (!providerId) {
+ maDaoOperatorOptions = [];
+ setMaDaoOperatorSelectOptions(selectedValue);
+ return maDaoOperatorOptions;
+ }
+ const payload = await fetchMaDaoJson(`/api/providers/${encodeURIComponent(providerId)}/operators`, {
+ method: 'POST',
+ body: country ? { country } : {},
+ });
+ maDaoOperatorOptions = getMaDaoOptionItemsFromPayload(payload);
+ setMaDaoOperatorSelectOptions(selectedValue);
+ updateHeroSmsPlatformDisplay();
+ if (!options.silent && typeof showToast === 'function') {
+ showToast('已刷新 MaDao 线路。', 'info', 1600);
+ }
+ return maDaoOperatorOptions;
+}
+
function getSelectedMaDaoRoutingPlanLabel(value = '') {
const selectedValue = normalizeMaDaoRoutingPlanIdValue(
value
@@ -12035,6 +12276,11 @@ function applySettingsState(state) {
loadMaDaoRoutingPlans({ silent: true }).catch(() => {
setMaDaoRoutingPlanSelectOptions(state?.madaoRoutingPlanId || '');
});
+ loadMaDaoProviders({ silent: true }).catch(() => {
+ setMaDaoProviderSelectOptions(state?.madaoProviderId || '');
+ setMaDaoCountrySelectOptions(state?.madaoCountry || '');
+ setMaDaoOperatorSelectOptions(state?.madaoOperator || '');
+ });
} else {
loadHeroSmsCountries({ silent: true }).catch(() => { });
}
@@ -12077,11 +12323,14 @@ function applySettingsState(state) {
if (typeof selectMaDaoRoutingPlanId !== 'undefined' && selectMaDaoRoutingPlanId) {
setMaDaoRoutingPlanSelectOptions(state?.madaoRoutingPlanId || '');
}
- if (typeof inputMaDaoProviderId !== 'undefined' && inputMaDaoProviderId) {
- inputMaDaoProviderId.value = normalizeMaDaoProviderIdValue(state?.madaoProviderId || '');
+ if (typeof selectMaDaoProviderId !== 'undefined' && selectMaDaoProviderId) {
+ setMaDaoProviderSelectOptions(state?.madaoProviderId || '');
}
- if (typeof inputMaDaoCountry !== 'undefined' && inputMaDaoCountry) {
- inputMaDaoCountry.value = normalizeMaDaoCountry(state?.madaoCountry || '');
+ if (typeof selectMaDaoCountry !== 'undefined' && selectMaDaoCountry) {
+ setMaDaoCountrySelectOptions(state?.madaoCountry || '');
+ }
+ if (typeof selectMaDaoOperator !== 'undefined' && selectMaDaoOperator) {
+ setMaDaoOperatorSelectOptions(state?.madaoOperator || '');
}
if (typeof inputMaDaoAutoPickCountry !== 'undefined' && inputMaDaoAutoPickCountry) {
inputMaDaoAutoPickCountry.checked = state?.madaoAutoPickCountry !== undefined
@@ -17378,17 +17627,26 @@ function buildPhoneSmsProviderStatePatch(provider = getSelectedPhoneSmsProvider(
};
}
if (normalizedProvider === PHONE_SMS_PROVIDER_MADAO) {
+ const maDaoMode = normalizeMaDaoModeValue(selectMaDaoMode?.value || latestState?.madaoMode);
+ const shouldReadMaDaoDirectControls = maDaoMode === MADAO_MODE_DIRECT;
return {
madaoBaseUrl: normalizeMaDaoBaseUrlValue(inputMaDaoBaseUrl?.value || latestState?.madaoBaseUrl),
madaoHttpSecret: String(inputMaDaoHttpSecret?.value || ''),
- madaoMode: normalizeMaDaoModeValue(selectMaDaoMode?.value || latestState?.madaoMode),
+ madaoMode: maDaoMode,
madaoRoutingPlanId: normalizeMaDaoRoutingPlanIdValue(
typeof selectMaDaoRoutingPlanId !== 'undefined' && selectMaDaoRoutingPlanId
? selectMaDaoRoutingPlanId.value
: latestState?.madaoRoutingPlanId
),
- madaoProviderId: normalizeMaDaoProviderIdValue(inputMaDaoProviderId?.value || ''),
- madaoCountry: normalizeMaDaoCountry(inputMaDaoCountry?.value || ''),
+ madaoProviderId: shouldReadMaDaoDirectControls
+ ? normalizeMaDaoProviderIdValue(selectMaDaoProviderId?.value || '')
+ : normalizeMaDaoProviderIdValue(latestState?.madaoProviderId || ''),
+ madaoCountry: shouldReadMaDaoDirectControls
+ ? normalizeMaDaoCountry(selectMaDaoCountry?.value || '')
+ : normalizeMaDaoCountry(latestState?.madaoCountry || ''),
+ madaoOperator: shouldReadMaDaoDirectControls
+ ? normalizeMaDaoOperatorValue(selectMaDaoOperator?.value || '')
+ : normalizeMaDaoOperatorValue(latestState?.madaoOperator || ''),
madaoAutoPickCountry: Boolean(inputMaDaoAutoPickCountry?.checked),
madaoReusePhone: Boolean(inputMaDaoReusePhone?.checked),
madaoMinPrice: normalizeMaDaoPriceValue(inputMaDaoMinPrice?.value || ''),
@@ -17436,11 +17694,14 @@ function applyPhoneSmsProviderFieldsToInputs(provider = getSelectedPhoneSmsProvi
if (typeof selectMaDaoRoutingPlanId !== 'undefined' && selectMaDaoRoutingPlanId) {
setMaDaoRoutingPlanSelectOptions(state?.madaoRoutingPlanId || '');
}
- if (typeof inputMaDaoProviderId !== 'undefined' && inputMaDaoProviderId) {
- inputMaDaoProviderId.value = normalizeMaDaoProviderIdValue(state?.madaoProviderId || '');
+ if (typeof selectMaDaoProviderId !== 'undefined' && selectMaDaoProviderId) {
+ setMaDaoProviderSelectOptions(state?.madaoProviderId || '');
}
- if (typeof inputMaDaoCountry !== 'undefined' && inputMaDaoCountry) {
- inputMaDaoCountry.value = normalizeMaDaoCountry(state?.madaoCountry || '');
+ if (typeof selectMaDaoCountry !== 'undefined' && selectMaDaoCountry) {
+ setMaDaoCountrySelectOptions(state?.madaoCountry || '');
+ }
+ if (typeof selectMaDaoOperator !== 'undefined' && selectMaDaoOperator) {
+ setMaDaoOperatorSelectOptions(state?.madaoOperator || '');
}
if (typeof inputMaDaoAutoPickCountry !== 'undefined' && inputMaDaoAutoPickCountry) {
inputMaDaoAutoPickCountry.checked = state?.madaoAutoPickCountry !== undefined
@@ -17523,6 +17784,11 @@ async function switchPhoneSmsProvider(nextProvider) {
await loadMaDaoRoutingPlans({ silent: true }).catch(() => {
setMaDaoRoutingPlanSelectOptions(latestState?.madaoRoutingPlanId || '');
});
+ await loadMaDaoProviders({ silent: true }).catch(() => {
+ setMaDaoProviderSelectOptions(latestState?.madaoProviderId || '');
+ setMaDaoCountrySelectOptions(latestState?.madaoCountry || '');
+ setMaDaoOperatorSelectOptions(latestState?.madaoOperator || '');
+ });
} else if (normalizedNextProvider === PHONE_SMS_PROVIDER_HERO_SMS) {
await loadHeroSmsCountries({ silent: true });
const restoredPrimary = {
@@ -17733,6 +17999,12 @@ selectMaDaoMode?.addEventListener('change', () => {
loadMaDaoRoutingPlans({ silent: true }).catch(() => {
setMaDaoRoutingPlanSelectOptions(latestState?.madaoRoutingPlanId || '');
});
+ } else {
+ loadMaDaoProviders({ silent: true }).catch(() => {
+ setMaDaoProviderSelectOptions(latestState?.madaoProviderId || '');
+ setMaDaoCountrySelectOptions(latestState?.madaoCountry || '');
+ setMaDaoOperatorSelectOptions(latestState?.madaoOperator || '');
+ });
}
markSettingsDirty(true);
saveSettings({ silent: true }).catch(() => { });
@@ -17750,23 +18022,60 @@ btnMaDaoRefreshRoutingPlans?.addEventListener('click', () => {
});
});
-inputMaDaoProviderId?.addEventListener('input', () => {
+selectMaDaoProviderId?.addEventListener('change', () => {
+ maDaoCountryOptions = [];
+ maDaoOperatorOptions = [];
+ setMaDaoCountrySelectOptions('');
+ setMaDaoOperatorSelectOptions('');
+ syncLatestState({
+ madaoProviderId: normalizeMaDaoProviderIdValue(selectMaDaoProviderId.value),
+ madaoCountry: '',
+ madaoOperator: '',
+ });
markSettingsDirty(true);
- scheduleSettingsAutoSave();
+ saveSettings({ silent: true }).catch(() => { });
+ loadMaDaoCountries({ silent: true }).catch((error) => {
+ showToast(`刷新 MaDao 国家失败:${error?.message || error}`, 'warn', 2200);
+ });
});
-inputMaDaoProviderId?.addEventListener('blur', () => {
- inputMaDaoProviderId.value = normalizeMaDaoProviderIdValue(inputMaDaoProviderId.value);
+
+btnMaDaoRefreshProviders?.addEventListener('click', () => {
+ loadMaDaoProviders().catch((error) => {
+ showToast(`刷新 MaDao 服务商失败:${error?.message || error}`, 'warn', 2200);
+ });
+});
+
+selectMaDaoCountry?.addEventListener('change', () => {
+ maDaoOperatorOptions = [];
+ setMaDaoOperatorSelectOptions('');
+ updateHeroSmsPlatformDisplay();
+ syncLatestState({
+ madaoCountry: normalizeMaDaoCountry(selectMaDaoCountry.value),
+ madaoOperator: '',
+ });
+ markSettingsDirty(true);
+ saveSettings({ silent: true }).catch(() => { });
+ loadMaDaoOperators({ silent: true }).catch((error) => {
+ showToast(`刷新 MaDao 线路失败:${error?.message || error}`, 'warn', 2200);
+ });
+});
+
+btnMaDaoRefreshCountries?.addEventListener('click', () => {
+ loadMaDaoCountries().catch((error) => {
+ showToast(`刷新 MaDao 国家失败:${error?.message || error}`, 'warn', 2200);
+ });
+});
+
+selectMaDaoOperator?.addEventListener('change', () => {
+ updateHeroSmsPlatformDisplay();
+ markSettingsDirty(true);
saveSettings({ silent: true }).catch(() => { });
});
-inputMaDaoCountry?.addEventListener('input', () => {
- markSettingsDirty(true);
- scheduleSettingsAutoSave();
-});
-inputMaDaoCountry?.addEventListener('blur', () => {
- inputMaDaoCountry.value = normalizeMaDaoCountry(inputMaDaoCountry.value);
- updateHeroSmsPlatformDisplay();
- saveSettings({ silent: true }).catch(() => { });
+btnMaDaoRefreshOperators?.addEventListener('click', () => {
+ loadMaDaoOperators().catch((error) => {
+ showToast(`刷新 MaDao 线路失败:${error?.message || error}`, 'warn', 2200);
+ });
});
inputMaDaoAutoPickCountry?.addEventListener('change', () => {
@@ -18835,11 +19144,14 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
if (message.payload.madaoRoutingPlanId !== undefined && selectMaDaoRoutingPlanId) {
setMaDaoRoutingPlanSelectOptions(message.payload.madaoRoutingPlanId);
}
- if (message.payload.madaoProviderId !== undefined && inputMaDaoProviderId) {
- inputMaDaoProviderId.value = normalizeMaDaoProviderIdValue(message.payload.madaoProviderId);
+ if (message.payload.madaoProviderId !== undefined && selectMaDaoProviderId) {
+ setMaDaoProviderSelectOptions(message.payload.madaoProviderId);
}
- if (message.payload.madaoCountry !== undefined && inputMaDaoCountry) {
- inputMaDaoCountry.value = normalizeMaDaoCountry(message.payload.madaoCountry);
+ if (message.payload.madaoCountry !== undefined && selectMaDaoCountry) {
+ setMaDaoCountrySelectOptions(message.payload.madaoCountry);
+ }
+ if (message.payload.madaoOperator !== undefined && selectMaDaoOperator) {
+ setMaDaoOperatorSelectOptions(message.payload.madaoOperator);
}
if (message.payload.madaoAutoPickCountry !== undefined && inputMaDaoAutoPickCountry) {
inputMaDaoAutoPickCountry.checked = Boolean(message.payload.madaoAutoPickCountry);
diff --git a/tests/background-account-history-settings.test.js b/tests/background-account-history-settings.test.js
index f4aaf35..9fcdbd8 100644
--- a/tests/background-account-history-settings.test.js
+++ b/tests/background-account-history-settings.test.js
@@ -71,6 +71,7 @@ test('background account history settings are normalized independently from hotm
extractFunction('normalizeMaDaoIdentifier'),
extractFunction('normalizeMaDaoProviderId'),
extractFunction('normalizeMaDaoCountry'),
+ extractFunction('normalizeMaDaoOperator'),
extractFunction('normalizeMaDaoPrice'),
extractFunction('normalizePhonePreferredActivation'),
extractFunction('normalizePhoneVerificationReplacementLimit'),
@@ -382,6 +383,7 @@ return {
assert.equal(api.normalizePersistentSettingValue('madaoProviderId', ' Upstream A! '), 'upstreama');
assert.equal(api.normalizePersistentSettingValue('madaoCountry', ' gb '), 'GB');
assert.equal(api.normalizePersistentSettingValue('madaoCountry', 'ANY'), 'any');
+ assert.equal(api.normalizePersistentSettingValue('madaoOperator', ' Operator A! '), 'operatora');
assert.equal(api.normalizePersistentSettingValue('madaoAutoPickCountry', 1), true);
assert.equal(api.normalizePersistentSettingValue('madaoReusePhone', 0), false);
assert.equal(api.normalizePersistentSettingValue('madaoMinPrice', '0.123456'), '0.1235');
diff --git a/tests/background-settings-import-mode-validation.test.js b/tests/background-settings-import-mode-validation.test.js
index a8eef31..9276c9e 100644
--- a/tests/background-settings-import-mode-validation.test.js
+++ b/tests/background-settings-import-mode-validation.test.js
@@ -419,6 +419,7 @@ return {
madaoRoutingPlanId: 'rp-openai',
madaoProviderId: 'upstream-a',
madaoCountry: 'GB',
+ madaoOperator: 'operator-a',
madaoAutoPickCountry: false,
madaoReusePhone: true,
madaoMinPrice: '0.12',
@@ -452,6 +453,7 @@ return {
assert.equal(api.getPayloadInput().madaoRoutingPlanId, 'rp-openai');
assert.equal(api.getPayloadInput().madaoProviderId, 'upstream-a');
assert.equal(api.getPayloadInput().madaoCountry, 'GB');
+ assert.equal(api.getPayloadInput().madaoOperator, 'operator-a');
assert.equal(api.getPayloadInput().madaoAutoPickCountry, false);
assert.equal(api.getPayloadInput().madaoReusePhone, true);
assert.equal(api.getPayloadInput().madaoMinPrice, '0.12');
diff --git a/tests/background-settings-schema-persistence.test.js b/tests/background-settings-schema-persistence.test.js
index e641981..847ead4 100644
--- a/tests/background-settings-schema-persistence.test.js
+++ b/tests/background-settings-schema-persistence.test.js
@@ -118,6 +118,7 @@ const PERSISTED_SETTING_DEFAULTS = {
madaoRoutingPlanId: '',
madaoProviderId: '',
madaoCountry: '',
+ madaoOperator: '',
madaoAutoPickCountry: true,
madaoReusePhone: true,
madaoMinPrice: '',
@@ -219,6 +220,7 @@ function normalizeMaDaoBaseUrl(value = '') {
function normalizeMaDaoMode(value = '') { return String(value || '').trim().toLowerCase() === 'direct' ? 'direct' : DEFAULT_MADAO_MODE; }
function normalizeMaDaoIdentifier(value = '') { return String(value || '').trim(); }
function normalizeMaDaoProviderId(value = '') { return String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); }
+function normalizeMaDaoOperator(value = '') { return String(value || '').trim().toLowerCase().replace(/[^a-z0-9_-]+/g, ''); }
function normalizeMaDaoCountry(value = '') {
const trimmed = String(value || '').trim();
if (!trimmed) return '';
@@ -306,6 +308,7 @@ test('buildPersistentSettingsPayload writes canonical settings schema into persi
assert.equal(payload.phoneSmsProvider, 'hero-sms');
assert.equal(payload.madaoBaseUrl, DEFAULT_MADAO_BASE_URL_FOR_TEST);
assert.equal(payload.madaoMode, DEFAULT_MADAO_MODE_FOR_TEST);
+ assert.equal(payload.madaoOperator, '');
assert.equal(payload.madaoAutoPickCountry, true);
assert.equal(payload.madaoReusePhone, true);
assert.equal(Object.prototype.hasOwnProperty.call(payload, 'kiroRegion'), false);
@@ -724,6 +727,7 @@ test('buildPersistentSettingsPayload persists normalized MaDao flat settings out
madaoRoutingPlanId: ' rp-openai ',
madaoProviderId: ' Upstream A! ',
madaoCountry: ' gb ',
+ madaoOperator: ' Operator A! ',
madaoAutoPickCountry: 0,
madaoReusePhone: 1,
madaoMinPrice: '0.123456',
@@ -737,6 +741,7 @@ test('buildPersistentSettingsPayload persists normalized MaDao flat settings out
assert.equal(payload.madaoRoutingPlanId, 'rp-openai');
assert.equal(payload.madaoProviderId, 'upstreama');
assert.equal(payload.madaoCountry, 'GB');
+ assert.equal(payload.madaoOperator, 'operatora');
assert.equal(payload.madaoAutoPickCountry, false);
assert.equal(payload.madaoReusePhone, true);
assert.equal(payload.madaoMinPrice, '0.1235');
diff --git a/tests/madao-provider.test.js b/tests/madao-provider.test.js
index afb8705..d55d700 100644
--- a/tests/madao-provider.test.js
+++ b/tests/madao-provider.test.js
@@ -38,6 +38,7 @@ test('MaDao direct acquire sends only direct fields and normalizes activation da
madaoRoutingPlanId: 'route-plan-should-not-be-sent',
madaoProviderId: 'Upstream A!',
madaoCountry: 'gb',
+ madaoOperator: 'Operator A!',
madaoAutoPickCountry: 'false',
madaoReusePhone: '1',
madaoMinPrice: '0.01',
@@ -54,6 +55,9 @@ test('MaDao direct acquire sends only direct fields and normalizes activation da
auto_pick_country: false,
reuse_phone: true,
country: 'GB',
+ metadata: {
+ operator: 'operatora',
+ },
min_price: 0.01,
max_price: 0.2,
});
diff --git a/tests/phone-verification-flow.test.js b/tests/phone-verification-flow.test.js
index e45c2b6..35077ab 100644
--- a/tests/phone-verification-flow.test.js
+++ b/tests/phone-verification-flow.test.js
@@ -9214,6 +9214,7 @@ test('phone verification helper reacquires MaDao direct numbers after releasing
madaoRoutingPlanId: 'rp-stale',
madaoProviderId: 'upstream-a',
madaoCountry: 'gb',
+ madaoOperator: 'operator-a',
madaoAutoPickCountry: false,
madaoReusePhone: true,
madaoMinPrice: '0.01',
@@ -9323,6 +9324,9 @@ test('phone verification helper reacquires MaDao direct numbers after releasing
auto_pick_country: false,
reuse_phone: true,
country: 'GB',
+ metadata: {
+ operator: 'operator-a',
+ },
min_price: 0.01,
max_price: 0.2,
});
diff --git a/tests/sidepanel-phone-verification-settings.test.js b/tests/sidepanel-phone-verification-settings.test.js
index b95cebd..97f5ad3 100644
--- a/tests/sidepanel-phone-verification-settings.test.js
+++ b/tests/sidepanel-phone-verification-settings.test.js
@@ -159,10 +159,17 @@ test('sidepanel html exposes phone verification toggle and multi-provider SMS ro
assert.match(html, /id="select-madao-routing-plan-id"/);
assert.match(html, /id="btn-madao-refresh-routing-plans"/);
assert.doesNotMatch(html, /id="input-madao-routing-plan-id"/);
- assert.doesNotMatch(html, /id="row-madao-provider-id"/);
+ assert.match(html, /id="row-madao-provider-id"/);
+ assert.match(html, /id="select-madao-provider-id"/);
+ assert.match(html, /id="btn-madao-refresh-providers"/);
assert.doesNotMatch(html, /id="input-madao-provider-id"/);
- assert.doesNotMatch(html, /id="row-madao-country"/);
+ assert.match(html, /id="row-madao-country"/);
+ assert.match(html, /id="select-madao-country"/);
+ assert.match(html, /id="btn-madao-refresh-countries"/);
assert.doesNotMatch(html, /id="input-madao-country"/);
+ assert.match(html, /id="row-madao-operator"/);
+ assert.match(html, /id="select-madao-operator"/);
+ assert.match(html, /id="btn-madao-refresh-operators"/);
assert.doesNotMatch(html, /id="row-madao-auto-pick-country"/);
assert.doesNotMatch(html, /id="input-madao-auto-pick-country"/);
assert.doesNotMatch(html, /id="row-madao-reuse-phone"/);
@@ -275,6 +282,144 @@ return {
assert.equal(requests[0].options.headers.Authorization, 'Bearer madao-secret');
});
+test('MaDao direct selects load provider country and operator options from daemon API', async () => {
+ const requests = [];
+ const fetchImpl = async (url, options = {}) => {
+ const parsedUrl = new URL(url);
+ requests.push({
+ pathname: parsedUrl.pathname,
+ options,
+ body: options.body ? JSON.parse(options.body) : null,
+ });
+ if (parsedUrl.pathname === '/api/providers') {
+ return {
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ async text() {
+ return JSON.stringify({
+ providers: [
+ { id: 'stored-provider', name: 'Stored Provider', enabled: true, protocol_label: 'REST' },
+ { id: 'disabled-provider', name: 'Disabled Provider', enabled: false },
+ ],
+ });
+ },
+ };
+ }
+ if (parsedUrl.pathname === '/api/providers/stored-provider/countries') {
+ return {
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ async text() {
+ return JSON.stringify({
+ provider: 'stored-provider',
+ items: [
+ { value: 'GB', label: 'United Kingdom' },
+ { value: 'TH', label: 'Thailand' },
+ ],
+ });
+ },
+ };
+ }
+ if (parsedUrl.pathname === '/api/providers/stored-provider/operators') {
+ return {
+ ok: true,
+ status: 200,
+ statusText: 'OK',
+ async text() {
+ return JSON.stringify({
+ provider: 'stored-provider',
+ items: [
+ { value: 'operator-a', label: 'Operator A' },
+ { value: 'operator-b', label: 'Operator B' },
+ ],
+ });
+ },
+ };
+ }
+ throw new Error(`Unexpected MaDao path: ${parsedUrl.pathname}`);
+ };
+
+ const api = new Function('fetch', `
+const DEFAULT_MADAO_BASE_URL = 'http://127.0.0.1:7822';
+let latestState = {
+ madaoBaseUrl: 'http://madao.local/api/acquire',
+ madaoHttpSecret: 'madao-secret',
+ madaoProviderId: 'stored-provider',
+ madaoCountry: 'GB',
+ madaoOperator: 'operator-a',
+};
+let maDaoProviderOptions = [];
+let maDaoCountryOptions = [];
+let maDaoOperatorOptions = [];
+let displayText = '';
+let toastText = '';
+const inputMaDaoBaseUrl = { value: 'http://madao.local/api/acquire' };
+const inputMaDaoHttpSecret = { value: 'madao-secret' };
+const selectMaDaoProviderId = { value: 'stored-provider', options: [], replaceChildren(...children) { this.options = children; } };
+const selectMaDaoCountry = { value: 'GB', options: [], replaceChildren(...children) { this.options = children; } };
+const selectMaDaoOperator = { value: 'operator-a', options: [], replaceChildren(...children) { this.options = children; } };
+function updateHeroSmsPlatformDisplay() {
+ displayText = [selectMaDaoProviderId.value, selectMaDaoCountry.value, selectMaDaoOperator.value].filter(Boolean).join('/');
+}
+function showToast(message) {
+ toastText = message;
+}
+${extractFunction('normalizeMaDaoBaseUrlValue')}
+${extractFunction('normalizeMaDaoIdentifierValue')}
+${extractFunction('normalizeMaDaoProviderIdValue')}
+${extractFunction('normalizeMaDaoOperatorValue')}
+${extractFunction('normalizeMaDaoCountry')}
+${extractFunction('createSelectOptionElement')}
+${extractFunction('setSelectOptions')}
+${extractFunction('normalizeMaDaoOptionListItems')}
+${extractFunction('setMaDaoProviderSelectOptions')}
+${extractFunction('setMaDaoCountrySelectOptions')}
+${extractFunction('setMaDaoOperatorSelectOptions')}
+${extractFunction('buildMaDaoRequestUrl')}
+${extractFunction('buildMaDaoRequestHeaders')}
+${extractFunction('fetchMaDaoJson')}
+${extractFunction('getMaDaoProvidersFromPayload')}
+${extractFunction('getMaDaoOptionItemsFromPayload')}
+${extractFunction('getSelectedMaDaoProviderId')}
+${extractFunction('getSelectedMaDaoCountry')}
+${extractFunction('loadMaDaoProviders')}
+${extractFunction('loadMaDaoCountries')}
+${extractFunction('loadMaDaoOperators')}
+return {
+ loadMaDaoProviders,
+ selectMaDaoProviderId,
+ selectMaDaoCountry,
+ selectMaDaoOperator,
+ get providerOptions() { return selectMaDaoProviderId.options.map((option) => ({ value: option.value, label: option.textContent, selected: option.selected })); },
+ get countryOptions() { return selectMaDaoCountry.options.map((option) => ({ value: option.value, label: option.textContent, selected: option.selected })); },
+ get operatorOptions() { return selectMaDaoOperator.options.map((option) => ({ value: option.value, label: option.textContent, selected: option.selected })); },
+ get displayText() { return displayText; },
+ get toastText() { return toastText; },
+};
+`)(fetchImpl);
+
+ const providers = await api.loadMaDaoProviders();
+
+ assert.deepStrictEqual(providers.map((provider) => provider.value), ['stored-provider']);
+ assert.equal(api.selectMaDaoProviderId.value, 'stored-provider');
+ assert.equal(api.selectMaDaoCountry.value, 'GB');
+ assert.equal(api.selectMaDaoOperator.value, 'operator-a');
+ assert.deepStrictEqual(api.providerOptions.map((option) => option.value), ['', 'stored-provider']);
+ assert.deepStrictEqual(api.countryOptions.map((option) => option.value), ['', 'GB', 'TH']);
+ assert.deepStrictEqual(api.operatorOptions.map((option) => option.value), ['', 'operator-a', 'operator-b']);
+ assert.equal(api.displayText, 'stored-provider/GB/operator-a');
+ assert.equal(api.toastText, '已刷新 MaDao 服务商。');
+ assert.deepStrictEqual(requests.map((request) => request.pathname), [
+ '/api/providers',
+ '/api/providers/stored-provider/countries',
+ '/api/providers/stored-provider/operators',
+ ]);
+ assert.deepStrictEqual(requests[2].body, { country: 'GB' });
+ assert.equal(requests[0].options.headers.Authorization, 'Bearer madao-secret');
+});
+
test('HeroSMS country parser accepts keyed country maps from the live API', () => {
const api = new Function(`
${extractFunction('normalizeHeroSmsCountryPayloadEntries')}
@@ -789,6 +934,7 @@ const rowMaDaoMode = { style: { display: 'none' } };
const rowMaDaoRoutingPlanId = { style: { display: 'none' } };
const rowMaDaoProviderId = { style: { display: 'none' } };
const rowMaDaoCountry = { style: { display: 'none' } };
+const rowMaDaoOperator = { style: { display: 'none' } };
const rowMaDaoAutoPickCountry = { style: { display: 'none' } };
const rowMaDaoReusePhone = { style: { display: 'none' } };
const rowMaDaoPriceRange = { style: { display: 'none' } };
@@ -868,6 +1014,9 @@ const PHONE_SMS_PROVIDER_UI_DESCRIPTORS = ${JSON.stringify({
'rowMaDaoRoutingPlanId',
],
directRowKeys: [
+ 'rowMaDaoProviderId',
+ 'rowMaDaoCountry',
+ 'rowMaDaoOperator',
'rowMaDaoPriceRange',
],
},
@@ -943,6 +1092,7 @@ return {
rowMaDaoRoutingPlanId,
rowMaDaoProviderId,
rowMaDaoCountry,
+ rowMaDaoOperator,
rowMaDaoAutoPickCountry,
rowMaDaoReusePhone,
rowMaDaoPriceRange,
@@ -1022,6 +1172,7 @@ return {
assert.equal(api.rowMaDaoRoutingPlanId.style.display, 'none');
assert.equal(api.rowMaDaoProviderId.style.display, 'none');
assert.equal(api.rowMaDaoCountry.style.display, 'none');
+ assert.equal(api.rowMaDaoOperator.style.display, 'none');
assert.equal(api.rowMaDaoAutoPickCountry.style.display, 'none');
assert.equal(api.rowMaDaoReusePhone.style.display, 'none');
assert.equal(api.rowMaDaoPriceRange.style.display, 'none');
@@ -1138,6 +1289,7 @@ return {
assert.equal(api.rowMaDaoRoutingPlanId.style.display, '');
assert.equal(api.rowMaDaoProviderId.style.display, 'none');
assert.equal(api.rowMaDaoCountry.style.display, 'none');
+ assert.equal(api.rowMaDaoOperator.style.display, 'none');
assert.equal(api.rowMaDaoAutoPickCountry.style.display, 'none');
assert.equal(api.rowMaDaoReusePhone.style.display, 'none');
assert.equal(api.rowMaDaoPriceRange.style.display, 'none');
@@ -1148,8 +1300,9 @@ return {
assert.equal(api.rowMaDaoHttpSecret.style.display, '');
assert.equal(api.rowMaDaoMode.style.display, '');
assert.equal(api.rowMaDaoRoutingPlanId.style.display, 'none');
- assert.equal(api.rowMaDaoProviderId.style.display, 'none');
- assert.equal(api.rowMaDaoCountry.style.display, 'none');
+ assert.equal(api.rowMaDaoProviderId.style.display, '');
+ assert.equal(api.rowMaDaoCountry.style.display, '');
+ assert.equal(api.rowMaDaoOperator.style.display, '');
assert.equal(api.rowMaDaoAutoPickCountry.style.display, 'none');
assert.equal(api.rowMaDaoReusePhone.style.display, 'none');
assert.equal(api.rowMaDaoPriceRange.style.display, '');
@@ -1242,8 +1395,9 @@ const inputMaDaoBaseUrl = { value: 'http://127.0.0.1:7822/api/acquire' };
const inputMaDaoHttpSecret = { value: 'madao-secret' };
const selectMaDaoMode = { value: 'direct' };
const selectMaDaoRoutingPlanId = { value: 'plan-1' };
-const inputMaDaoProviderId = { value: 'Local Provider!!' };
-const inputMaDaoCountry = { value: 'th' };
+const selectMaDaoProviderId = { value: 'Local Provider!!' };
+const selectMaDaoCountry = { value: 'th' };
+const selectMaDaoOperator = { value: 'Operator A!' };
const inputMaDaoAutoPickCountry = { checked: false };
const inputMaDaoReusePhone = { checked: true };
const inputMaDaoMinPrice = { value: '0.02' };
@@ -1347,6 +1501,7 @@ ${extractFunction('normalizeMaDaoBaseUrlValue')}
${extractFunction('normalizeMaDaoModeValue')}
${extractFunction('normalizeMaDaoIdentifierValue')}
${extractFunction('normalizeMaDaoProviderIdValue')}
+${extractFunction('normalizeMaDaoOperatorValue')}
${extractFunction('normalizeMaDaoCountry')}
${extractFunction('normalizeMaDaoPriceValue')}
${extractFunction('normalizeFiveSimCountryCode')}
@@ -1419,6 +1574,7 @@ return { collectSettingsPayload };
assert.equal(payload.madaoRoutingPlanId, 'plan-1');
assert.equal(payload.madaoProviderId, 'localprovider');
assert.equal(payload.madaoCountry, 'TH');
+ assert.equal(payload.madaoOperator, 'operatora');
assert.equal(payload.madaoAutoPickCountry, false);
assert.equal(payload.madaoReusePhone, true);
assert.equal(payload.madaoMinPrice, '0.02');
@@ -1470,6 +1626,7 @@ let latestState = {
madaoRoutingPlanId: 'plan-old',
madaoProviderId: 'provider-old',
madaoCountry: 'TH',
+ madaoOperator: 'operator-old',
madaoAutoPickCountry: true,
madaoReusePhone: true,
madaoMinPrice: '0.01',
@@ -1522,8 +1679,27 @@ const selectMaDaoRoutingPlanId = {
this.options = children;
},
};
-const inputMaDaoProviderId = { value: 'Provider Live!' };
-const inputMaDaoCountry = { value: 'local' };
+const selectMaDaoProviderId = {
+ value: 'Provider Live!',
+ options: [],
+ replaceChildren(...children) {
+ this.options = children;
+ },
+};
+const selectMaDaoCountry = {
+ value: 'local',
+ options: [],
+ replaceChildren(...children) {
+ this.options = children;
+ },
+};
+const selectMaDaoOperator = {
+ value: 'Operator Live!',
+ options: [],
+ replaceChildren(...children) {
+ this.options = children;
+ },
+};
const inputMaDaoAutoPickCountry = { checked: false };
const inputMaDaoReusePhone = { checked: false };
const inputMaDaoMinPrice = { value: '0.02' };
@@ -1542,6 +1718,9 @@ let phoneSmsProviderOrderSelection = ['hero-sms', '5sim'];
let lastPhoneSmsProviderBeforeChange = null;
let savedPayload = null;
let maDaoRoutingPlanOptions = [];
+let maDaoProviderOptions = [];
+let maDaoCountryOptions = [];
+let maDaoOperatorOptions = [];
${extractFunction('normalizePhoneSmsProvider')}
${extractFunction('normalizePhoneSmsProviderValue')}
@@ -1573,12 +1752,17 @@ ${extractFunction('normalizeMaDaoModeValue')}
${extractFunction('normalizeMaDaoIdentifierValue')}
${extractFunction('normalizeMaDaoRoutingPlanIdValue')}
${extractFunction('normalizeMaDaoProviderIdValue')}
+${extractFunction('normalizeMaDaoOperatorValue')}
${extractFunction('normalizeMaDaoCountry')}
${extractFunction('normalizeMaDaoPriceValue')}
${extractFunction('createSelectOptionElement')}
${extractFunction('setSelectOptions')}
+${extractFunction('normalizeMaDaoOptionListItems')}
${extractFunction('buildMaDaoRoutingPlanOptions')}
${extractFunction('setMaDaoRoutingPlanSelectOptions')}
+${extractFunction('setMaDaoProviderSelectOptions')}
+${extractFunction('setMaDaoCountrySelectOptions')}
+${extractFunction('setMaDaoOperatorSelectOptions')}
${extractFunction('normalizePhoneSmsMinPriceValue')}
${extractFunction('normalizePhoneSmsMaxPriceValue')}
${extractFunction('normalizeHeroSmsCountryId')}
@@ -1601,6 +1785,7 @@ function syncLatestState(patch) { latestState = { ...latestState, ...patch }; }
function loadHeroSmsCountries() { return Promise.resolve(); }
function loadFiveSimCountries() { return Promise.resolve(); }
function loadNexSmsCountries() { return Promise.resolve(); }
+function loadMaDaoProviders() { return Promise.resolve(); }
function applyHeroSmsFallbackSelection() {}
function applyFiveSimCountrySelection() {}
function applyNexSmsCountrySelection() {}