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 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 Set([
17
- "__internal__",
18
- "fork",
19
- "removeNode",
20
- "addNode",
21
- "clone",
22
- "forEach",
23
- "filter",
24
- "map",
25
- "toString",
26
- ] satisfies Array<keyof Struct>);
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>(obj: T): T extends object ? GetStructType<T> : 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
- if (key === "__internal__") {
160
- instance[key] = new Refs(value);
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[key] = Struct.fromJson(value);
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[key] = value.toJson();
209
+ obj[nKey] = value.toJson(minify);
176
210
  } else if (value instanceof Refs) {
177
- obj[key] = { ...value };
211
+ obj[nKey] = Object.fromEntries(
212
+ Object.entries(value).map(([k, v]) => [maybeMinifyKey(k, minify), v]),
213
+ );
178
214
  } else {
179
- obj[key] = value;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "s2cfgtojson",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "Converts Stalker 2 Cfg file into POJOs",
5
5
  "keywords": [
6
6
  "stalker",
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
- | "entries"
81
- | "toString";
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
  }