s2cfgtojson 3.4.0 → 3.5.0
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/Struct.mts +67 -19
- package/Struct.test.mts +62 -6
- package/package.json +1 -1
package/Struct.mts
CHANGED
|
@@ -13,17 +13,33 @@ const KEYWORDS = [
|
|
|
13
13
|
"bpatch", // allows patching only specific keys
|
|
14
14
|
];
|
|
15
15
|
const REMOVE_NODE = "removenode";
|
|
16
|
-
const INTERNAL_PROPS = new
|
|
17
|
-
"__internal__",
|
|
18
|
-
"fork",
|
|
19
|
-
"removeNode",
|
|
20
|
-
"addNode",
|
|
21
|
-
"clone",
|
|
22
|
-
"forEach",
|
|
23
|
-
"filter",
|
|
24
|
-
"map",
|
|
25
|
-
"toString",
|
|
26
|
-
]
|
|
16
|
+
const INTERNAL_PROPS = new Map([
|
|
17
|
+
["__internal__", "_"],
|
|
18
|
+
["fork", ""], // methods
|
|
19
|
+
["removeNode", ""], // methods
|
|
20
|
+
["addNode", ""], // methods
|
|
21
|
+
["clone", ""], // methods
|
|
22
|
+
["forEach", ""], // methods
|
|
23
|
+
["filter", ""], // methods
|
|
24
|
+
["map", ""], // methods
|
|
25
|
+
["toString", ""], // methods
|
|
26
|
+
] as const);
|
|
27
|
+
const INTERNAL_PROPS_INV = new Map(
|
|
28
|
+
Array.from(INTERNAL_PROPS.entries()).map(([k, v]) => [v, k]),
|
|
29
|
+
);
|
|
30
|
+
const REF_INTERNAL_PROPS = new Map([
|
|
31
|
+
["rawName", "w"],
|
|
32
|
+
["refurl", "u"],
|
|
33
|
+
["refkey", "k"],
|
|
34
|
+
["bskipref", "s"],
|
|
35
|
+
["bpatch", "p"],
|
|
36
|
+
["isArray", "a"],
|
|
37
|
+
["isRoot", "r"],
|
|
38
|
+
["useAsterisk", "*"],
|
|
39
|
+
] as const);
|
|
40
|
+
const REF_INTERNAL_PROPS_INV = new Map(
|
|
41
|
+
Array.from(REF_INTERNAL_PROPS.entries()).map(([k, v]) => [v, k]),
|
|
42
|
+
);
|
|
27
43
|
|
|
28
44
|
/**
|
|
29
45
|
* This file is part of the Stalker 2 Modding Tools project.
|
|
@@ -152,14 +168,26 @@ export class Struct {
|
|
|
152
168
|
return clone;
|
|
153
169
|
}
|
|
154
170
|
|
|
155
|
-
static fromJson<T>(
|
|
171
|
+
static fromJson<T>(
|
|
172
|
+
obj: T,
|
|
173
|
+
minified = false,
|
|
174
|
+
): T extends object ? GetStructType<T> : T {
|
|
156
175
|
if (typeof obj === "object" && !!obj) {
|
|
157
176
|
const instance = new Struct();
|
|
158
177
|
Object.entries(obj).forEach(([key, value]) => {
|
|
159
|
-
|
|
160
|
-
|
|
178
|
+
const nKey = fromMinifiedKey(key, minified);
|
|
179
|
+
|
|
180
|
+
if (nKey === "__internal__") {
|
|
181
|
+
instance[nKey] = new Refs(
|
|
182
|
+
Object.fromEntries(
|
|
183
|
+
Object.entries(value).map(([k, v]) => [
|
|
184
|
+
fromMinifiedKey(k, minified),
|
|
185
|
+
v,
|
|
186
|
+
]),
|
|
187
|
+
),
|
|
188
|
+
);
|
|
161
189
|
} else {
|
|
162
|
-
instance[
|
|
190
|
+
instance[nKey] = Struct.fromJson(value, minified);
|
|
163
191
|
}
|
|
164
192
|
});
|
|
165
193
|
return instance as any;
|
|
@@ -168,15 +196,19 @@ export class Struct {
|
|
|
168
196
|
return obj as any;
|
|
169
197
|
}
|
|
170
198
|
|
|
171
|
-
toJson<T extends object>() {
|
|
199
|
+
toJson<T extends object>(minify = false): T {
|
|
172
200
|
const obj = {};
|
|
201
|
+
|
|
173
202
|
Object.entries(this).forEach(([key, value]) => {
|
|
203
|
+
let nKey = maybeMinifyKey(key, minify);
|
|
174
204
|
if (value instanceof Struct) {
|
|
175
|
-
obj[
|
|
205
|
+
obj[nKey] = value.toJson(minify);
|
|
176
206
|
} else if (value instanceof Refs) {
|
|
177
|
-
obj[
|
|
207
|
+
obj[nKey] = Object.fromEntries(
|
|
208
|
+
Object.entries(value).map(([k, v]) => [maybeMinifyKey(k, minify), v]),
|
|
209
|
+
);
|
|
178
210
|
} else {
|
|
179
|
-
obj[
|
|
211
|
+
obj[nKey] = value;
|
|
180
212
|
}
|
|
181
213
|
});
|
|
182
214
|
return obj as T;
|
|
@@ -449,3 +481,19 @@ function parseStructName(name: string): string {
|
|
|
449
481
|
.replace(/_+/g, "_")
|
|
450
482
|
.replace(/^_+/, "");
|
|
451
483
|
}
|
|
484
|
+
|
|
485
|
+
function maybeMinifyKey(key: string, minify: boolean) {
|
|
486
|
+
return minify &&
|
|
487
|
+
(INTERNAL_PROPS.has(key as any) || REF_INTERNAL_PROPS.has(key as any))
|
|
488
|
+
? INTERNAL_PROPS.get(key as any) || REF_INTERNAL_PROPS.get(key as any)
|
|
489
|
+
: key;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function fromMinifiedKey(key: string, minified: boolean) {
|
|
493
|
+
if (!minified) return key;
|
|
494
|
+
return (
|
|
495
|
+
INTERNAL_PROPS_INV.get(key as any) ||
|
|
496
|
+
REF_INTERNAL_PROPS_INV.get(key as any) ||
|
|
497
|
+
key
|
|
498
|
+
);
|
|
499
|
+
}
|
package/Struct.test.mts
CHANGED
|
@@ -10,21 +10,21 @@ import {
|
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
|
|
12
12
|
class ChimeraHPFix extends Struct {
|
|
13
|
-
__internal__ = {
|
|
13
|
+
__internal__ = new Refs({
|
|
14
14
|
rawName: "ChimeraHPFix",
|
|
15
15
|
isRoot: true,
|
|
16
16
|
bskipref: true,
|
|
17
|
-
};
|
|
17
|
+
});
|
|
18
18
|
|
|
19
19
|
MaxHP = 750;
|
|
20
20
|
}
|
|
21
21
|
class TradePrototype extends Struct {
|
|
22
|
-
__internal__ = {
|
|
22
|
+
__internal__ = new Refs({
|
|
23
23
|
rawName: "TradersDontBuyWeaponsArmor",
|
|
24
24
|
refurl: "../TradePrototypes.cfg",
|
|
25
25
|
refkey: 0,
|
|
26
26
|
isRoot: true,
|
|
27
|
-
};
|
|
27
|
+
});
|
|
28
28
|
|
|
29
29
|
TradeGenerators = new TradeGenerators();
|
|
30
30
|
}
|
|
@@ -37,9 +37,9 @@ class TradeGenerators extends Struct {
|
|
|
37
37
|
"0" = new TradeGenerator();
|
|
38
38
|
}
|
|
39
39
|
class TradeGenerator extends Struct {
|
|
40
|
-
__internal__ = {
|
|
40
|
+
__internal__ = new Refs({
|
|
41
41
|
rawName: "0",
|
|
42
|
-
};
|
|
42
|
+
});
|
|
43
43
|
BuyLimitations = new BuyLimitations();
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -348,6 +348,14 @@ struct.end`;
|
|
|
348
348
|
},
|
|
349
349
|
});
|
|
350
350
|
});
|
|
351
|
+
|
|
352
|
+
test("2", () => {
|
|
353
|
+
const struct = new ChimeraHPFix();
|
|
354
|
+
expect(struct.toJson(true)).toEqual({
|
|
355
|
+
_: { w: "ChimeraHPFix", r: true, s: true },
|
|
356
|
+
MaxHP: 750,
|
|
357
|
+
});
|
|
358
|
+
});
|
|
351
359
|
});
|
|
352
360
|
|
|
353
361
|
describe("fromJson", () => {
|
|
@@ -396,6 +404,54 @@ struct.end`;
|
|
|
396
404
|
struct.end
|
|
397
405
|
struct.end
|
|
398
406
|
struct.end
|
|
407
|
+
struct.end`);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test("2", () => {
|
|
411
|
+
const json = {
|
|
412
|
+
_: { w: "Test", r: true },
|
|
413
|
+
MeshGenerator: {
|
|
414
|
+
_: { w: "MeshGenerator" },
|
|
415
|
+
Meshes: {
|
|
416
|
+
_: { w: "Meshes", a: true },
|
|
417
|
+
"0": {
|
|
418
|
+
_: { w: "0" },
|
|
419
|
+
MeshPath: "path/to/mesh",
|
|
420
|
+
Offset: {
|
|
421
|
+
_: { w: "Offset" },
|
|
422
|
+
X: 0,
|
|
423
|
+
Y: 0,
|
|
424
|
+
Z: 0,
|
|
425
|
+
},
|
|
426
|
+
Rotation: {
|
|
427
|
+
_: { w: "Rotation" },
|
|
428
|
+
Pitch: 0,
|
|
429
|
+
Yaw: 0,
|
|
430
|
+
Roll: 0,
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
const struct = Struct.fromJson(json, true);
|
|
437
|
+
expect(struct.toString()).toBe(`Test : struct.begin
|
|
438
|
+
MeshGenerator : struct.begin
|
|
439
|
+
Meshes : struct.begin
|
|
440
|
+
[0] : struct.begin
|
|
441
|
+
MeshPath = path/to/mesh
|
|
442
|
+
Offset : struct.begin
|
|
443
|
+
X = 0
|
|
444
|
+
Y = 0
|
|
445
|
+
Z = 0
|
|
446
|
+
struct.end
|
|
447
|
+
Rotation : struct.begin
|
|
448
|
+
Pitch = 0
|
|
449
|
+
Yaw = 0
|
|
450
|
+
Roll = 0
|
|
451
|
+
struct.end
|
|
452
|
+
struct.end
|
|
453
|
+
struct.end
|
|
454
|
+
struct.end
|
|
399
455
|
struct.end`);
|
|
400
456
|
});
|
|
401
457
|
});
|