@vnejs/build 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@vnejs/build",
3
+ "version": "0.0.1",
4
+ "description": "Build tools for @vnejs",
5
+ "source": "src/index.js",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "@vnejs/tools": "./src/index.js"
9
+ },
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1",
12
+ "publish:major": "npm version major && npm publish --access public",
13
+ "publish:minor": "npm version minor && npm publish --access public",
14
+ "publish:patch": "npm version patch && npm publish --access public"
15
+ },
16
+ "keywords": [],
17
+ "author": "",
18
+ "license": "ISC",
19
+ "dependencies": {
20
+ "lodash.merge": "4.6.2"
21
+ }
22
+ }
@@ -0,0 +1,27 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const merge = require("lodash.merge");
4
+ const { runBuildData } = require("./utils");
5
+
6
+ let result = {};
7
+
8
+ const gameDir = path.join(process.env.PWD, "game");
9
+ const distDir = path.join(process.env.PWD, "dist");
10
+
11
+ module.exports = (options) => {
12
+ !options.watch && fs.rmSync(distDir, { recursive: true, force: true });
13
+ !options.watch && fs.mkdirSync(distDir);
14
+
15
+ fs.readdirSync(gameDir).forEach((modDir) => {
16
+ const newData = runBuildData({ modDir: path.join(gameDir, modDir) });
17
+ result = merge(result, newData);
18
+
19
+ fs.writeFileSync(path.join(distDir, `media.${modDir}.json`), JSON.stringify(newData.data.media));
20
+ });
21
+
22
+ Object.keys(result.label).forEach((label) => {
23
+ fs.writeFileSync(path.join(distDir, `label.${label}.json`), JSON.stringify(result.label[label]));
24
+ });
25
+
26
+ fs.writeFileSync(path.join(distDir, "mods.json"), JSON.stringify(fs.readdirSync(gameDir)));
27
+ };
@@ -0,0 +1,151 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const labelReg = /^label (?<name>[a-zA-Z0-9А-Яа-я_-]+?):?$/;
5
+ const importReg = /^import (?<filename>[a-zA-Z0-9_/]+?)$/;
6
+ const keyValueReg = /(?<key>[a-zA-Z0-9_-]+): (?<value>.+)$/;
7
+ const keyReg = /(?<key>[a-zA-Z0-9_-]+):$/;
8
+
9
+ const rawValueReg = /^(\d+|\d+[.]\d+|["].*["]|true|false)$/;
10
+
11
+ const commentStartChars = ["//", "#"];
12
+
13
+ const mapValue = (value) => JSON.parse(rawValueReg.test(value) ? value : `"${value}"`);
14
+
15
+ const readScenarioFile = (filename) => fs.readFileSync(`${filename}.vne`).toString().replace(/\r/g, "").split("\n");
16
+
17
+ const getFilesInDir = (dirPath, prefix = "") => {
18
+ let result = fs.readdirSync(dirPath);
19
+
20
+ while (!result.every((dirOrFile) => fs.lstatSync(path.join(dirPath, dirOrFile)).isFile())) {
21
+ const dirs = result.filter((i) => fs.lstatSync(path.join(dirPath, i)).isDirectory());
22
+ result = result.filter((i) => !dirs.includes(i));
23
+
24
+ dirs.forEach((dir) => {
25
+ result.push(...getFilesInDir(path.join(dirPath, dir), dir));
26
+ });
27
+ }
28
+
29
+ return prefix ? result.map((filename) => `${prefix}/${filename}`) : result;
30
+ };
31
+
32
+ const prepareMediaInfo = (mediaDir, mediaSubType = null) =>
33
+ getFilesInDir(path.join(mediaDir, mediaSubType)).reduce((acc, file) => {
34
+ acc[file.slice(0, -path.parse(file).ext.length)] = `/media/${mediaSubType}/${file}`;
35
+
36
+ return acc;
37
+ }, {});
38
+
39
+ const parseLines = (lines) => {
40
+ const realLines = [];
41
+ let curKeys = [];
42
+
43
+ lines
44
+ .filter((value) => {
45
+ const kek = value.trim();
46
+
47
+ return !commentStartChars.some((char) => kek.startsWith(char));
48
+ })
49
+ .map((line) => (line.endsWith(":") && !line.startsWith(" ") ? line.slice(0, line.length - 1) : line))
50
+ .forEach((line) => {
51
+ if (keyReg.test(line)) {
52
+ const { key } = line.match(keyReg).groups;
53
+ return curKeys.push({ key, indent: line.length - line.trim().length });
54
+ } else if (keyValueReg.test(line)) {
55
+ const { key, value } = line.match(keyValueReg).groups;
56
+
57
+ curKeys = curKeys.filter(({ indent } = {}) => indent < line.length - line.trim().length);
58
+
59
+ const args = curKeys.reduce((acc, { key }) => {
60
+ if (!acc[key]) {
61
+ acc[key] = {};
62
+ }
63
+ return acc[key];
64
+ }, realLines[realLines.length - 1].args);
65
+
66
+ args[key] = mapValue(value);
67
+ } else {
68
+ curKeys = [];
69
+ const realLine = line.trim();
70
+ realLines.push({
71
+ line: realLine,
72
+ indent: line.length - realLine.length,
73
+ args: {},
74
+ });
75
+ }
76
+ });
77
+
78
+ return realLines;
79
+ };
80
+
81
+ const runBuildData = ({ modDir } = {}) => {
82
+ const result = { data: {}, label: {} };
83
+ const mediaDir = path.join(modDir, "media");
84
+ const scenarioDir = path.join(modDir, "scenario");
85
+
86
+ if (fs.existsSync(mediaDir)) {
87
+ const media = fs.readdirSync(mediaDir).reduce((acc, mediaSubDir) => {
88
+ acc[mediaSubDir] = prepareMediaInfo(mediaDir, mediaSubDir);
89
+
90
+ return acc;
91
+ }, {});
92
+ result.data = { media };
93
+ }
94
+
95
+ if (fs.existsSync(scenarioDir)) {
96
+ const lines = readScenarioFile(`${scenarioDir}/index`);
97
+ let [curLine, curLabel, curIndent] = [0, null, 0];
98
+
99
+ while (curLine < lines.length) {
100
+ const line = lines[curLine];
101
+
102
+ if (line.trim().length) {
103
+ if (importReg.test(line)) {
104
+ let { filename } = line.match(importReg).groups;
105
+ lines.splice(curLine, 1, ...readScenarioFile(path.join(scenarioDir, filename)));
106
+ continue;
107
+ } else if (labelReg.test(line)) {
108
+ const nextLine = lines[curLine + 1];
109
+
110
+ let { name } = line.match(labelReg).groups;
111
+
112
+ curLabel = name;
113
+ curIndent = nextLine.length - nextLine.trim().length;
114
+ }
115
+ }
116
+
117
+ curLine++;
118
+ }
119
+
120
+ // fs.writeFileSync(path.join(rootDir, "dist", "data.json"), JSON.stringify({ media }));
121
+
122
+ let curLabel2 = null;
123
+
124
+ const kek = lines.reduce((acc, line) => {
125
+ if (labelReg.test(line)) {
126
+ let { name } = line.match(labelReg).groups;
127
+
128
+ curLabel2 = name;
129
+ acc[name] = [];
130
+ } else {
131
+ acc[curLabel2].push(line);
132
+ }
133
+
134
+ return acc;
135
+ }, {});
136
+
137
+ Object.keys(kek).map(async (label) => {
138
+ const minIndent = kek[label].reduce(
139
+ (acc, k) => Math.min(acc, k.length ? k.length - k.trim().length : 9999),
140
+ 9999
141
+ );
142
+ // const maxIndent = kek[label].reduce((acc, k) => Math.max(acc, k.length - k.trim().length), -9999);
143
+ const lines = kek[label].map((a) => a.slice(minIndent)).filter(Boolean);
144
+ result.label[label] = { lines: parseLines(lines) };
145
+ });
146
+ }
147
+
148
+ return result;
149
+ };
150
+
151
+ module.exports = { runBuildData };
package/src/index.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require("commander");
4
+
5
+ const dataAction = require("./data");
6
+
7
+ const packageJson = require("../package.json");
8
+
9
+ const program = new Command();
10
+
11
+ program.name(packageJson.name).description(packageJson.description).version(packageJson.version);
12
+
13
+ program
14
+ .command("data")
15
+ .option("-w, --watch", "watch mode", false)
16
+ .option("-q, --quiet", "no console mode", false)
17
+ .action(dataAction);
18
+
19
+ program
20
+ .command("bundle")
21
+ .option("-w, --watch", "watch mode", false)
22
+ .option("-q, --quiet", "no console mode", false)
23
+ .action(dataAction);
24
+
25
+ program.parse();