dcs-git-utils 1.0.0 → 1.0.8
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/.github/workflows/pr.yml +33 -33
- package/.github/workflows/release.yml +71 -64
- package/.vscode/launch.json +22 -22
- package/LICENSE +21 -21
- package/README.md +24 -15
- package/dist/compression.js +119 -109
- package/dist/compression.js.map +1 -1
- package/dist/config.js +149 -139
- package/dist/config.js.map +1 -1
- package/dist/fengari-wrapper.js +88 -78
- package/dist/fengari-wrapper.js.map +1 -1
- package/dist/files/file-picker.js +75 -76
- package/dist/files/file-picker.js.map +1 -1
- package/dist/files/miz-selector.js +23 -23
- package/dist/files/miz-selector.js.map +1 -1
- package/dist/lua +72 -72
- package/dist/main.js +51 -48
- package/dist/main.js.map +1 -1
- package/dist/sorting.js +153 -143
- package/dist/sorting.js.map +1 -1
- package/dist/watchers.js +92 -82
- package/dist/watchers.js.map +1 -1
- package/lua/sorter_lib.lua +72 -72
- package/package.json +61 -62
- package/src/compression.ts +87 -87
- package/src/config.ts +119 -119
- package/src/fengari-wrapper.ts +67 -67
- package/src/files/file-picker.ts +63 -63
- package/src/files/miz-selector.ts +9 -9
- package/src/main.ts +53 -49
- package/src/sorting.ts +127 -127
- package/src/watchers.ts +57 -57
- package/tests/sorting.spec.ts +25 -25
- package/tsconfig.json +100 -100
- package/vitest.config.ts +9 -9
|
@@ -1,77 +1,76 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.pickMissionFileNative =
|
|
16
|
-
const node_child_process_1 = require("node:child_process");
|
|
17
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
18
|
-
function pickMissionFileNative() {
|
|
19
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const platform = node_os_1.default.platform();
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
let cmd = '';
|
|
23
|
-
let args = [];
|
|
24
|
-
if (platform === 'win32') {
|
|
25
|
-
// WINDOWS: Use PowerShell with .NET Forms
|
|
26
|
-
cmd = 'powershell';
|
|
27
|
-
const psScript = `
|
|
28
|
-
Add-Type -AssemblyName System.Windows.Forms
|
|
29
|
-
$f = New-Object System.Windows.Forms.OpenFileDialog
|
|
30
|
-
$f.Filter = "Mission Files (*.miz)|*.miz"
|
|
31
|
-
$f.Title = "Select a DCS Mission File"
|
|
32
|
-
$f.ShowHelp = $true
|
|
33
|
-
$result = $f.ShowDialog()
|
|
34
|
-
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
|
|
35
|
-
Write-Host $f.FileName
|
|
36
|
-
}
|
|
37
|
-
`;
|
|
38
|
-
// Encode command to avoid escaping issues
|
|
39
|
-
args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psScript];
|
|
40
|
-
}
|
|
41
|
-
else if (platform === 'linux') {
|
|
42
|
-
// LINUX: Use Zenity (Common on Ubuntu/Desktop Linux)
|
|
43
|
-
cmd = 'zenity';
|
|
44
|
-
args = ['--file-selection', '--file-filter=*.miz', '--title=Select a Mission File'];
|
|
45
|
-
}
|
|
46
|
-
else if (platform === 'darwin') {
|
|
47
|
-
// MAC: Use AppleScript
|
|
48
|
-
cmd = 'osascript';
|
|
49
|
-
const appleScript = `
|
|
50
|
-
set theFile to choose file with prompt "Select a Mission File" of type {"miz"}
|
|
51
|
-
POSIX path of theFile
|
|
52
|
-
`;
|
|
53
|
-
args = ['-e', appleScript];
|
|
54
|
-
}
|
|
55
|
-
const child = (0, node_child_process_1.spawn)(cmd, args);
|
|
56
|
-
let output = '';
|
|
57
|
-
let errorOutput = '';
|
|
58
|
-
child.stdout.on('data', (data) => { output += data.toString(); });
|
|
59
|
-
child.stderr.on('data', (data) => { errorOutput += data.toString(); });
|
|
60
|
-
child.on('close', (code) => {
|
|
61
|
-
const resultPath = output.trim();
|
|
62
|
-
if (code === 0 && resultPath) {
|
|
63
|
-
resolve(resultPath);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
// If user cancelled, usually code is 1 or path is empty
|
|
67
|
-
reject(new Error("Selection cancelled"));
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
child.on('error', (err) => {
|
|
71
|
-
reject(new Error(`Failed to launch dialog: ${err.message}`));
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
exports.pickMissionFileNative = pickMissionFileNative;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.pickMissionFileNative = pickMissionFileNative;
|
|
16
|
+
const node_child_process_1 = require("node:child_process");
|
|
17
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
18
|
+
function pickMissionFileNative() {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const platform = node_os_1.default.platform();
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
let cmd = '';
|
|
23
|
+
let args = [];
|
|
24
|
+
if (platform === 'win32') {
|
|
25
|
+
// WINDOWS: Use PowerShell with .NET Forms
|
|
26
|
+
cmd = 'powershell';
|
|
27
|
+
const psScript = `
|
|
28
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
29
|
+
$f = New-Object System.Windows.Forms.OpenFileDialog
|
|
30
|
+
$f.Filter = "Mission Files (*.miz)|*.miz"
|
|
31
|
+
$f.Title = "Select a DCS Mission File"
|
|
32
|
+
$f.ShowHelp = $true
|
|
33
|
+
$result = $f.ShowDialog()
|
|
34
|
+
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
|
|
35
|
+
Write-Host $f.FileName
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
// Encode command to avoid escaping issues
|
|
39
|
+
args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', psScript];
|
|
40
|
+
}
|
|
41
|
+
else if (platform === 'linux') {
|
|
42
|
+
// LINUX: Use Zenity (Common on Ubuntu/Desktop Linux)
|
|
43
|
+
cmd = 'zenity';
|
|
44
|
+
args = ['--file-selection', '--file-filter=*.miz', '--title=Select a Mission File'];
|
|
45
|
+
}
|
|
46
|
+
else if (platform === 'darwin') {
|
|
47
|
+
// MAC: Use AppleScript
|
|
48
|
+
cmd = 'osascript';
|
|
49
|
+
const appleScript = `
|
|
50
|
+
set theFile to choose file with prompt "Select a Mission File" of type {"miz"}
|
|
51
|
+
POSIX path of theFile
|
|
52
|
+
`;
|
|
53
|
+
args = ['-e', appleScript];
|
|
54
|
+
}
|
|
55
|
+
const child = (0, node_child_process_1.spawn)(cmd, args);
|
|
56
|
+
let output = '';
|
|
57
|
+
let errorOutput = '';
|
|
58
|
+
child.stdout.on('data', (data) => { output += data.toString(); });
|
|
59
|
+
child.stderr.on('data', (data) => { errorOutput += data.toString(); });
|
|
60
|
+
child.on('close', (code) => {
|
|
61
|
+
const resultPath = output.trim();
|
|
62
|
+
if (code === 0 && resultPath) {
|
|
63
|
+
resolve(resultPath);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// If user cancelled, usually code is 1 or path is empty
|
|
67
|
+
reject(new Error("Selection cancelled"));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
child.on('error', (err) => {
|
|
71
|
+
reject(new Error(`Failed to launch dialog: ${err.message}`));
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
77
76
|
//# sourceMappingURL=file-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-picker.js","sourceRoot":"","sources":["../../src/files/file-picker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-picker.js","sourceRoot":"","sources":["../../src/files/file-picker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAGA,sDA4DC;AA/DD,2DAA2C;AAC3C,sDAAwB;AAExB,SAAsB,qBAAqB;;QACvC,MAAM,QAAQ,GAAG,iBAAE,CAAC,QAAQ,EAAE,CAAC;QAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,IAAI,IAAI,GAAa,EAAE,CAAC;YAExB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACvB,0CAA0C;gBAC1C,GAAG,GAAG,YAAY,CAAC;gBACnB,MAAM,QAAQ,GAAG;;;;;;;;;;aAUhB,CAAC;gBACF,0CAA0C;gBAC1C,IAAI,GAAG,CAAC,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC9E,CAAC;iBACI,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC5B,qDAAqD;gBACrD,GAAG,GAAG,QAAQ,CAAC;gBACf,IAAI,GAAG,CAAC,kBAAkB,EAAE,qBAAqB,EAAE,+BAA+B,CAAC,CAAC;YACxF,CAAC;iBACI,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC7B,uBAAuB;gBACvB,GAAG,GAAG,WAAW,CAAC;gBAClB,MAAM,WAAW,GAAG;;;cAGlB,CAAC;gBACH,IAAI,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,KAAK,GAAG,IAAA,0BAAK,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC/B,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,WAAW,GAAG,EAAE,CAAC;YAErB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,WAAW,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAEvE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACvB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjC,IAAI,IAAI,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,OAAO,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACJ,wDAAwD;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;gBAC7C,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;CAAA"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.getMizPath = void 0;
|
|
16
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
-
const file_picker_1 = require("./file-picker");
|
|
18
|
-
const getMizPath = (
|
|
19
|
-
const mizPath = yield (0, file_picker_1.pickMissionFileNative)();
|
|
20
|
-
const dir = mizPath.replace(node_path_1.default.basename(mizPath), "");
|
|
21
|
-
return { mizPath, dir };
|
|
22
|
-
});
|
|
23
|
-
exports.getMizPath = getMizPath;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getMizPath = void 0;
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
const file_picker_1 = require("./file-picker");
|
|
18
|
+
const getMizPath = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (root = ".") {
|
|
19
|
+
const mizPath = yield (0, file_picker_1.pickMissionFileNative)();
|
|
20
|
+
const dir = mizPath.replace(node_path_1.default.basename(mizPath), "");
|
|
21
|
+
return { mizPath, dir };
|
|
22
|
+
});
|
|
23
|
+
exports.getMizPath = getMizPath;
|
|
24
24
|
//# sourceMappingURL=miz-selector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"miz-selector.js","sourceRoot":"","sources":["../../src/files/miz-selector.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,0DAA4B;AAE5B,+CAAqD;AAE9C,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"miz-selector.js","sourceRoot":"","sources":["../../src/files/miz-selector.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,0DAA4B;AAE5B,+CAAqD;AAE9C,MAAM,UAAU,GAAG,YAA2B,EAAE,mDAAtB,OAAe,GAAG;IAC/C,MAAM,OAAO,GAAG,MAAM,IAAA,mCAAqB,GAAE,CAAC;IAE9C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAC5B,CAAC,CAAA,CAAA;AALY,QAAA,UAAU,cAKtB"}
|
package/dist/lua
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
-- sorter_lib.lua
|
|
2
|
-
|
|
3
|
-
local global_var_name = ...
|
|
4
|
-
local target_table = _G[global_var_name]
|
|
5
|
-
|
|
6
|
-
if type(target_table) ~= "table" then
|
|
7
|
-
return nil, "Table '" .. tostring(global_var_name) .. "' not found."
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
-- CONFIGURATION
|
|
11
|
-
-- true = "key = value" (Clean, standard Lua)
|
|
12
|
-
-- false = "['key'] = value" (Verbose, preserves quotes)
|
|
13
|
-
local SIMPLIFY_KEYS = true
|
|
14
|
-
|
|
15
|
-
-- Keywords that MUST have brackets if used as keys
|
|
16
|
-
local keywords = {
|
|
17
|
-
["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true, ["elseif"]=true, ["end"]=true,
|
|
18
|
-
["false"]=true, ["for"]=true, ["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true,
|
|
19
|
-
["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true, ["repeat"]=true, ["return"]=true,
|
|
20
|
-
["then"]=true, ["true"]=true, ["until"]=true, ["while"]=true
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
local function serialize_sorted(tbl, indent_level)
|
|
24
|
-
indent_level = indent_level or 1
|
|
25
|
-
local indent_str = string.rep(" ", indent_level)
|
|
26
|
-
local result = "{\n"
|
|
27
|
-
|
|
28
|
-
local keys = {}
|
|
29
|
-
for k in pairs(tbl) do table.insert(keys, k) end
|
|
30
|
-
|
|
31
|
-
table.sort(keys, function(a, b)
|
|
32
|
-
local ta, tb = type(a), type(b)
|
|
33
|
-
if ta ~= tb then return ta == "number" end
|
|
34
|
-
if ta == "number" then return a < b end
|
|
35
|
-
return tostring(a) < tostring(b)
|
|
36
|
-
end)
|
|
37
|
-
|
|
38
|
-
for _, k in ipairs(keys) do
|
|
39
|
-
local v = tbl[k]
|
|
40
|
-
local key_str
|
|
41
|
-
|
|
42
|
-
if type(k) == "number" then
|
|
43
|
-
key_str = "[" .. tostring(k) .. "]"
|
|
44
|
-
|
|
45
|
-
elseif type(k) == "string" then
|
|
46
|
-
-- CHECK: Do we want to simplify "['key']" to "key"?
|
|
47
|
-
if SIMPLIFY_KEYS and k:match("^[%a_][%w_]*$") and not keywords[k] then
|
|
48
|
-
key_str = k -- Output: airports =
|
|
49
|
-
else
|
|
50
|
-
key_str = '["' .. k .. '"]' -- Output: ["airports"] =
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
else
|
|
54
|
-
key_str = "[" .. tostring(k) .. "]"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
local val_str
|
|
58
|
-
if type(v) == "table" then
|
|
59
|
-
val_str = serialize_sorted(v, indent_level + 1)
|
|
60
|
-
elseif type(v) == "string" then
|
|
61
|
-
val_str = string.format("%q", v)
|
|
62
|
-
else
|
|
63
|
-
val_str = tostring(v)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
result = result .. indent_str .. key_str .. " = " .. val_str .. ",\n"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
result = result .. string.rep(" ", indent_level - 1) .. "}"
|
|
70
|
-
return result
|
|
71
|
-
end
|
|
72
|
-
|
|
1
|
+
-- sorter_lib.lua
|
|
2
|
+
|
|
3
|
+
local global_var_name = ...
|
|
4
|
+
local target_table = _G[global_var_name]
|
|
5
|
+
|
|
6
|
+
if type(target_table) ~= "table" then
|
|
7
|
+
return nil, "Table '" .. tostring(global_var_name) .. "' not found."
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
-- CONFIGURATION
|
|
11
|
+
-- true = "key = value" (Clean, standard Lua)
|
|
12
|
+
-- false = "['key'] = value" (Verbose, preserves quotes)
|
|
13
|
+
local SIMPLIFY_KEYS = true
|
|
14
|
+
|
|
15
|
+
-- Keywords that MUST have brackets if used as keys
|
|
16
|
+
local keywords = {
|
|
17
|
+
["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true, ["elseif"]=true, ["end"]=true,
|
|
18
|
+
["false"]=true, ["for"]=true, ["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true,
|
|
19
|
+
["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true, ["repeat"]=true, ["return"]=true,
|
|
20
|
+
["then"]=true, ["true"]=true, ["until"]=true, ["while"]=true
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
local function serialize_sorted(tbl, indent_level)
|
|
24
|
+
indent_level = indent_level or 1
|
|
25
|
+
local indent_str = string.rep(" ", indent_level)
|
|
26
|
+
local result = "{\n"
|
|
27
|
+
|
|
28
|
+
local keys = {}
|
|
29
|
+
for k in pairs(tbl) do table.insert(keys, k) end
|
|
30
|
+
|
|
31
|
+
table.sort(keys, function(a, b)
|
|
32
|
+
local ta, tb = type(a), type(b)
|
|
33
|
+
if ta ~= tb then return ta == "number" end
|
|
34
|
+
if ta == "number" then return a < b end
|
|
35
|
+
return tostring(a) < tostring(b)
|
|
36
|
+
end)
|
|
37
|
+
|
|
38
|
+
for _, k in ipairs(keys) do
|
|
39
|
+
local v = tbl[k]
|
|
40
|
+
local key_str
|
|
41
|
+
|
|
42
|
+
if type(k) == "number" then
|
|
43
|
+
key_str = "[" .. tostring(k) .. "]"
|
|
44
|
+
|
|
45
|
+
elseif type(k) == "string" then
|
|
46
|
+
-- CHECK: Do we want to simplify "['key']" to "key"?
|
|
47
|
+
if SIMPLIFY_KEYS and k:match("^[%a_][%w_]*$") and not keywords[k] then
|
|
48
|
+
key_str = k -- Output: airports =
|
|
49
|
+
else
|
|
50
|
+
key_str = '["' .. k .. '"]' -- Output: ["airports"] =
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
else
|
|
54
|
+
key_str = "[" .. tostring(k) .. "]"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
local val_str
|
|
58
|
+
if type(v) == "table" then
|
|
59
|
+
val_str = serialize_sorted(v, indent_level + 1)
|
|
60
|
+
elseif type(v) == "string" then
|
|
61
|
+
val_str = string.format("%q", v)
|
|
62
|
+
else
|
|
63
|
+
val_str = tostring(v)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
result = result .. indent_str .. key_str .. " = " .. val_str .. ",\n"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
result = result .. string.rep(" ", indent_level - 1) .. "}"
|
|
70
|
+
return result
|
|
71
|
+
end
|
|
72
|
+
|
|
73
73
|
return global_var_name .. " = " .. serialize_sorted(target_table)
|
package/dist/main.js
CHANGED
|
@@ -1,50 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
-
};
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
const node_process_1 = __importDefault(require("node:process"));
|
|
17
|
-
const node_fs_1 = require("node:fs");
|
|
18
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
19
|
-
const watchers_1 = require("./watchers");
|
|
20
|
-
const compression_1 = require("./compression");
|
|
21
|
-
const sorting_1 = require("./sorting");
|
|
22
|
-
const config_1 = require("./config");
|
|
23
|
-
const [_0, _1, file] = node_process_1.default.argv;
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
17
|
+
const node_fs_1 = require("node:fs");
|
|
18
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
19
|
+
const watchers_1 = require("./watchers");
|
|
20
|
+
const compression_1 = require("./compression");
|
|
21
|
+
const sorting_1 = require("./sorting");
|
|
22
|
+
const config_1 = require("./config");
|
|
23
|
+
const [_0, _1, file, backup] = node_process_1.default.argv;
|
|
24
|
+
const shouldBackup = backup === "--backup";
|
|
25
|
+
const backupMiz = (filepath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
if (!(filepath === null || filepath === void 0 ? void 0 : filepath.indexOf(".miz"))) {
|
|
27
|
+
throw new Error('no miz file ext');
|
|
28
|
+
}
|
|
29
|
+
const fileWithoutExt = filepath.replace(node_path_1.default.extname(filepath), "");
|
|
30
|
+
yield node_fs_1.promises.copyFile(filepath, `${fileWithoutExt}_backup_${new Date().toISOString().replace(/:/g, '-')}.miz`);
|
|
31
|
+
});
|
|
32
|
+
const initialize = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const { missionPath, outDir, } = yield (0, config_1.initializeConfig)({ file });
|
|
34
|
+
if (shouldBackup) {
|
|
35
|
+
backupMiz(missionPath);
|
|
36
|
+
}
|
|
37
|
+
if ((0, node_fs_1.existsSync)(outDir)) {
|
|
38
|
+
console.log('out exists, using this as source');
|
|
39
|
+
yield (0, compression_1.handleArchive)(outDir, missionPath);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.log("Initial unpack of .miz");
|
|
43
|
+
const files = yield (0, compression_1.unpackMiz)(missionPath, outDir);
|
|
44
|
+
const filePaths = files.filter(f => f.type === "file").map(f => node_path_1.default.join(outDir, f.path));
|
|
45
|
+
yield (0, sorting_1.sortFiles)(filePaths);
|
|
46
|
+
}
|
|
47
|
+
return { mizPath: missionPath, outDir };
|
|
48
|
+
});
|
|
49
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
const { mizPath, outDir } = yield initialize();
|
|
51
|
+
(0, watchers_1.startWatchers)(mizPath, outDir);
|
|
52
|
+
}))();
|
|
50
53
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,gEAAmC;AACnC,qCAAqD;AACrD,0DAA4B;AAC5B,yCAA2C;AAC3C,+CAAyD;AACzD,uCAAsC;AACtC,qCAA4C;AAE5C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,sBAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,gEAAmC;AACnC,qCAAqD;AACrD,0DAA4B;AAC5B,yCAA2C;AAC3C,+CAAyD;AACzD,uCAAsC;AACtC,qCAA4C;AAE5C,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,sBAAO,CAAC,IAAI,CAAC;AAE5C,MAAM,YAAY,GAAG,MAAM,KAAK,UAAU,CAAC;AAE3C,MAAM,SAAS,GAAG,CAAO,QAAgB,EAAE,EAAE;IAEzC,IAAI,CAAC,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,MAAM,CAAC,CAAA,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,cAAc,WAAW,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAC/G,CAAC,CAAA,CAAA;AAED,MAAM,UAAU,GAAG,GAAS,EAAE;IAE1B,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,GAAG,MAAM,IAAA,yBAAgB,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAElE,IAAI,YAAY,EAAE,CAAC;QACf,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,IAAA,oBAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,MAAM,IAAA,2BAAa,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,IAAA,uBAAS,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3F,MAAM,IAAA,mBAAS,EAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC,CAAA,CAAA;AAGD,CAAC,GAAS,EAAE;IAER,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,EAAE,CAAC;IAE/C,IAAA,wBAAa,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC,CAAA,CAAC,EAAE,CAAA"}
|