videa.hu
[Adblock-list-backups-hufilter.git] / assets / scripts / build.js
bloba3cfde9e46fa1ce5810e7fd61bfc5855942fd678
1 import dateFormat from "dateformat";
2 import crypto from "crypto";
3 import { promises as fs } from "fs";
4 import path from "path";
5 import { fileURLToPath } from "url";
7 // Filters structure
8 import filters from "../../filters.json" with { type: "json" };
10 const NULL_IP = "0.0.0.0";
12 // For header example, see https://easylist-downloads.adblockplus.org/easylist.txt
13 const currentDate = new Date();
14 const version = dateFormat(currentDate, "yyyymmddHHMM", true);
15 const lastModified = dateFormat(currentDate, "dd mmm yyyy HH:MM Z", true);
17 const __filename = fileURLToPath(import.meta.url);
18 const __dirname = path.dirname(__filename);
20 const calculateChecksum = (content) => {
21 const rest = content.replace(/! Checksum: #CHECKSUM#\n/, "");
22 return crypto
23 .createHash("md5")
24 .update(rest)
25 .digest("base64")
26 .replace("==", "");
29 const withFinalNL = (content) => content.toString().trim() + "\n";
31 const buildFilters = async () => {
32 console.log("Build filters...");
33 for (const filter of filters) {
34 if (!filter.hasOwnProperty("sections")) continue;
35 console.log(` * Building list: ${filter.output}`);
36 try {
37 // Collect header
38 let headerContent = "";
39 if (filter.hasOwnProperty("header")) {
40 headerContent += withFinalNL(
41 await fs.readFile(
42 path.join(__dirname, `../../sections/headers/${filter.header}`)
45 console.log(` - Header: ${filter.header} added`);
47 // Collect sections
48 console.log(` - Sections:`);
49 let content = "";
50 for (const section of filter.sections) {
51 content += withFinalNL(
52 await fs.readFile(path.join(__dirname, `../../sections/${section}`))
54 console.log(` - ${section} added`);
56 // Handle DNS / hosts filters
57 if (filter.dns || filter.hosts) {
58 // TODO: Switch to AGTree and extract domain from pattern with tldts
59 const regex = /^\|\|([a-z0-9]+([-.][a-z0-9]+)*\.[a-z]{2,})($|\^$)/gm;
60 const matches = content.matchAll(regex);
61 const domains = Array.from(matches, ([_, domain]) => domain);
62 content = (
63 filter.hosts
64 ? domains.map((domain) => `${NULL_IP} ${domain}`)
65 : domains
66 ).join("\n");
68 // Remove empty lines
69 const strippedFilters =
70 content
71 .split(/\r?\n/)
72 .filter((line) => line.replace("!", "").trim().length > 0)
73 .join("\n") +
74 "\n";
75 // Header attributes
76 if (headerContent.length) {
77 // Versions
78 headerContent = headerContent.replace(/#VERSION#/, version);
79 headerContent = headerContent.replace(/#LAST_MODIFIED#/, lastModified);
80 headerContent = headerContent.replace(/#TITLE#/, filter.title || "hufilter");
81 // Checksum
82 const checksum = await calculateChecksum(headerContent + strippedFilters);
83 headerContent = headerContent.replace(/#CHECKSUM#/, checksum);
85 const fileContent = headerContent + strippedFilters;
86 // Write output
87 await fs.writeFile(
88 path.join(__dirname, `../../dist/${filter.output}`),
89 fileContent
91 } catch (err) {
92 console.log(` - FAILED: ${err.message}`);
97 (async () => {
98 // Create dist folder if not exists
99 try {
100 await fs.mkdir(path.join(__dirname, "../../dist"));
101 } catch (err) {}
103 await buildFilters();
104 })();