s2cfgtojson 3.4.0 → 3.5.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/Struct.mts +71 -19
- package/Struct.test.mts +62 -6
- package/package.json +1 -1
- package/types.mts +6 -3
package/Struct.mts
CHANGED
|
@@ -13,17 +13,37 @@ 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
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
]
|
|
16
|
+
const INTERNAL_PROPS = new Map([
|
|
17
|
+
["__internal__", "_"],
|
|
18
|
+
["fork", ""], // methods
|
|
19
|
+
["removeNode", ""], // methods
|
|
20
|
+
["addNode", ""], // methods
|
|
21
|
+
["clone", ""], // methods
|
|
22
|
+
["entries", ""], // methods
|
|
23
|
+
["forEach", ""], // methods
|
|
24
|
+
["filter", ""], // methods
|
|
25
|
+
["map", ""], // methods
|
|
26
|
+
["fromJson", ""], // methods
|
|
27
|
+
["toJson", ""], // methods
|
|
28
|
+
["toString", ""], // methods
|
|
29
|
+
["fromString", ""], // methods
|
|
30
|
+
] as const);
|
|
31
|
+
const INTERNAL_PROPS_INV = new Map(
|
|
32
|
+
Array.from(INTERNAL_PROPS.entries()).map(([k, v]) => [v, k]),
|
|
33
|
+
);
|
|
34
|
+
const REF_INTERNAL_PROPS = new Map([
|
|
35
|
+
["rawName", "w"],
|
|
36
|
+
["refurl", "u"],
|
|
37
|
+
["refkey", "k"],
|
|
38
|
+
["bskipref", "s"],
|
|
39
|
+
["bpatch", "p"],
|
|
40
|
+
["isArray", "a"],
|
|
41
|
+
["isRoot", "r"],
|
|
42
|
+
["useAsterisk", "*"],
|
|
43
|
+
] as const);
|
|
44
|
+
const REF_INTERNAL_PROPS_INV = new Map(
|
|
45
|
+
Array.from(REF_INTERNAL_PROPS.entries()).map(([k, v]) => [v, k]),
|
|
46
|
+
);
|
|
27
47
|
|
|
28
48
|
/**
|
|
29
49
|
* This file is part of the Stalker 2 Modding Tools project.
|
|
@@ -152,14 +172,26 @@ export class Struct {
|
|
|
152
172
|
return clone;
|
|
153
173
|
}
|
|
154
174
|
|
|
155
|
-
static fromJson<T>(
|
|
175
|
+
static fromJson<T>(
|
|
176
|
+
obj: T,
|
|
177
|
+
minified = false,
|
|
178
|
+
): T extends object ? GetStructType<T> : T {
|
|
156
179
|
if (typeof obj === "object" && !!obj) {
|
|
157
180
|
const instance = new Struct();
|
|
158
181
|
Object.entries(obj).forEach(([key, value]) => {
|
|
159
|
-
|
|
160
|
-
|
|
182
|
+
const nKey = fromMinifiedKey(key, minified);
|
|
183
|
+
|
|
184
|
+
if (nKey === "__internal__") {
|
|
185
|
+
instance[nKey] = new Refs(
|
|
186
|
+
Object.fromEntries(
|
|
187
|
+
Object.entries(value).map(([k, v]) => [
|
|
188
|
+
fromMinifiedKey(k, minified),
|
|
189
|
+
v,
|
|
190
|
+
]),
|
|
191
|
+
),
|
|
192
|
+
);
|
|
161
193
|
} else {
|
|
162
|
-
instance[
|
|
194
|
+
instance[nKey] = Struct.fromJson(value, minified);
|
|
163
195
|
}
|
|
164
196
|
});
|
|
165
197
|
return instance as any;
|
|
@@ -168,15 +200,19 @@ export class Struct {
|
|
|
168
200
|
return obj as any;
|
|
169
201
|
}
|
|
170
202
|
|
|
171
|
-
toJson<T extends object>() {
|
|
203
|
+
toJson<T extends object>(minify = false): T {
|
|
172
204
|
const obj = {};
|
|
205
|
+
|
|
173
206
|
Object.entries(this).forEach(([key, value]) => {
|
|
207
|
+
let nKey = maybeMinifyKey(key, minify);
|
|
174
208
|
if (value instanceof Struct) {
|
|
175
|
-
obj[
|
|
209
|
+
obj[nKey] = value.toJson(minify);
|
|
176
210
|
} else if (value instanceof Refs) {
|
|
177
|
-
obj[
|
|
211
|
+
obj[nKey] = Object.fromEntries(
|
|
212
|
+
Object.entries(value).map(([k, v]) => [maybeMinifyKey(k, minify), v]),
|
|
213
|
+
);
|
|
178
214
|
} else {
|
|
179
|
-
obj[
|
|
215
|
+
obj[nKey] = value;
|
|
180
216
|
}
|
|
181
217
|
});
|
|
182
218
|
return obj as T;
|
|
@@ -449,3 +485,19 @@ function parseStructName(name: string): string {
|
|
|
449
485
|
.replace(/_+/g, "_")
|
|
450
486
|
.replace(/^_+/, "");
|
|
451
487
|
}
|
|
488
|
+
|
|
489
|
+
function maybeMinifyKey(key: string, minify: boolean) {
|
|
490
|
+
return minify &&
|
|
491
|
+
(INTERNAL_PROPS.has(key as any) || REF_INTERNAL_PROPS.has(key as any))
|
|
492
|
+
? INTERNAL_PROPS.get(key as any) || REF_INTERNAL_PROPS.get(key as any)
|
|
493
|
+
: key;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function fromMinifiedKey(key: string, minified: boolean) {
|
|
497
|
+
if (!minified) return key;
|
|
498
|
+
return (
|
|
499
|
+
INTERNAL_PROPS_INV.get(key as any) ||
|
|
500
|
+
REF_INTERNAL_PROPS_INV.get(key as any) ||
|
|
501
|
+
key
|
|
502
|
+
);
|
|
503
|
+
}
|
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
|
});
|
package/package.json
CHANGED
package/types.mts
CHANGED
|
@@ -74,11 +74,14 @@ export type Internal =
|
|
|
74
74
|
| "removeNode"
|
|
75
75
|
| "addNode"
|
|
76
76
|
| "clone"
|
|
77
|
+
| "entries"
|
|
77
78
|
| "forEach"
|
|
78
79
|
| "filter"
|
|
79
80
|
| "map"
|
|
80
|
-
| "
|
|
81
|
-
| "
|
|
81
|
+
| "fromJson"
|
|
82
|
+
| "toJson"
|
|
83
|
+
| "toString"
|
|
84
|
+
| "fromString";
|
|
82
85
|
|
|
83
86
|
export type DeeplyPartial<T> = {
|
|
84
87
|
[P in keyof T]?: T[P] extends Array<infer U>
|
|
@@ -100,7 +103,7 @@ export interface DefaultEntries {
|
|
|
100
103
|
refkey?: string | number;
|
|
101
104
|
bskipref?: boolean;
|
|
102
105
|
bpatch?: boolean;
|
|
103
|
-
|
|
106
|
+
isRoot?: boolean;
|
|
104
107
|
isArray?: boolean;
|
|
105
108
|
useAsterisk?: boolean;
|
|
106
109
|
}
|