Migrate project to TypeScript and Playwright scraping

This commit is contained in:
2026-08-05 13:47:45 +02:00
parent 8ecbc6655f
commit 639d9bec75
30 changed files with 3222 additions and 1625 deletions
+89
View File
@@ -0,0 +1,89 @@
// @ts-nocheck
import fs from "node:fs";
import path from "node:path";
export function loadConfig({ configPath = "config/local.json", dryRun } = {}) {
const localConfig = readJsonFile(configPath);
const exampleConfig = readJsonFile("config/local.example.json");
const config = mergeConfig(exampleConfig, localConfig);
const env = readEnvFile(".env");
const appMode = String(config.appMode || "dry-run").toLowerCase();
const resolvedDryRun = dryRun === undefined ? appMode !== "live" : Boolean(dryRun);
return {
appMode,
dryRun: resolvedDryRun,
sourceWorkbook: path.resolve(config.sourceWorkbook || "./xxx_endpoint_bo_2026-08-04_v1.xlsm"),
outputDir: path.resolve(config.outputDir || "./outputs"),
server: {
host: config.server?.host || "127.0.0.1",
port: Number(config.server?.port || 3400),
},
endpoint: {
url: config.endpoint?.url || "https://www.9b-plus.com/apiv1/endpoint/query",
loginUrl: config.endpoint?.loginUrl || "https://www.9b-plus.com/apiv1/auth/login",
token: config.endpoint?.token || "",
username: config.endpoint?.username || "",
password: config.endpoint?.password || "",
},
database: {
driver: String(env.DB_DRIVER || config.database?.driver || "endpoint").toLowerCase(),
mode: String(env.DB_MODE || config.database?.mode || "local").toLowerCase(),
allowWrites: parseBoolean(env.DB_ALLOW_WRITES, config.database?.allowWrites),
host: env.DB_HOST || config.database?.host || "127.0.0.1",
port: Number(env.DB_PORT || config.database?.port || 3306),
name: env.DB_NAME || config.database?.name || "catalog_maker_test",
user: env.DB_USER || config.database?.user || "catalog_maker",
password: env.DB_PASSWORD || config.database?.password || "",
connectionLimit: Number(env.DB_CONNECTION_LIMIT || config.database?.connectionLimit || 5),
},
};
}
function readJsonFile(filePath) {
if (!fs.existsSync(filePath)) {
return {};
}
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function readEnvFile(filePath) {
if (!fs.existsSync(filePath)) return {};
return Object.fromEntries(
fs.readFileSync(filePath, "utf8")
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line && !line.startsWith("#") && line.includes("="))
.map((line) => {
const separator = line.indexOf("=");
return [line.slice(0, separator).trim(), line.slice(separator + 1).trim()];
}),
);
}
function parseBoolean(value, fallback = false) {
if (value === undefined) return Boolean(fallback);
return ["1", "true", "yes", "on"].includes(String(value).toLowerCase());
}
function mergeConfig(base, override) {
return {
...base,
...override,
server: {
...base.server,
...override.server,
},
endpoint: {
...base.endpoint,
...override.endpoint,
},
database: {
...base.database,
...override.database,
},
};
}