- ocr.js: Removed all subprocess/spawn logic (spawn, fs, path, process imports, resolveWorkerCommand, buildPythonPath, buildWorkerError, callOcrViaSubprocess, resolveOcrMode, runOcrCommand, etc.) HTTP is now the only mode. Added validation when OCR_BASE_URL is not configured. ~281 lines → ~80 lines. - default.cjs: Removed projectRoot from ocr config (kept path import for data.root) - runtime.js: Removed OCR_PROJECT_ROOT env var parsing - runtime-config.js: Removed projectRoot from ocr type definition All 5 exports preserved: recognizeTencentCaptcha, recognizeImageCaptcha, batchRecognizeTencentCaptcha, warmupLocalOcrWorker, closeLocalOcrWorker
682 lines
19 KiB
JavaScript
682 lines
19 KiB
JavaScript
// @ts-check
|
|
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { createRequire } from "node:module";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
/** @typedef {import('../types/runtime-config.js').RuntimeConfig} RuntimeConfig */
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
export const PROJECT_ROOT = path.resolve(CURRENT_DIR, "../..");
|
|
const WORKSPACE_ROOT = path.resolve(PROJECT_ROOT, "../..");
|
|
const CONFIG_ROOT = path.join(PROJECT_ROOT, "config");
|
|
|
|
loadEnvFiles([
|
|
path.join(WORKSPACE_ROOT, ".env"),
|
|
path.join(PROJECT_ROOT, ".env"),
|
|
]);
|
|
|
|
const defaultConfig = /** @type {RuntimeConfig} */ (
|
|
loadConfig(path.join(CONFIG_ROOT, "default.cjs"))
|
|
);
|
|
|
|
export const runtimeConfig = /** @type {RuntimeConfig} */ (
|
|
applyEnvOverrides(defaultConfig)
|
|
);
|
|
|
|
function loadConfig(configPath) {
|
|
if (!fs.existsSync(configPath)) {
|
|
return {};
|
|
}
|
|
|
|
const loaded = require(configPath);
|
|
return isPlainObject(loaded) ? loaded : {};
|
|
}
|
|
|
|
function loadEnvFiles(filePaths) {
|
|
for (const filePath of filePaths) {
|
|
loadEnvFile(filePath);
|
|
}
|
|
}
|
|
|
|
function loadEnvFile(filePath) {
|
|
if (!fs.existsSync(filePath)) {
|
|
return;
|
|
}
|
|
|
|
const rawText = fs.readFileSync(filePath, "utf8");
|
|
const lines = rawText.split(/\r?\n/);
|
|
|
|
for (const rawLine of lines) {
|
|
const line = rawLine.trim();
|
|
|
|
if (!line || line.startsWith("#")) {
|
|
continue;
|
|
}
|
|
|
|
const separatorIndex = line.indexOf("=");
|
|
if (separatorIndex <= 0) {
|
|
continue;
|
|
}
|
|
|
|
const key = line.slice(0, separatorIndex).trim();
|
|
if (!key || key in process.env) {
|
|
continue;
|
|
}
|
|
|
|
process.env[key] = parseEnvValue(line.slice(separatorIndex + 1));
|
|
}
|
|
}
|
|
|
|
function parseEnvValue(rawValue) {
|
|
const value = String(rawValue || "").trim();
|
|
|
|
if (!value) {
|
|
return "";
|
|
}
|
|
|
|
const quote = value[0];
|
|
if ((quote === '"' || quote === "'") && value.endsWith(quote)) {
|
|
return value.slice(1, -1);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
function applyEnvOverrides(baseConfig) {
|
|
const nextConfig = deepMerge(baseConfig, {});
|
|
|
|
const port = parseInteger(process.env.PORT);
|
|
if (port !== null) {
|
|
nextConfig.server.port = port;
|
|
}
|
|
|
|
const chromePath = String(process.env.CHROME_PATH || "").trim();
|
|
if (chromePath) {
|
|
nextConfig.browser.chromePath = chromePath;
|
|
}
|
|
|
|
const browserHeadless = parseBoolean(process.env.TENCENT_BROWSER_HEADLESS);
|
|
if (browserHeadless !== null) {
|
|
nextConfig.browser.headless = browserHeadless;
|
|
}
|
|
|
|
const browserDevtools = parseBoolean(process.env.TENCENT_BROWSER_DEVTOOLS);
|
|
if (browserDevtools !== null) {
|
|
nextConfig.browser.devtools = browserDevtools;
|
|
}
|
|
|
|
const browserKeepAlive = parseBoolean(process.env.TENCENT_BROWSER_KEEP_ALIVE);
|
|
if (browserKeepAlive !== null) {
|
|
nextConfig.browser.keepAlive = browserKeepAlive;
|
|
}
|
|
|
|
const browserPrewarm = parseBoolean(process.env.TENCENT_BROWSER_PREWARM);
|
|
if (browserPrewarm !== null) {
|
|
nextConfig.browser.prewarm = browserPrewarm;
|
|
}
|
|
|
|
const browserSlowMoMs = parseInteger(process.env.TENCENT_BROWSER_SLOW_MO);
|
|
if (browserSlowMoMs !== null) {
|
|
nextConfig.browser.slowMoMs = browserSlowMoMs;
|
|
}
|
|
|
|
const sessionDebug = parseBoolean(process.env.TENCENT_SESSION_DEBUG);
|
|
if (sessionDebug !== null) {
|
|
nextConfig.session.debug = sessionDebug;
|
|
}
|
|
const ocrBaseUrl = String(process.env.OCR_BASE_URL || "").trim();
|
|
if (ocrBaseUrl) {
|
|
nextConfig.ocr.baseUrl = ocrBaseUrl;
|
|
}
|
|
|
|
const dataRoot = String(process.env.DATA_ROOT || "").trim();
|
|
if (dataRoot) {
|
|
nextConfig.data.root = path.resolve(dataRoot);
|
|
}
|
|
|
|
const logLevel = String(process.env.LOG_LEVEL || "").trim();
|
|
if (logLevel) {
|
|
nextConfig.logging.level = logLevel;
|
|
}
|
|
|
|
const databaseUrl = String(process.env.DATABASE_URL || "").trim();
|
|
if (databaseUrl) {
|
|
nextConfig.database.url = databaseUrl;
|
|
}
|
|
|
|
const databaseSsl = parseBoolean(process.env.DATABASE_SSL);
|
|
if (databaseSsl !== null) {
|
|
nextConfig.database.ssl = databaseSsl;
|
|
}
|
|
|
|
const databaseMaxConnections = parseInteger(
|
|
process.env.DATABASE_MAX_CONNECTIONS
|
|
);
|
|
if (databaseMaxConnections !== null) {
|
|
nextConfig.database.maxConnections = databaseMaxConnections;
|
|
}
|
|
|
|
const claimBaseUrl = String(process.env.CLAIM_BASE_URL || "").trim();
|
|
if (claimBaseUrl) {
|
|
nextConfig.orders.claimBaseUrl = claimBaseUrl;
|
|
} else {
|
|
const appBaseUrl = String(process.env.APP_BASE_URL || "").trim();
|
|
if (appBaseUrl) {
|
|
nextConfig.orders.claimBaseUrl = `${appBaseUrl.replace(
|
|
/\/+$/,
|
|
""
|
|
)}/#/claim`;
|
|
}
|
|
}
|
|
|
|
const tokenTtlHours = parseInteger(process.env.CLAIM_TOKEN_TTL_HOURS);
|
|
if (tokenTtlHours !== null) {
|
|
nextConfig.orders.tokenTtlHours = tokenTtlHours;
|
|
}
|
|
|
|
const adminSessionSecret = String(
|
|
process.env.ADMIN_SESSION_SECRET || ""
|
|
).trim();
|
|
if (adminSessionSecret) {
|
|
nextConfig.admin.sessionSecret = adminSessionSecret;
|
|
}
|
|
|
|
const adminSessionTtlHours = parseInteger(
|
|
process.env.ADMIN_SESSION_TTL_HOURS
|
|
);
|
|
if (adminSessionTtlHours !== null) {
|
|
nextConfig.admin.sessionTtlHours = adminSessionTtlHours;
|
|
}
|
|
|
|
const adminDefaultUsers = parseJsonArray(
|
|
process.env.ADMIN_DEFAULT_USERS_JSON
|
|
);
|
|
if (adminDefaultUsers) {
|
|
nextConfig.admin.defaultUsers = adminDefaultUsers;
|
|
}
|
|
|
|
const agisoAppSecret = String(process.env.AGISO_APP_SECRET || "").trim();
|
|
if (agisoAppSecret) {
|
|
nextConfig.platforms.agiso.appSecret = agisoAppSecret;
|
|
}
|
|
|
|
const agisoTradeDetailEndpoint = String(
|
|
process.env.AGISO_TRADE_DETAIL_ENDPOINT || ""
|
|
).trim();
|
|
if (agisoTradeDetailEndpoint) {
|
|
nextConfig.platforms.agiso.tradeDetail.endpoint = agisoTradeDetailEndpoint;
|
|
}
|
|
|
|
const agisoTradeDetailApiVersion = String(
|
|
process.env.AGISO_TRADE_DETAIL_API_VERSION || ""
|
|
).trim();
|
|
if (agisoTradeDetailApiVersion) {
|
|
nextConfig.platforms.agiso.tradeDetail.apiVersion =
|
|
agisoTradeDetailApiVersion;
|
|
}
|
|
|
|
const agisoTradeDetailTimeoutMs = parseInteger(
|
|
process.env.AGISO_TRADE_DETAIL_TIMEOUT_MS
|
|
);
|
|
if (agisoTradeDetailTimeoutMs !== null) {
|
|
nextConfig.platforms.agiso.tradeDetail.timeoutMs =
|
|
agisoTradeDetailTimeoutMs;
|
|
}
|
|
|
|
const agisoAutoDeliveryEnabled = parseBoolean(
|
|
process.env.AGISO_AUTO_DELIVERY_ENABLED
|
|
);
|
|
if (agisoAutoDeliveryEnabled !== null) {
|
|
nextConfig.platforms.agiso.autoDelivery.enabled = agisoAutoDeliveryEnabled;
|
|
}
|
|
|
|
const agisoAutoDeliveryEndpoint = String(
|
|
process.env.AGISO_AUTO_DELIVERY_ENDPOINT || ""
|
|
).trim();
|
|
if (agisoAutoDeliveryEndpoint) {
|
|
nextConfig.platforms.agiso.autoDelivery.endpoint =
|
|
agisoAutoDeliveryEndpoint;
|
|
}
|
|
|
|
const agisoAutoDeliveryApiVersion = String(
|
|
process.env.AGISO_AUTO_DELIVERY_API_VERSION || ""
|
|
).trim();
|
|
if (agisoAutoDeliveryApiVersion) {
|
|
nextConfig.platforms.agiso.autoDelivery.apiVersion =
|
|
agisoAutoDeliveryApiVersion;
|
|
}
|
|
|
|
const agisoMessageApiVersion = String(
|
|
process.env.AGISO_MESSAGE_API_VERSION || ""
|
|
).trim();
|
|
if (agisoMessageApiVersion) {
|
|
nextConfig.platforms.agiso.messaging.apiVersion = agisoMessageApiVersion;
|
|
}
|
|
|
|
const agisoSendMessageEndpoint = String(
|
|
process.env.AGISO_SEND_MESSAGE_ENDPOINT || ""
|
|
).trim();
|
|
if (agisoSendMessageEndpoint) {
|
|
nextConfig.platforms.agiso.messaging.sendMessageEndpoint =
|
|
agisoSendMessageEndpoint;
|
|
}
|
|
|
|
const agisoMessagingEnabled = parseBoolean(
|
|
process.env.AGISO_MESSAGING_ENABLED
|
|
);
|
|
if (agisoMessagingEnabled !== null) {
|
|
nextConfig.platforms.agiso.messaging.enabled = agisoMessagingEnabled;
|
|
}
|
|
|
|
const ninetyoneUserId = String(process.env.NINETYONE_USER_ID || "").trim();
|
|
if (ninetyoneUserId) {
|
|
nextConfig.platforms.ninetyone.userId = ninetyoneUserId;
|
|
}
|
|
|
|
const ninetyoneSecret = String(process.env.NINETYONE_SECRET || "").trim();
|
|
if (ninetyoneSecret) {
|
|
nextConfig.platforms.ninetyone.secret = ninetyoneSecret;
|
|
}
|
|
|
|
const ninetyoneVersion = String(process.env.NINETYONE_VERSION || "").trim();
|
|
if (ninetyoneVersion) {
|
|
nextConfig.platforms.ninetyone.version = ninetyoneVersion;
|
|
}
|
|
|
|
const ninetyoneShopId = String(process.env.NINETYONE_SHOP_ID || "").trim();
|
|
if (ninetyoneShopId) {
|
|
nextConfig.platforms.ninetyone.shopId = ninetyoneShopId;
|
|
}
|
|
|
|
const ninetyoneShopName = String(
|
|
process.env.NINETYONE_SHOP_NAME || ""
|
|
).trim();
|
|
if (ninetyoneShopName) {
|
|
nextConfig.platforms.ninetyone.shopName = ninetyoneShopName;
|
|
}
|
|
|
|
const ninetyoneTimestampToleranceSeconds = parseInteger(
|
|
process.env.NINETYONE_TIMESTAMP_TOLERANCE_SECONDS
|
|
);
|
|
if (ninetyoneTimestampToleranceSeconds !== null) {
|
|
nextConfig.platforms.ninetyone.timestampToleranceSeconds =
|
|
ninetyoneTimestampToleranceSeconds;
|
|
}
|
|
|
|
const ninetyoneCardsEncoding = String(
|
|
process.env.NINETYONE_CARDS_ENCODING || ""
|
|
).trim();
|
|
if (ninetyoneCardsEncoding) {
|
|
nextConfig.platforms.ninetyone.cardsEncoding = ninetyoneCardsEncoding;
|
|
}
|
|
|
|
const cloudtentaclesBaseUrl = String(
|
|
process.env.CLOUDTENTACLES_BASE_URL || ""
|
|
).trim();
|
|
if (cloudtentaclesBaseUrl) {
|
|
nextConfig.platforms.cloudtentacles.baseUrl = cloudtentaclesBaseUrl;
|
|
}
|
|
|
|
const cloudtentaclesTimeoutMs = parseInteger(
|
|
process.env.CLOUDTENTACLES_TIMEOUT_MS
|
|
);
|
|
if (cloudtentaclesTimeoutMs !== null) {
|
|
nextConfig.platforms.cloudtentacles.timeoutMs = cloudtentaclesTimeoutMs;
|
|
}
|
|
|
|
const cloudtentaclesSendSmsPath = String(
|
|
process.env.CLOUDTENTACLES_SEND_SMS_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesSendSmsPath) {
|
|
nextConfig.platforms.cloudtentacles.sendSmsPath = cloudtentaclesSendSmsPath;
|
|
}
|
|
|
|
const cloudtentaclesLoginPath = String(
|
|
process.env.CLOUDTENTACLES_LOGIN_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesLoginPath) {
|
|
nextConfig.platforms.cloudtentacles.loginPath = cloudtentaclesLoginPath;
|
|
}
|
|
|
|
const cloudtentaclesUserInfoPath = String(
|
|
process.env.CLOUDTENTACLES_USER_INFO_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesUserInfoPath) {
|
|
nextConfig.platforms.cloudtentacles.userInfoPath =
|
|
cloudtentaclesUserInfoPath;
|
|
}
|
|
|
|
const cloudtentaclesAssetPath = String(
|
|
process.env.CLOUDTENTACLES_ASSET_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesAssetPath) {
|
|
nextConfig.platforms.cloudtentacles.assetPath = cloudtentaclesAssetPath;
|
|
}
|
|
|
|
const cloudtentaclesPermissionPath = String(
|
|
process.env.CLOUDTENTACLES_PERMISSION_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesPermissionPath) {
|
|
nextConfig.platforms.cloudtentacles.permissionPath =
|
|
cloudtentaclesPermissionPath;
|
|
}
|
|
|
|
const cloudtentaclesCategoriesPath = String(
|
|
process.env.CLOUDTENTACLES_CATEGORIES_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesCategoriesPath) {
|
|
nextConfig.platforms.cloudtentacles.categoriesPath =
|
|
cloudtentaclesCategoriesPath;
|
|
}
|
|
|
|
const cloudtentaclesSkuListPath = String(
|
|
process.env.CLOUDTENTACLES_SKU_LIST_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesSkuListPath) {
|
|
nextConfig.platforms.cloudtentacles.skuListPath = cloudtentaclesSkuListPath;
|
|
}
|
|
|
|
const cloudtentaclesSkuBuyPath = String(
|
|
process.env.CLOUDTENTACLES_SKU_BUY_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesSkuBuyPath) {
|
|
nextConfig.platforms.cloudtentacles.skuBuyPath = cloudtentaclesSkuBuyPath;
|
|
}
|
|
|
|
const cloudtentaclesKnapsackPath = String(
|
|
process.env.CLOUDTENTACLES_KNAPSACK_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesKnapsackPath) {
|
|
nextConfig.platforms.cloudtentacles.knapsackPath =
|
|
cloudtentaclesKnapsackPath;
|
|
}
|
|
|
|
const cloudtentaclesVnListPath = String(
|
|
process.env.CLOUDTENTACLES_VN_LIST_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnListPath) {
|
|
nextConfig.platforms.cloudtentacles.vnListPath = cloudtentaclesVnListPath;
|
|
}
|
|
|
|
const cloudtentaclesVnAppointPath = String(
|
|
process.env.CLOUDTENTACLES_VN_APPOINT_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnAppointPath) {
|
|
nextConfig.platforms.cloudtentacles.vnAppointPath =
|
|
cloudtentaclesVnAppointPath;
|
|
}
|
|
|
|
const cloudtentaclesVnGenerateLoginCodePath = String(
|
|
process.env.CLOUDTENTACLES_VN_GENERATE_LOGIN_CODE_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnGenerateLoginCodePath) {
|
|
nextConfig.platforms.cloudtentacles.vnGenerateLoginCodePath =
|
|
cloudtentaclesVnGenerateLoginCodePath;
|
|
}
|
|
|
|
const cloudtentaclesVnVerifCodePath = String(
|
|
process.env.CLOUDTENTACLES_VN_VERIF_CODE_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnVerifCodePath) {
|
|
nextConfig.platforms.cloudtentacles.vnVerifCodePath =
|
|
cloudtentaclesVnVerifCodePath;
|
|
}
|
|
|
|
const cloudtentaclesVnVerifyLoginCodePath = String(
|
|
process.env.CLOUDTENTACLES_VN_VERIFY_LOGIN_CODE_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnVerifyLoginCodePath) {
|
|
nextConfig.platforms.cloudtentacles.vnVerifyLoginCodePath =
|
|
cloudtentaclesVnVerifyLoginCodePath;
|
|
}
|
|
|
|
const cloudtentaclesVnBindUrlPath = String(
|
|
process.env.CLOUDTENTACLES_VN_BIND_URL_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnBindUrlPath) {
|
|
nextConfig.platforms.cloudtentacles.vnBindUrlPath =
|
|
cloudtentaclesVnBindUrlPath;
|
|
}
|
|
|
|
const cloudtentaclesVnBindInfoPath = String(
|
|
process.env.CLOUDTENTACLES_VN_BIND_INFO_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnBindInfoPath) {
|
|
nextConfig.platforms.cloudtentacles.vnBindInfoPath =
|
|
cloudtentaclesVnBindInfoPath;
|
|
}
|
|
|
|
const cloudtentaclesVnBackPath = String(
|
|
process.env.CLOUDTENTACLES_VN_BACK_PATH || ""
|
|
).trim();
|
|
if (cloudtentaclesVnBackPath) {
|
|
nextConfig.platforms.cloudtentacles.vnBackPath = cloudtentaclesVnBackPath;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlTtlSeconds = parseInteger(
|
|
process.env.CLOUDTENTACLES_BIND_URL_TTL_SECONDS
|
|
);
|
|
if (cloudtentaclesBindUrlTtlSeconds !== null) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlTtlSeconds =
|
|
cloudtentaclesBindUrlTtlSeconds;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeIntervalSeconds = parseInteger(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_INTERVAL_SECONDS
|
|
);
|
|
if (cloudtentaclesBindUrlProbeIntervalSeconds !== null) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeIntervalSeconds =
|
|
cloudtentaclesBindUrlProbeIntervalSeconds;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeTimeoutMs = parseInteger(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_TIMEOUT_MS
|
|
);
|
|
if (cloudtentaclesBindUrlProbeTimeoutMs !== null) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeTimeoutMs =
|
|
cloudtentaclesBindUrlProbeTimeoutMs;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeUserAgent = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_USER_AGENT || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeUserAgent) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeUserAgent =
|
|
cloudtentaclesBindUrlProbeUserAgent;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeEndpoint = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_ENDPOINT || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeEndpoint) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeEndpoint =
|
|
cloudtentaclesBindUrlProbeEndpoint;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeChartId = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_CHART_ID || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeChartId) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeChartId =
|
|
cloudtentaclesBindUrlProbeChartId;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeSubChartId = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_SUB_CHART_ID || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeSubChartId) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeSubChartId =
|
|
cloudtentaclesBindUrlProbeSubChartId;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeIdeToken = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_IDE_TOKEN || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeIdeToken) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeIdeToken =
|
|
cloudtentaclesBindUrlProbeIdeToken;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeActivityUrl = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_ACTIVITY_URL || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeActivityUrl) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeActivityUrl =
|
|
cloudtentaclesBindUrlProbeActivityUrl;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeReferer = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_REFERER || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeReferer) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeReferer =
|
|
cloudtentaclesBindUrlProbeReferer;
|
|
}
|
|
|
|
const cloudtentaclesBindUrlProbeExtraCookie = String(
|
|
process.env.CLOUDTENTACLES_BIND_URL_PROBE_EXTRA_COOKIE || ""
|
|
).trim();
|
|
if (cloudtentaclesBindUrlProbeExtraCookie) {
|
|
nextConfig.platforms.cloudtentacles.bindUrlProbeExtraCookie =
|
|
cloudtentaclesBindUrlProbeExtraCookie;
|
|
}
|
|
|
|
const cloudtentaclesPublicKeyPem = String(
|
|
process.env.CLOUDTENTACLES_PUBLIC_KEY_PEM || ""
|
|
).trim();
|
|
if (cloudtentaclesPublicKeyPem) {
|
|
nextConfig.platforms.cloudtentacles.publicKeyPem =
|
|
cloudtentaclesPublicKeyPem;
|
|
}
|
|
|
|
const cloudtentaclesClientSource = String(
|
|
process.env.CLOUDTENTACLES_CLIENT_SOURCE || ""
|
|
).trim();
|
|
if (cloudtentaclesClientSource) {
|
|
nextConfig.platforms.cloudtentacles.clientSource =
|
|
cloudtentaclesClientSource;
|
|
}
|
|
|
|
const cloudtentaclesDeviceId = String(
|
|
process.env.CLOUDTENTACLES_DEVICE_ID || ""
|
|
).trim();
|
|
if (cloudtentaclesDeviceId) {
|
|
nextConfig.platforms.cloudtentacles.deviceId = cloudtentaclesDeviceId;
|
|
}
|
|
|
|
const cloudtentaclesDeviceType = parseInteger(
|
|
process.env.CLOUDTENTACLES_DEVICE_TYPE
|
|
);
|
|
if (cloudtentaclesDeviceType !== null) {
|
|
nextConfig.platforms.cloudtentacles.deviceType = cloudtentaclesDeviceType;
|
|
}
|
|
|
|
const proofMode = String(process.env.TENCENT_REDEEM_PROOF_MODE || "").trim();
|
|
if (proofMode) {
|
|
nextConfig.redeem.proofMode = proofMode;
|
|
}
|
|
|
|
return nextConfig;
|
|
}
|
|
|
|
function deepMerge(baseValue, overrideValue) {
|
|
if (!isPlainObject(baseValue)) {
|
|
return cloneValue(overrideValue);
|
|
}
|
|
|
|
const result = cloneValue(baseValue);
|
|
|
|
if (!isPlainObject(overrideValue)) {
|
|
return result;
|
|
}
|
|
|
|
for (const [key, value] of Object.entries(overrideValue)) {
|
|
if (isPlainObject(value) && isPlainObject(result[key])) {
|
|
result[key] = deepMerge(result[key], value);
|
|
continue;
|
|
}
|
|
|
|
result[key] = cloneValue(value);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function cloneValue(value) {
|
|
if (Array.isArray(value)) {
|
|
return value.map((item) => cloneValue(item));
|
|
}
|
|
|
|
if (isPlainObject(value)) {
|
|
const output = {};
|
|
for (const [key, item] of Object.entries(value)) {
|
|
output[key] = cloneValue(item);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
function isPlainObject(value) {
|
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
}
|
|
|
|
function parseBoolean(rawValue) {
|
|
const normalized = String(rawValue || "")
|
|
.trim()
|
|
.toLowerCase();
|
|
|
|
if (!normalized) {
|
|
return null;
|
|
}
|
|
|
|
if (["1", "true", "yes", "on"].includes(normalized)) {
|
|
return true;
|
|
}
|
|
|
|
if (["0", "false", "no", "off"].includes(normalized)) {
|
|
return false;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function parseInteger(rawValue) {
|
|
const normalized = String(rawValue || "").trim();
|
|
|
|
if (!normalized) {
|
|
return null;
|
|
}
|
|
|
|
const parsed = Number(normalized);
|
|
return Number.isFinite(parsed) ? parsed : null;
|
|
}
|
|
|
|
function parseJsonArray(rawValue) {
|
|
const normalized = String(rawValue || "").trim();
|
|
|
|
if (!normalized) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const parsed = JSON.parse(normalized);
|
|
return Array.isArray(parsed) ? parsed : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function normalizeBooleanLike(value) {
|
|
if (typeof value === "boolean") {
|
|
return value;
|
|
}
|
|
|
|
return parseBoolean(value);
|
|
}
|