diff --git a/Build/build-anti-bogus-domain.js b/Build/build-anti-bogus-domain.js index 368f9d68..7e0e4c0e 100644 --- a/Build/build-anti-bogus-domain.js +++ b/Build/build-anti-bogus-domain.js @@ -1,10 +1,8 @@ // @ts-check const path = require('path'); const { isIPv4, isIPv6 } = require('net'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); -const { withBannerArray } = require('./lib/with-banner'); +const { createRuleset } = require('./lib/create-file'); const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('./lib/fetch-remote-text-by-line'); -const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); const { processLine } = require('./lib/process-line'); (async () => { @@ -53,36 +51,15 @@ const { processLine } = require('./lib/process-line'); ' - https://github.com/felixonmars/dnsmasq-china-list' ]; - await compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Anti Bogus Domain', - description, - new Date(), - surgeRulesetToClashClassicalTextRuleset(result) - ), + await Promise.all(createRuleset( + 'Sukka\'s Ruleset - Anti Bogus Domain', + description, + new Date(), + result, + 'ruleset', + path.resolve(__dirname, '../List/ip/reject.conf'), path.resolve(__dirname, '../Clash/ip/reject.txt') - ); - - await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Anti Bogus Domain', - description, - new Date(), - result - ), - path.resolve(__dirname, '../List/ip/reject.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Anti Bogus Domain', - description, - new Date(), - surgeRulesetToClashClassicalTextRuleset(result) - ), - path.resolve(__dirname, '../Clash/ip/reject.txt') - ) - ]); + )); console.timeEnd('Total Time - build-anti-bogus-domain'); })(); diff --git a/Build/build-apple-cdn.js b/Build/build-apple-cdn.js index 19986b84..11dfde13 100644 --- a/Build/build-apple-cdn.js +++ b/Build/build-apple-cdn.js @@ -1,10 +1,6 @@ const path = require('path'); - -const { compareAndWriteFile } = require('./lib/string-array-compare'); -const { withBannerArray } = require('./lib/with-banner'); - +const { createRuleset } = require('./lib/create-file'); const { parseFelixDnsmasq } = require('./lib/parse-dnsmasq'); -const { surgeRulesetToClashClassicalTextRuleset, surgeDomainsetToClashDomainset } = require('./lib/clash'); (async () => { console.time('Total Time - build-apple-cdn-conf'); @@ -26,40 +22,22 @@ const { surgeRulesetToClashClassicalTextRuleset, surgeDomainsetToClashDomainset const domainset = res.map(i => `.${i}`); await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Apple CDN', - description, - new Date(), - ruleset - ), - path.resolve(__dirname, '../List/non_ip/apple_cdn.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Apple CDN', - description, - new Date(), - surgeRulesetToClashClassicalTextRuleset(ruleset) - ), + ...createRuleset( + 'Sukka\'s Ruleset - Apple CDN', + description, + new Date(), + ruleset, + 'ruleset', + path.resolve(__dirname, '../List/non_ip/apple_cdn.conf'), path.resolve(__dirname, '../Clash/non_ip/apple_cdn.txt') ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Apple CDN', - description, - new Date(), - domainset - ), - path.resolve(__dirname, '../List/domainset/apple_cdn.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Apple CDN', - description, - new Date(), - surgeDomainsetToClashDomainset(domainset) - ), + ...createRuleset( + 'Sukka\'s Ruleset - Apple CDN', + description, + new Date(), + domainset, + 'domainset', + path.resolve(__dirname, '../List/domainset/apple_cdn.conf'), path.resolve(__dirname, '../Clash/domainset/apple_cdn.txt') ) ]); diff --git a/Build/build-cdn-conf.js b/Build/build-cdn-conf.js index 54cbc1fe..077f5b7c 100644 --- a/Build/build-cdn-conf.js +++ b/Build/build-cdn-conf.js @@ -1,11 +1,9 @@ // @ts-check const path = require('path'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); -const { withBannerArray } = require('./lib/with-banner'); +const { createRuleset } = require('./lib/create-file'); const { minifyRules } = require('./lib/minify-rules'); const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('./lib/fetch-remote-text-by-line'); const Trie = require('./lib/trie'); -const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { console.time('Total Time - build-cdn-conf'); @@ -48,26 +46,15 @@ const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); ]; const ruleset = minifyRules(cdnDomainsList); - await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - CDN Domains', - description, - new Date(), - ruleset - ), - path.resolve(__dirname, '../List/non_ip/cdn.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - CDN Domains', - description, - new Date(), - surgeRulesetToClashClassicalTextRuleset(ruleset) - ), - path.resolve(__dirname, '../Clash/non_ip/cdn.txt') - ) - ]); + await Promise.all(createRuleset( + 'Sukka\'s Ruleset - CDN Domains', + description, + new Date(), + ruleset, + 'ruleset', + path.resolve(__dirname, '../List/non_ip/cdn.conf'), + path.resolve(__dirname, '../Clash/non_ip/cdn.txt') + )); console.timeEnd('Total Time - build-cdn-conf'); })(); diff --git a/Build/build-chn-cidr.js b/Build/build-chn-cidr.js index aa359a91..5433b5c6 100644 --- a/Build/build-chn-cidr.js +++ b/Build/build-chn-cidr.js @@ -1,8 +1,8 @@ // @ts-check const { fetchRemoteTextAndCreateReadlineInterface } = require('./lib/fetch-remote-text-by-line'); -const { withBannerArray } = require('./lib/with-banner'); const { resolve: pathResolve } = require('path'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); +// This should not use `createRuleset` API since we are going to generate ipcidr for Clash +const { compareAndWriteFile, withBannerArray } = require('./lib/create-file'); const { processLine } = require('./lib/process-line'); // https://github.com/misakaio/chnroutes2/issues/25 @@ -28,17 +28,19 @@ const EXCLUDE_CIDRS = [ const filteredCidr = excludeCidrs(Array.from(cidr), EXCLUDE_CIDRS, true); console.log('After Merge:', filteredCidr.length); + const description = [ + 'License: CC BY-SA 2.0', + 'Homepage: https://ruleset.skk.moe', + 'GitHub: https://github.com/SukkaW/Surge', + '', + 'Data from https://misaka.io (misakaio @ GitHub)' + ]; + await Promise.all([ compareAndWriteFile( withBannerArray( 'Sukka\'s Ruleset - Mainland China IPv4 CIDR', - [ - 'License: CC BY-SA 2.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'Data from https://misaka.io (misakaio @ GitHub)' - ], + description, new Date(), filteredCidr.map(i => `IP-CIDR,${i}`) ), @@ -47,13 +49,7 @@ const EXCLUDE_CIDRS = [ compareAndWriteFile( withBannerArray( 'Sukka\'s Ruleset - Mainland China IPv4 CIDR', - [ - 'License: CC BY-SA 2.0', - 'Homepage: https://ruleset.skk.moe', - 'GitHub: https://github.com/SukkaW/Surge', - '', - 'Data from https://misaka.io (misakaio @ GitHub)' - ], + description, new Date(), filteredCidr ), diff --git a/Build/build-domestic-ruleset.js b/Build/build-domestic-ruleset.js index 769fba34..50a090c5 100644 --- a/Build/build-domestic-ruleset.js +++ b/Build/build-domestic-ruleset.js @@ -3,10 +3,8 @@ const path = require('path'); const { DOMESTICS } = require('../Source/non_ip/domestic'); const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); const { processLine } = require('./lib/process-line'); -const { withBannerArray } = require('./lib/with-banner'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { compareAndWriteFile, createRuleset } = require('./lib/create-file'); const domainSorter = require('./lib/stable-sort-domain'); -const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); (async () => { const rl = readFileByLine(path.resolve(__dirname, '../Source/non_ip/domestic.conf')); @@ -35,22 +33,13 @@ const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); ]; await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Domestic Domains', - rulesetDescription, - new Date(), - results - ), - path.resolve(__dirname, '../List/non_ip/domestic.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Domestic Domains', - rulesetDescription, - new Date(), - surgeRulesetToClashClassicalTextRuleset(results) - ), + ...createRuleset( + 'Sukka\'s Ruleset - Domestic Domains', + rulesetDescription, + new Date(), + results, + 'ruleset', + path.resolve(__dirname, '../List/non_ip/domestic.conf'), path.resolve(__dirname, '../Clash/non_ip/domestic.txt') ), compareAndWriteFile( diff --git a/Build/build-phishing-domainset.js b/Build/build-phishing-domainset.js index aabf8c22..c2956321 100644 --- a/Build/build-phishing-domainset.js +++ b/Build/build-phishing-domainset.js @@ -1,11 +1,9 @@ const { parse } = require('tldts'); const { processFilterRules } = require('./lib/parse-filter.js'); const path = require('path'); -const { withBannerArray } = require('./lib/with-banner.js'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { createRuleset } = require('./lib/create-file'); const { processLine } = require('./lib/process-line.js'); const domainSorter = require('./lib/stable-sort-domain'); -const { surgeDomainsetToClashDomainset } = require('./lib/clash.js'); const WHITELIST_DOMAIN = new Set([ 'w3s.link', @@ -152,24 +150,13 @@ const BLACK_TLD = new Set([ ' - https://gitlab.com/malware-filter/phishing-filter' ]; - await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Reject Phishing', - description, - new Date(), - results - ), - path.resolve(__dirname, '../List/domainset/reject_phishing.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Reject Phishing', - description, - new Date(), - surgeDomainsetToClashDomainset(results) - ), - path.resolve(__dirname, '../Clash/domainset/reject_phishing.txt') - ) - ]); + await Promise.all(createRuleset( + 'Sukka\'s Ruleset - Reject Phishing', + description, + new Date(), + results, + 'domainset', + path.resolve(__dirname, '../List/domainset/reject_phishing.conf'), + path.resolve(__dirname, '../Clash/domainset/reject_phishing.txt') + )); })(); diff --git a/Build/build-reject-domainset.js b/Build/build-reject-domainset.js index 9c133a37..1e92e1b6 100644 --- a/Build/build-reject-domainset.js +++ b/Build/build-reject-domainset.js @@ -9,14 +9,12 @@ const { processHosts, processFilterRules } = require('./lib/parse-filter'); const Trie = require('./lib/trie'); const { HOSTS, ADGUARD_FILTERS, PREDEFINED_WHITELIST, PREDEFINED_ENFORCED_BACKLIST } = require('./lib/reject-data-source'); -const { withBannerArray } = require('./lib/with-banner'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { createRuleset } = require('./lib/create-file'); const { processLine } = require('./lib/process-line'); const { domainDeduper } = require('./lib/domain-deduper'); const createKeywordFilter = require('./lib/aho-corasick'); const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); const domainSorter = require('./lib/stable-sort-domain'); -const { surgeDomainsetToClashDomainset } = require('./lib/clash'); /** Whitelists */ const filterRuleWhitelistDomainSets = new Set(PREDEFINED_WHITELIST); @@ -210,22 +208,13 @@ const domainSuffixSet = new Set(); const domainset = dudupedDominArray.sort(domainSorter); await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Reject Base', - description, - new Date(), - domainset - ), - pathResolve(__dirname, '../List/domainset/reject.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Reject Base', - description, - new Date(), - surgeDomainsetToClashDomainset(domainset) - ), + ...createRuleset( + 'Sukka\'s Ruleset - Reject Base', + description, + new Date(), + domainset, + 'domainset', + pathResolve(__dirname, '../List/domainset/reject.conf'), pathResolve(__dirname, '../Clash/domainset/reject.txt') ), fs.promises.writeFile( diff --git a/Build/build-speedtest-domainset.js b/Build/build-speedtest-domainset.js index c9e13f52..ff5ea28c 100644 --- a/Build/build-speedtest-domainset.js +++ b/Build/build-speedtest-domainset.js @@ -1,12 +1,10 @@ const { fetch } = require('undici'); const { domainDeduper } = require('./lib/domain-deduper'); const path = require('path'); -const { withBannerArray } = require('./lib/with-banner.js'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); +const { createRuleset } = require('./lib/create-file'); const domainSorter = require('./lib/stable-sort-domain'); const { Sema } = require('async-sema'); -const { surgeDomainsetToClashDomainset } = require('./lib/clash'); const s = new Sema(2); /** @@ -115,24 +113,13 @@ const querySpeedtestApi = async (keyword) => { 'GitHub: https://github.com/SukkaW/Surge' ]; - await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Speedtest Domains', - description, - new Date(), - deduped - ), - path.resolve(__dirname, '../List/domainset/speedtest.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Speedtest Domains', - description, - new Date(), - surgeDomainsetToClashDomainset(deduped) - ), - path.resolve(__dirname, '../Clash/domainset/speedtest.txt') - ) - ]); + await Promise.all(createRuleset( + 'Sukka\'s Ruleset - Speedtest Domains', + description, + new Date(), + deduped, + 'domainset', + path.resolve(__dirname, '../List/domainset/speedtest.conf'), + path.resolve(__dirname, '../Clash/domainset/speedtest.txt') + )); })(); diff --git a/Build/build-telegram-cidr.js b/Build/build-telegram-cidr.js index ec99a565..59152e55 100644 --- a/Build/build-telegram-cidr.js +++ b/Build/build-telegram-cidr.js @@ -2,10 +2,8 @@ const { fetchWithRetry } = require('./lib/fetch-retry'); const { createReadlineInterfaceFromResponse } = require('./lib/fetch-remote-text-by-line'); const path = require('path'); const { isIPv4, isIPv6 } = require('net'); -const { withBannerArray } = require('./lib/with-banner'); const { processLine } = require('./lib/process-line'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); -const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); +const { createRuleset } = require('./lib/create-file'); (async () => { console.time('Total Time - build-telegram-cidr'); @@ -43,26 +41,15 @@ const { surgeRulesetToClashClassicalTextRuleset } = require('./lib/clash'); ' - https://core.telegram.org/resources/cidr.txt' ]; - await Promise.all([ - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Telegram IP CIDR', - description, - date, - results - ), - path.resolve(__dirname, '../List/ip/telegram.conf') - ), - compareAndWriteFile( - withBannerArray( - 'Sukka\'s Ruleset - Telegram IP CIDR', - description, - date, - surgeRulesetToClashClassicalTextRuleset(results) - ), - path.resolve(__dirname, '../Clash/ip/telegram.txt') - ) - ]); + await Promise.all(createRuleset( + 'Sukka\'s Ruleset - Telegram IP CIDR', + description, + date, + results, + 'ruleset', + path.resolve(__dirname, '../List/ip/telegram.conf'), + path.resolve(__dirname, '../Clash/ip/telegram.txt') + )); console.timeEnd('Total Time - build-telegram-cidr'); })(); diff --git a/Build/build.js b/Build/build.js index 963838ef..04722995 100644 --- a/Build/build.js +++ b/Build/build.js @@ -4,10 +4,8 @@ const path = require('path'); const { PathScurry } = require('path-scurry'); const { readFileByLine } = require('./lib/fetch-remote-text-by-line'); const { processLine } = require('./lib/process-line'); -const { compareAndWriteFile } = require('./lib/string-array-compare'); -const { withBannerArray } = require('./lib/with-banner'); +const { createRuleset } = require('./lib/create-file'); const { domainDeduper } = require('./lib/domain-deduper'); -const { surgeRulesetToClashClassicalTextRuleset, surgeDomainsetToClashDomainset } = require('./lib/clash'); const MAGIC_COMMAND_SKIP = '# $ custom_build_script'; const MAGIC_COMMAND_TITLE = '# $ meta_title '; @@ -102,29 +100,15 @@ async function transformDomainset(sourcePath, relativePath) { ) ]; - await Promise.all([ - // Surge DOMAIN-SET - compareAndWriteFile( - withBannerArray( - title, - description, - new Date(), - deduped - ), - path.resolve(outputSurgeDir, relativePath) - ), - // Clash domain text - compareAndWriteFile( - withBannerArray( - title, - description, - new Date(), - surgeDomainsetToClashDomainset(deduped) - ), - // change path extname to .txt - path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) - ) - ]); + await Promise.all(createRuleset( + title, + description, + new Date(), + deduped, + 'domainset', + path.resolve(outputSurgeDir, relativePath), + path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) + )); } /** @@ -149,31 +133,13 @@ async function transformRuleset(sourcePath, relativePath) { ) ]; - const lines = Array.from(set); - - const clashSupported = surgeRulesetToClashClassicalTextRuleset(set); - - await Promise.all([ - // Surge RULE-SET - compareAndWriteFile( - withBannerArray( - title, - description, - new Date(), - lines - ), - path.resolve(outputSurgeDir, relativePath) - ), - // Clash domainset - compareAndWriteFile( - withBannerArray( - title, - description, - new Date(), - clashSupported - ), - // change path extname to .txt - path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) - ) - ]); + await Promise.all(createRuleset( + title, + description, + new Date(), + Array.from(set), + 'ruleset', + path.resolve(outputSurgeDir, relativePath), + path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`) + )); } diff --git a/Build/lib/create-file.js b/Build/lib/create-file.js new file mode 100644 index 00000000..8fbd0180 --- /dev/null +++ b/Build/lib/create-file.js @@ -0,0 +1,99 @@ +// @ts-check +const { promises: fsPromises } = require('fs'); +const fse = require('fs-extra'); +const { readFileByLine } = require('./fetch-remote-text-by-line'); +const { surgeDomainsetToClashDomainset, surgeRulesetToClashClassicalTextRuleset } = require('./clash'); + +/** + * @param {string[]} linesA + * @param {string} filePath + */ +async function compareAndWriteFile(linesA, filePath) { + await fse.ensureFile(filePath); + + let isEqual = true; + let index = 0; + + for await (const lineB of readFileByLine(filePath)) { + const lineA = linesA[index]; + index++; + + if (lineA[0] === '#' && lineB[0] === '#') { + continue; + } + + if (lineA !== lineB) { + isEqual = false; + break; + } + } + + if (!isEqual || index !== linesA.length - 1) { + await fsPromises.writeFile( + filePath, + linesA.join('\n'), + { encoding: 'utf-8' } + ); + } else { + console.log(`Same Content, bail out writing: ${filePath}`); + } +} +module.exports.compareAndWriteFile = compareAndWriteFile; + +/** + * @param {string} title + * @param {string[]} description + * @param {Date} date + * @param {string[]} content + * @returns {string[]} + */ +const withBannerArray = (title, description, date, content) => { + return [ + '########################################', + `# ${title}`, + `# Last Updated: ${date.toISOString()}`, + `# Size: ${content.length}`, + ...description.map(line => (line ? `# ${line}` : '#')), + '########################################', + ...content, + '################# END ###################', + '' + ]; +}; +module.exports.withBannerArray = withBannerArray; + +/** + * @param {string} title + * @param {string[]} description + * @param {Date} date + * @param {string[]} content + * @param {'ruleset' | 'domainset'} type + * @param {string} surgePath + * @param {string} clashPath + */ +const createRuleset = ( + title, description, date, content, + type, surgePath, clashPath +) => { + const surgeContent = withBannerArray(title, description, date, content); + + let _clashContent; + switch (type) { + case 'domainset': + _clashContent = surgeDomainsetToClashDomainset(content); + break; + case 'ruleset': + _clashContent = surgeRulesetToClashClassicalTextRuleset(content); + break; + default: + throw new TypeError(`Unknown type: ${type}`); + } + + const clashContent = withBannerArray(title, description, date, _clashContent); + + return [ + compareAndWriteFile(surgeContent, surgePath), + compareAndWriteFile(clashContent, clashPath) + ]; +}; +module.exports.createRuleset = createRuleset; diff --git a/Build/lib/string-array-compare.js b/Build/lib/string-array-compare.js deleted file mode 100644 index 741d4700..00000000 --- a/Build/lib/string-array-compare.js +++ /dev/null @@ -1,41 +0,0 @@ -// @ts-check -const { promises: fsPromises } = require('fs'); -const fse = require('fs-extra'); -const { readFileByLine } = require('./fetch-remote-text-by-line'); - -/** - * @param {string[]} linesA - * @param {string} filePath - */ -async function compareAndWriteFile(linesA, filePath) { - await fse.ensureFile(filePath); - - let isEqual = true; - let index = 0; - - for await (const lineB of readFileByLine(filePath)) { - const lineA = linesA[index]; - index++; - - if (lineA[0] === '#' && lineB[0] === '#') { - continue; - } - - if (lineA !== lineB) { - isEqual = false; - break; - } - } - - if (!isEqual || index !== linesA.length - 1) { - await fsPromises.writeFile( - filePath, - linesA.join('\n'), - { encoding: 'utf-8' } - ); - } else { - console.log(`Same Content, bail out writing: ${filePath}`); - } -} - -module.exports.compareAndWriteFile = compareAndWriteFile; diff --git a/Build/lib/with-banner.js b/Build/lib/with-banner.js deleted file mode 100644 index 833254f6..00000000 --- a/Build/lib/with-banner.js +++ /dev/null @@ -1,41 +0,0 @@ -// @ts-check - -/** - * @param {string} title - * @param {string[]} description - * @param {Date} date - * @param {string[]} content - * @returns {string} - */ -// const withBanner = (title, description, date, content) => { -// return `######################################## -// # ${title} -// # Last Updated: ${date.toISOString()} -// # Size: ${content.length} -// ${description.map(line => (line ? `# ${line}` : '#')).join('\n')} -// ########################################\n${content.join('\n')}\n################# END ###################\n`; -// }; -// module.exports.withBanner = withBanner; - -/** - * @param {string} title - * @param {string[]} description - * @param {Date} date - * @param {string[]} content - * @returns {string[]} - */ -const withBannerArray = (title, description, date, content) => { - return [ - '########################################', - `# ${title}`, - `# Last Updated: ${date.toISOString()}`, - `# Size: ${content.length}`, - ...description.map(line => (line ? `# ${line}` : '#')), - '########################################', - ...content, - '################# END ###################', - '' - ]; -}; - -module.exports.withBannerArray = withBannerArray;