create-file.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // @ts-check
  2. const { promises: fsPromises } = require('fs');
  3. const fse = require('fs-extra');
  4. const { readFileByLine } = require('./fetch-remote-text-by-line');
  5. const { surgeDomainsetToClashDomainset, surgeRulesetToClashClassicalTextRuleset } = require('./clash');
  6. /**
  7. * @param {string[]} linesA
  8. * @param {string} filePath
  9. */
  10. async function compareAndWriteFile(linesA, filePath) {
  11. await fse.ensureFile(filePath);
  12. let isEqual = true;
  13. let index = 0;
  14. for await (const lineB of readFileByLine(filePath)) {
  15. const lineA = linesA[index];
  16. index++;
  17. if (lineA[0] === '#' && lineB[0] === '#') {
  18. continue;
  19. }
  20. if (lineA !== lineB) {
  21. isEqual = false;
  22. break;
  23. }
  24. }
  25. if (!isEqual || index !== linesA.length - 1) {
  26. await fsPromises.writeFile(
  27. filePath,
  28. linesA.join('\n'),
  29. { encoding: 'utf-8' }
  30. );
  31. } else {
  32. console.log(`Same Content, bail out writing: ${filePath}`);
  33. }
  34. }
  35. module.exports.compareAndWriteFile = compareAndWriteFile;
  36. /**
  37. * @param {string} title
  38. * @param {string[]} description
  39. * @param {Date} date
  40. * @param {string[]} content
  41. * @returns {string[]}
  42. */
  43. const withBannerArray = (title, description, date, content) => {
  44. return [
  45. '########################################',
  46. `# ${title}`,
  47. `# Last Updated: ${date.toISOString()}`,
  48. `# Size: ${content.length}`,
  49. ...description.map(line => (line ? `# ${line}` : '#')),
  50. '########################################',
  51. ...content,
  52. '################# END ###################',
  53. ''
  54. ];
  55. };
  56. module.exports.withBannerArray = withBannerArray;
  57. /**
  58. * @param {string} title
  59. * @param {string[]} description
  60. * @param {Date} date
  61. * @param {string[]} content
  62. * @param {'ruleset' | 'domainset'} type
  63. * @param {string} surgePath
  64. * @param {string} clashPath
  65. */
  66. const createRuleset = (
  67. title, description, date, content,
  68. type, surgePath, clashPath
  69. ) => {
  70. const surgeContent = withBannerArray(title, description, date, content);
  71. let _clashContent;
  72. switch (type) {
  73. case 'domainset':
  74. _clashContent = surgeDomainsetToClashDomainset(content);
  75. break;
  76. case 'ruleset':
  77. _clashContent = surgeRulesetToClashClassicalTextRuleset(content);
  78. break;
  79. default:
  80. throw new TypeError(`Unknown type: ${type}`);
  81. }
  82. const clashContent = withBannerArray(title, description, date, _clashContent);
  83. return [
  84. compareAndWriteFile(surgeContent, surgePath),
  85. compareAndWriteFile(clashContent, clashPath)
  86. ];
  87. };
  88. module.exports.createRuleset = createRuleset;