adofai-lib 1.3.1 → 1.3.2

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.
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import LevelDict from '../LevelDict.js';
4
- const SPECIFIED_LEVEL_PATH = "C:/ADOFAI charts/template.adofai";
4
+ const SPECIFIED_LEVEL_PATH = "C:/Users/Acer_Nitro/Downloads/Team_Wild_Hunt Ice_-_Atohs (DLC Excluded)/level.adofai";
5
5
  describe('LevelDict specified file loader', () => {
6
6
  const runOrSkip = SPECIFIED_LEVEL_PATH ? it : it.skip;
7
7
  runOrSkip('loads and parses specified .adofai file into LevelDict', () => {
@@ -18,7 +18,7 @@ describe('LevelDict specified file loader', () => {
18
18
  // }}))
19
19
  // }}).slice(-40, -1))
20
20
  //console.log(JSON.stringify(levelSlice, null, 2))
21
- console.log(JSON.stringify(level.getTiles(), null, 2));
21
+ //console.log(JSON.stringify(level.getTiles(), null, 2))
22
22
  expect(angles.length).toBeGreaterThan(0);
23
23
  });
24
24
  });
@@ -1 +1 @@
1
- {"version":3,"file":"LocalFileTest.test.js","sourceRoot":"","sources":["../../src/__tests__/LocalFileTest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,SAAS,MAAM,iBAAiB,CAAC;AAGxC,MAAM,oBAAoB,GAAG,kCAAkC,CAAC;AAEhE,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,MAAM,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;IAEtD,SAAS,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACvE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,oBAA8B,CAAC,CAAC;QAElE,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAExC,iGAAiG;QACjG,6MAA6M;QAC7M,uEAAuE;QACvE,wGAAwG;QACxG,WAAW;QACX,0BAA0B;QAC1B,kDAAkD;QAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACtD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"LocalFileTest.test.js","sourceRoot":"","sources":["../../src/__tests__/LocalFileTest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,SAAS,MAAM,iBAAiB,CAAC;AAGxC,MAAM,oBAAoB,GAAG,sFAAsF,CAAC;AAEpH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,MAAM,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;IAEtD,SAAS,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACvE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,oBAA8B,CAAC,CAAC;QAElE,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEzC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAExC,iGAAiG;QACjG,6MAA6M;QAC7M,uEAAuE;QACvE,wGAAwG;QACxG,WAAW;QACX,0BAA0B;QAC1B,kDAAkD;QAClD,wDAAwD;QACxD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=levelUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"levelUtils.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/levelUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import { escapeRawLineBreaksInDoubleQuotedStrings, safeParseJSON } from '../utils/levelUtils.js';
2
+ describe('levelUtils', () => {
3
+ it('escapes raw newlines inside double-quoted strings (EditorComment)', () => {
4
+ const raw = `{
5
+ "pathData": "",
6
+ "settings": { "version": 2, "artist": "", "song": "", "author": "", "difficulty": "", "bpm": 100 },
7
+ "actions": [
8
+ { "floor": 0, "eventType": "EditorComment", "comment": "health
9
+ 100% - 3.7
10
+
11
+ gauge
12
+ 100% - 1.4\\n\\nCLEAR = 20%\\n
13
+ 14 7 10\\n24 32 64"}
14
+ ],
15
+ "decorations": []
16
+ }`;
17
+ const parsed = safeParseJSON(raw);
18
+ expect(parsed.actions[0].comment).toContain('health');
19
+ expect(parsed.actions[0].comment).toContain('100% - 3.7');
20
+ expect(parsed.actions[0].comment).toContain('gauge');
21
+ });
22
+ it('does not treat // inside strings as line comments', () => {
23
+ const raw = `{"pathData": "", "settings": {"bpm": 100}, "actions": [{"floor": 0, "eventType": "EditorComment", "comment": "see // not a comment
24
+ next line"}], "decorations": []}`;
25
+ const parsed = safeParseJSON(raw);
26
+ expect(parsed.actions[0].comment).toBe('see // not a comment\nnext line');
27
+ });
28
+ it('escapeRawLineBreaksInDoubleQuotedStrings leaves structure outside strings unchanged', () => {
29
+ const s = '{\n "a": 1\n}';
30
+ expect(escapeRawLineBreaksInDoubleQuotedStrings(s)).toBe(s);
31
+ });
32
+ });
33
+ //# sourceMappingURL=levelUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"levelUtils.test.js","sourceRoot":"","sources":["../../src/__tests__/levelUtils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wCAAwC,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEjG,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG;;;;;;;;;;;;EAYd,CAAC;QAEC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAA6C,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAG;iCACiB,CAAC;QAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAA6C,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC7F,MAAM,CAAC,GAAG,gBAAgB,CAAC;QAC3B,MAAM,CAAC,wCAAwC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,3 +1,10 @@
1
1
  import { LevelJSON } from '../types/index.js';
2
+ /**
3
+ * The ADOFAI editor can write real line breaks inside double-quoted strings (e.g.
4
+ * EditorComment "comment"). JSON/JSON5 require those to be escaped as \\n, so JSON5.parse
5
+ * fails otherwise. This pass only mutates characters inside "..." strings, and skips
6
+ * JSON5 // and /* *\/ comments so quotes inside comments do not toggle string state.
7
+ */
8
+ export declare function escapeRawLineBreaksInDoubleQuotedStrings(str: string): string;
2
9
  export declare function safeParseJSON(str: string): LevelJSON;
3
10
  //# sourceMappingURL=levelUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"levelUtils.d.ts","sourceRoot":"","sources":["../../src/utils/levelUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAapD"}
1
+ {"version":3,"file":"levelUtils.d.ts","sourceRoot":"","sources":["../../src/utils/levelUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAI9C;;;;;GAKG;AACH,wBAAgB,wCAAwC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyF5E;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAapD"}
@@ -1,8 +1,98 @@
1
1
  import JSON5 from 'json5';
2
+ /**
3
+ * The ADOFAI editor can write real line breaks inside double-quoted strings (e.g.
4
+ * EditorComment "comment"). JSON/JSON5 require those to be escaped as \\n, so JSON5.parse
5
+ * fails otherwise. This pass only mutates characters inside "..." strings, and skips
6
+ * JSON5 // and /* *\/ comments so quotes inside comments do not toggle string state.
7
+ */
8
+ export function escapeRawLineBreaksInDoubleQuotedStrings(str) {
9
+ let out = '';
10
+ let state = 'normal';
11
+ let i = 0;
12
+ let stringEscaped = false;
13
+ while (i < str.length) {
14
+ const c = str[i];
15
+ const next = str[i + 1];
16
+ if (state === 'lineComment') {
17
+ if (c === '\n' || c === '\r') {
18
+ state = 'normal';
19
+ out += c;
20
+ }
21
+ i++;
22
+ continue;
23
+ }
24
+ if (state === 'blockComment') {
25
+ if (c === '*' && next === '/') {
26
+ out += '*/';
27
+ i += 2;
28
+ state = 'normal';
29
+ continue;
30
+ }
31
+ out += c;
32
+ i++;
33
+ continue;
34
+ }
35
+ if (state === 'string') {
36
+ if (stringEscaped) {
37
+ out += c;
38
+ stringEscaped = false;
39
+ i++;
40
+ continue;
41
+ }
42
+ if (c === '\\') {
43
+ out += c;
44
+ stringEscaped = true;
45
+ i++;
46
+ continue;
47
+ }
48
+ if (c === '"') {
49
+ out += c;
50
+ state = 'normal';
51
+ i++;
52
+ continue;
53
+ }
54
+ if (c === '\r') {
55
+ out += '\\n';
56
+ i += next === '\n' ? 2 : 1;
57
+ continue;
58
+ }
59
+ if (c === '\n') {
60
+ out += '\\n';
61
+ i++;
62
+ continue;
63
+ }
64
+ out += c;
65
+ i++;
66
+ continue;
67
+ }
68
+ // normal
69
+ if (c === '/' && next === '/') {
70
+ out += '//';
71
+ i += 2;
72
+ state = 'lineComment';
73
+ continue;
74
+ }
75
+ if (c === '/' && next === '*') {
76
+ out += '/*';
77
+ i += 2;
78
+ state = 'blockComment';
79
+ continue;
80
+ }
81
+ if (c === '"') {
82
+ out += c;
83
+ state = 'string';
84
+ i++;
85
+ continue;
86
+ }
87
+ out += c;
88
+ i++;
89
+ }
90
+ return out;
91
+ }
2
92
  export function safeParseJSON(str) {
3
93
  try {
4
- const cleaned = str
5
- .replace(/\r/g, '') // Remove all carriage returns
94
+ const normalized = str.replace(/\r/g, '');
95
+ const cleaned = escapeRawLineBreaksInDoubleQuotedStrings(normalized)
6
96
  .replace(/,(\s*[}\]])/g, '$1') // Remove trailing commas before closing brackets
7
97
  .replace(/([}\]])[\s\n\t]*([}\]])/g, '$1,$2') // Ensure comma between closing brackets
8
98
  .replace(/([}\]])[\s\n\t]*([{"\[])/g, '$1,$2') // Add comma between any closing brace/bracket and opening brace/bracket
@@ -1 +1 @@
1
- {"version":3,"file":"levelUtils.js","sourceRoot":"","sources":["../../src/utils/levelUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,UAAU,aAAa,CAAC,GAAW;IACrC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,GAAG;aACd,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,8BAA8B;aACjD,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,iDAAiD;aAC/E,OAAO,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC,wCAAwC;aACrF,OAAO,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC,wEAAwE;aACtH,OAAO,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC,+DAA+D;aAC/G,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA,CAAC,uDAAuD;QAC1F,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"levelUtils.js","sourceRoot":"","sources":["../../src/utils/levelUtils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adofai-lib",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "A TypeScript library for advanced manipulation and analysis of ADOFAI level files.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",