-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
124 lines (104 loc) · 5.46 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "fs";
import { checkbox, confirm, input, select } from '@inquirer/prompts';
import colors from 'yoctocolors-cjs';
import { resolve, join } from "path";
import Bun, { $ } from 'bun';
type optionType = ('remove_empty_lines' | 'remove_comments' | 'remove_useless_files')[];
const OS: 'win' | 'linux' | 'darwin' = require(`os`).platform().toLowerCase().replace(/[0-9]/g, ``);
const glob = new Bun.Glob('**/*');
const whitelistFiles = ['pack.png', 'pack.mcmeta'];
function format(path: string): string {
return ((path.startsWith('"') || path.startsWith("'")) ? path.slice(1, -1) : path).trim();
}
async function writePath(PATH: string, path: string, options: optionType) {
for await (const file of glob.scan({ cwd: path, absolute: false, onlyFiles: true })) {
mkdirSync(join(PATH, file, '..'), { recursive: true });
if (file.startsWith('data/minecraft/tags/function/')) {
let content = existsSync(join(PATH, file)) ? JSON.parse(readFileSync(join(PATH, file), { encoding: 'utf-8' })).values : [];
let final = JSON.parse(readFileSync(join(path, file), { encoding: 'utf-8' }));
final.values = final.values.concat(content);
writeFileSync(join(PATH, file), JSON.stringify(final, null, options.includes('remove_empty_lines') ? 0 : 4), { encoding: 'utf-8' });
}
else {
if (whitelistFiles.includes(file) || !existsSync(join(PATH, file)) || await confirm({
message: `File ${colors.underline(file)} has a conflict. Overwrite it with file from datapack ${colors.underline(path)}?`,
})) {
if (options.includes('remove_useless_files') && !whitelistFiles.includes(file) && !(file.endsWith('.json') || file.endsWith('.mcfunction') || file.endsWith('.nbt'))) continue;
if (options.length == 0) copyFileSync(join(path, file), join(PATH, file));
else {
let content = readFileSync(join(path, file), { encoding: 'utf-8' });
if (options.includes('remove_comments')) content = content.split('\n').filter(line => !line.trim().startsWith('#')).join('\n');
if (options.includes('remove_empty_lines')) {
if (file.endsWith('.json')) content = JSON.stringify(JSON.parse(content), null, 0);
else content = content.split('\n\n').map(line => line.trim()).join('\n');
}
writeFileSync(join(PATH, file), content, { encoding: 'utf-8' });
}
}
};
};
};
async function askPath(prompt: string): Promise<string> {
return resolve(format(await input({
message: prompt,
required: true,
validate: (value) => existsSync(resolve(format(value))) ? true : colors.red('Path does not exist'),
})));
};
async function timeIt(message: string, func: () => Promise<void> | void) {
console.time(message);
await func();
console.timeEnd(message);
};
async function main() {
const mainFolder = await askPath('Path of your datapacks folder in your world:');
const packList = readdirSync(mainFolder, { withFileTypes: true }).filter(f => f.isDirectory()).map(dir => dir.name);
const mainDatapack = await select({
message: 'Please select the main datapack (the pack.png & pack.mcmeta will override the others):',
choices: packList.map(p => {
return {
name: p,
value: p,
}
}),
});
const secondaryDatapacks = packList.filter(p => p != mainDatapack).concat(mainDatapack);
const PATH = join(process.cwd(), 'output', mainDatapack);
if (existsSync(PATH) && !await confirm({
message: `This will override a previous output at ${colors.underline(PATH)}. Please confirm:`,
default: true,
})) throw new Error('Action cancelled.');
const OPTIONS: optionType = await checkbox({
message: 'Select options for the bundle:',
choices: [
{ name: 'Remove Empty Lines', value: 'remove_empty_lines' },
{ name: 'Remove Comments', value: 'remove_comments' },
{ name: 'Remove Non .json/.mcfunction/.nbt Files', value: 'remove_useless_files' },
],
});
if (existsSync(PATH)) await timeIt(`${colors.green('✔')} Deleted previous build.`, () => {
rmSync(PATH, { recursive: true });
mkdirSync(PATH, { recursive: true });
});
await timeIt(`${colors.green('✔')} Finished bundling ${secondaryDatapacks.length} datapacks into one.`, async () => {
for (const path of secondaryDatapacks) {
await timeIt(`${colors.green('✔')} Added ${colors.bold(path)}.`, async () => {
await writePath(PATH, join(mainFolder, path), OPTIONS);
});
};
});
console.log('');
if (await confirm({
message: 'Do you want to zip the output? This will override the previous zip file.',
default: false,
})) await timeIt(`${colors.green('✔')} Zipped the output.`, async () => {
await $`zip -r ${PATH + '.zip'} ${PATH}`.quiet();
})
if (await confirm({
message: 'Do you want to open the result folder in your file explorer?',
default: false,
})) await timeIt(`${colors.green('✔')} Opened the output folder.`, async () => {
await $`${{ win: 'explorer', linux: 'xdg-open', darwin: 'open' }[OS]} ${PATH}`.quiet();
});
};
main();