-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.ts
105 lines (90 loc) · 3.88 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import * as fetcher from './assets/fetcher';
import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';
import {EvaluatedScript} from "./assets/types";
const writeFileAsync = promisify(fs.writeFile);
const readdir = promisify(fs.readdir);
// we don't need this awesome method right now ;3
/*function readJSONFile(filename: string): { [key: string]: string }[] | null {
try {
const data = fs.readFileSync(filename, 'utf8');
return JSON.parse(data);
} catch (err) {
console.error('Error reading JSON file:', err);
return null;
}
}*/
// thankies shady. regex go brerrr
const REPLACEMENT_REGEX = /(\[["']\w+.+?]).(\w+)/g;
function replaceClassNamesByRegex(cssString: string, jsonFile: { [key: string]: string }[]): string {
return cssString.replace(REPLACEMENT_REGEX, (match, group1: string, group2) => {
const modifiedGroup = group1.replace(/'/g, "\"");
// JSON.parse can't parse single quotes....?
const rawProps: string[] = JSON.parse(modifiedGroup); // too lazy
const toExcludeProps: string[] = [];
const targetProps = rawProps.filter(x => x.startsWith("!") ? toExcludeProps.push(x) && false : true);
console.log(match, targetProps);
const targetClassName = jsonFile.find(x => targetProps.every(key => x && x.hasOwnProperty(key)) && !toExcludeProps.some(key => x && x.hasOwnProperty(key.slice(1))));
if (targetClassName) {
return targetClassName[group2].replace(' ','.');
}
return match;
});
}
async function startConverting(inputFilePath: string, optionalFilePath: string): Promise<void> {
const outputFolder = 'build';
const fileName = path.basename(inputFilePath, path.extname(inputFilePath));
const outputPath = path.join(outputFolder, fileName);
if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder);
}
try {
if (!fs.existsSync(inputFilePath)) {
fs.writeFileSync(inputFilePath, '');
}
const cssString = await fs.promises.readFile(inputFilePath, 'utf8');
const jsonFile = await fetcher.fetchFullDiscordCSSDefinitions();
const updatedCSS = replaceClassNamesByRegex(cssString, jsonFile);
// you're welcome salty boi ;3
const fileExtension = optionalFilePath && optionalFilePath.startsWith('.') ? optionalFilePath : `.${optionalFilePath || 'css'}`;
await writeFileAsync(outputPath + fileExtension, updatedCSS);
console.log(`Updated CSS has been written to ${outputPath}`);
} catch (err) {
console.error('Error:', err);
}
}
const args: string[] = process.argv.slice(2);
if (args.includes("--help") || args.length == 0) {
console.error('Usage:\n\tnpx ts-node index.ts <file or directory>');
process.exit(1);
}
async function getFiles(dir: string): Promise<string[]> {
const direntArr = await readdir(dir, { withFileTypes: true });
const files = await Promise.all<string[] | string>(direntArr.map((dirent) => {
const res = path.resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
return Array.prototype.concat(...files);
}
let inputPath: string = args[0];
console.log(args)
if (inputPath) {
let resolvedPath: string = path.resolve(inputPath);
let optionalFilePath = args[1];
if (!fs.existsSync(resolvedPath)) {
inputPath += '.css'; // we can try if the user doesn't wanna add .css or forgets to.
resolvedPath = path.resolve(inputPath);
}
if (fs.statSync(resolvedPath).isDirectory()) {
(async () => {
const paths = await getFiles(resolvedPath);
for (let index = 0; index < paths.length; index++) {
const element = paths[index];
startConverting(element, optionalFilePath);
}
})();
}
else
startConverting(resolvedPath, optionalFilePath);
}