@willwade/aac-processors 0.1.19 → 0.1.21

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.
Files changed (94) hide show
  1. package/dist/browser/core/baseProcessor.js +4 -0
  2. package/dist/browser/processors/applePanelsProcessor.js +24 -31
  3. package/dist/browser/processors/astericsGridProcessor.js +10 -3
  4. package/dist/browser/processors/dotProcessor.js +5 -2
  5. package/dist/browser/processors/gridset/colorUtils.js +354 -0
  6. package/dist/browser/processors/gridset/helpers.js +49 -45
  7. package/dist/browser/processors/gridset/index.js +61 -0
  8. package/dist/browser/processors/gridset/styleHelpers.js +205 -0
  9. package/dist/browser/processors/gridset/symbolExtractor.js +331 -0
  10. package/dist/browser/processors/gridset/symbolSearch.js +248 -0
  11. package/dist/browser/processors/gridset/symbols.js +35 -68
  12. package/dist/browser/processors/gridsetProcessor.js +32 -41
  13. package/dist/browser/processors/obfProcessor.js +53 -45
  14. package/dist/browser/processors/opmlProcessor.js +5 -2
  15. package/dist/browser/processors/snap/helpers.js +49 -45
  16. package/dist/browser/processors/snapProcessor.js +67 -31
  17. package/dist/browser/processors/touchchatProcessor.js +54 -45
  18. package/dist/browser/utilities/analytics/reference/index.js +27 -19
  19. package/dist/browser/utils/io.js +67 -14
  20. package/dist/browser/utils/sqlite.js +6 -8
  21. package/dist/browser/utils/zip.js +45 -43
  22. package/dist/browser/validation/baseValidator.js +5 -0
  23. package/dist/browser/validation/gridsetValidator.js +12 -20
  24. package/dist/browser/validation/obfValidator.js +5 -4
  25. package/dist/browser/validation/snapValidator.js +9 -5
  26. package/dist/browser/validation/touchChatValidator.js +21 -11
  27. package/dist/cli/index.js +10 -15
  28. package/dist/core/baseProcessor.d.ts +7 -7
  29. package/dist/core/baseProcessor.js +4 -0
  30. package/dist/processors/applePanelsProcessor.js +29 -36
  31. package/dist/processors/astericsGridProcessor.js +20 -13
  32. package/dist/processors/dotProcessor.js +10 -7
  33. package/dist/processors/excelProcessor.js +9 -12
  34. package/dist/processors/gridset/helpers.d.ts +9 -11
  35. package/dist/processors/gridset/helpers.js +49 -71
  36. package/dist/processors/gridset/imageDebug.d.ts +3 -5
  37. package/dist/processors/gridset/imageDebug.js +4 -4
  38. package/dist/processors/gridset/password.d.ts +1 -1
  39. package/dist/processors/gridset/symbolExtractor.d.ts +5 -3
  40. package/dist/processors/gridset/symbolExtractor.js +15 -38
  41. package/dist/processors/gridset/symbolSearch.d.ts +3 -2
  42. package/dist/processors/gridset/symbolSearch.js +12 -34
  43. package/dist/processors/gridset/symbols.d.ts +8 -6
  44. package/dist/processors/gridset/symbols.js +34 -67
  45. package/dist/processors/gridset/wordlistHelpers.d.ts +4 -6
  46. package/dist/processors/gridset/wordlistHelpers.js +15 -74
  47. package/dist/processors/gridsetProcessor.js +36 -68
  48. package/dist/processors/obfProcessor.js +58 -73
  49. package/dist/processors/obfsetProcessor.js +2 -2
  50. package/dist/processors/opmlProcessor.js +10 -7
  51. package/dist/processors/snap/helpers.d.ts +8 -8
  52. package/dist/processors/snap/helpers.js +50 -72
  53. package/dist/processors/snapProcessor.js +66 -30
  54. package/dist/processors/touchchatProcessor.js +54 -45
  55. package/dist/utilities/analytics/index.d.ts +3 -2
  56. package/dist/utilities/analytics/index.js +8 -10
  57. package/dist/utilities/analytics/reference/index.d.ts +5 -3
  58. package/dist/utilities/analytics/reference/index.js +26 -18
  59. package/dist/utilities/symbolTools.d.ts +4 -2
  60. package/dist/utilities/symbolTools.js +16 -15
  61. package/dist/utils/io.d.ts +24 -6
  62. package/dist/utils/io.js +64 -14
  63. package/dist/utils/sqlite.d.ts +2 -0
  64. package/dist/utils/sqlite.js +6 -8
  65. package/dist/utils/zip.d.ts +7 -3
  66. package/dist/utils/zip.js +45 -43
  67. package/dist/validation/applePanelsValidator.d.ts +2 -1
  68. package/dist/validation/applePanelsValidator.js +9 -11
  69. package/dist/validation/astericsValidator.d.ts +2 -1
  70. package/dist/validation/astericsValidator.js +5 -4
  71. package/dist/validation/baseValidator.d.ts +2 -2
  72. package/dist/validation/baseValidator.js +5 -0
  73. package/dist/validation/dotValidator.d.ts +2 -1
  74. package/dist/validation/dotValidator.js +5 -4
  75. package/dist/validation/excelValidator.d.ts +2 -1
  76. package/dist/validation/excelValidator.js +5 -4
  77. package/dist/validation/gridsetValidator.d.ts +2 -1
  78. package/dist/validation/gridsetValidator.js +11 -22
  79. package/dist/validation/index.d.ts +2 -2
  80. package/dist/validation/index.js +5 -4
  81. package/dist/validation/obfValidator.d.ts +2 -1
  82. package/dist/validation/obfValidator.js +5 -4
  83. package/dist/validation/obfsetValidator.d.ts +2 -1
  84. package/dist/validation/obfsetValidator.js +5 -4
  85. package/dist/validation/opmlValidator.d.ts +2 -1
  86. package/dist/validation/opmlValidator.js +5 -4
  87. package/dist/validation/snapValidator.d.ts +2 -1
  88. package/dist/validation/snapValidator.js +9 -5
  89. package/dist/validation/touchChatValidator.d.ts +4 -6
  90. package/dist/validation/touchChatValidator.js +21 -11
  91. package/dist/validation/validationTypes.d.ts +8 -1
  92. package/package.json +1 -1
  93. package/dist/core/fileProcessor.d.ts +0 -7
  94. package/dist/core/fileProcessor.js +0 -52
@@ -1,21 +1,18 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.TouchChatSymbolResolver = exports.TouchChatSymbolExtractor = exports.Grid3SymbolResolver = exports.Grid3SymbolExtractor = exports.SnapSymbolResolver = exports.SnapSymbolExtractor = exports.SymbolResolver = exports.SymbolExtractor = void 0;
7
4
  exports.resolveSymbol = resolveSymbol;
8
- const path_1 = __importDefault(require("path"));
9
- const fs_1 = __importDefault(require("fs"));
10
5
  const symbols_1 = require("../processors/gridset/symbols");
6
+ const io_1 = require("../utils/io");
11
7
  // --- Base Classes ---
12
8
  class SymbolExtractor {
13
9
  }
14
10
  exports.SymbolExtractor = SymbolExtractor;
15
11
  class SymbolResolver {
16
- constructor(symbolPath, dbPath) {
12
+ constructor(symbolPath, dbPath, fileAdapter = io_1.defaultFileAdapter) {
17
13
  this.symbolPath = symbolPath;
18
14
  this.dbPath = dbPath;
15
+ this.fileAdapter = fileAdapter;
19
16
  }
20
17
  }
21
18
  exports.SymbolResolver = SymbolResolver;
@@ -43,6 +40,7 @@ class SnapSymbolExtractor extends SymbolExtractor {
43
40
  exports.SnapSymbolExtractor = SnapSymbolExtractor;
44
41
  class SnapSymbolResolver extends SymbolResolver {
45
42
  resolveSymbol(symbolRef) {
43
+ const { join, writeBinaryToPath } = this.fileAdapter;
46
44
  if (!Database)
47
45
  throw new Error('better-sqlite3 not installed');
48
46
  const db = new Database(this.dbPath, { readonly: true });
@@ -51,8 +49,8 @@ class SnapSymbolResolver extends SymbolResolver {
51
49
  db.close();
52
50
  if (!row)
53
51
  return null;
54
- const outPath = path_1.default.join(this.symbolPath, `${symbolRef}.png`);
55
- fs_1.default.writeFileSync(outPath, row.ImageData);
52
+ const outPath = join(this.symbolPath, `${symbolRef}.png`);
53
+ writeBinaryToPath(outPath, row.ImageData);
56
54
  return outPath;
57
55
  }
58
56
  }
@@ -89,9 +87,10 @@ class Grid3SymbolExtractor extends SymbolExtractor {
89
87
  exports.Grid3SymbolExtractor = Grid3SymbolExtractor;
90
88
  class Grid3SymbolResolver extends SymbolResolver {
91
89
  resolveSymbol(symbolRef) {
90
+ const { join, pathExists } = this.fileAdapter;
92
91
  // Implementation depends on Grid 3 symbol storage format
93
- const symbolPath = path_1.default.join(this.symbolPath, symbolRef);
94
- return fs_1.default.existsSync(symbolPath) ? symbolPath : null;
92
+ const symbolPath = join(this.symbolPath, symbolRef);
93
+ return pathExists(symbolPath) ? symbolPath : null;
95
94
  }
96
95
  }
97
96
  exports.Grid3SymbolResolver = Grid3SymbolResolver;
@@ -105,19 +104,21 @@ class TouchChatSymbolExtractor extends SymbolExtractor {
105
104
  exports.TouchChatSymbolExtractor = TouchChatSymbolExtractor;
106
105
  class TouchChatSymbolResolver extends SymbolResolver {
107
106
  resolveSymbol(symbolRef) {
107
+ const { join, pathExists } = this.fileAdapter;
108
108
  // Implementation depends on TouchChat symbol storage format
109
- const symbolPath = path_1.default.join(this.symbolPath, symbolRef);
110
- return fs_1.default.existsSync(symbolPath) ? symbolPath : null;
109
+ const symbolPath = join(this.symbolPath, symbolRef);
110
+ return pathExists(symbolPath) ? symbolPath : null;
111
111
  }
112
112
  }
113
113
  exports.TouchChatSymbolResolver = TouchChatSymbolResolver;
114
114
  // --- Simple fallback function for PCS-style lookup ---
115
- function resolveSymbol(label, symbolDir) {
115
+ function resolveSymbol(label, symbolDir, fileAdapter = io_1.defaultFileAdapter) {
116
+ const { join, pathExists } = fileAdapter;
116
117
  const cleanLabel = label.toLowerCase().replace(/[^a-z0-9]/g, '');
117
118
  const exts = ['.png', '.jpg', '.svg'];
118
119
  for (const ext of exts) {
119
- const symbolPath = path_1.default.join(symbolDir, cleanLabel + ext);
120
- if (fs_1.default.existsSync(symbolPath)) {
120
+ const symbolPath = join(symbolDir, cleanLabel + ext);
121
+ if (pathExists(symbolPath)) {
121
122
  return symbolPath;
122
123
  }
123
124
  }
@@ -1,9 +1,28 @@
1
1
  export type ProcessorInput = string | Buffer | ArrayBuffer | Uint8Array;
2
2
  export type BinaryOutput = Buffer | Uint8Array;
3
+ export interface FileAdapter {
4
+ readBinaryFromInput: (input: ProcessorInput) => Uint8Array;
5
+ readTextFromInput: (input: ProcessorInput, encoding?: BufferEncoding) => string;
6
+ writeBinaryToPath: (outputPath: string, data: BinaryOutput) => void;
7
+ writeTextToPath: (outputPath: string, text: string) => void;
8
+ pathExists: (path: string) => boolean;
9
+ isDirectory: (path: string) => boolean;
10
+ getFileSize: (path: string) => number;
11
+ mkDir: (path: string, options?: {
12
+ recursive?: boolean;
13
+ }) => void;
14
+ listDir: (path: string) => string[];
15
+ removePath: (path: string, options?: {
16
+ recursive?: boolean;
17
+ force?: boolean;
18
+ }) => void;
19
+ mkTempDir: (prefix: string) => string;
20
+ join: (...pathParts: string[]) => string;
21
+ dirname: (path: string) => string;
22
+ basename: (path: string, suffix?: string) => string;
23
+ }
3
24
  type NodeRequire = (id: string) => any;
4
25
  export declare function getNodeRequire(): NodeRequire;
5
- export declare function getFs(): typeof import('fs');
6
- export declare function getPath(): typeof import('path');
7
26
  export declare function getOs(): typeof import('os');
8
27
  export declare function isNodeRuntime(): boolean;
9
28
  export declare function getBasename(filePath: string): string;
@@ -12,8 +31,7 @@ export declare function toArrayBuffer(input: Uint8Array | ArrayBuffer | Buffer):
12
31
  export declare function decodeText(input: Uint8Array): string;
13
32
  export declare function encodeBase64(input: Uint8Array): string;
14
33
  export declare function encodeText(text: string): BinaryOutput;
15
- export declare function readBinaryFromInput(input: ProcessorInput): Uint8Array;
16
- export declare function readTextFromInput(input: ProcessorInput, encoding?: BufferEncoding): string;
17
- export declare function writeBinaryToPath(outputPath: string, data: BinaryOutput): void;
18
- export declare function writeTextToPath(outputPath: string, text: string): void;
34
+ export declare function extname(path: string): string;
35
+ export declare function joinWin32(...pathParts: string[]): string;
36
+ export declare const defaultFileAdapter: FileAdapter;
19
37
  export {};
package/dist/utils/io.js CHANGED
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultFileAdapter = void 0;
3
4
  exports.getNodeRequire = getNodeRequire;
4
- exports.getFs = getFs;
5
- exports.getPath = getPath;
6
5
  exports.getOs = getOs;
7
6
  exports.isNodeRuntime = isNodeRuntime;
8
7
  exports.getBasename = getBasename;
@@ -11,10 +10,8 @@ exports.toArrayBuffer = toArrayBuffer;
11
10
  exports.decodeText = decodeText;
12
11
  exports.encodeBase64 = encodeBase64;
13
12
  exports.encodeText = encodeText;
14
- exports.readBinaryFromInput = readBinaryFromInput;
15
- exports.readTextFromInput = readTextFromInput;
16
- exports.writeBinaryToPath = writeBinaryToPath;
17
- exports.writeTextToPath = writeTextToPath;
13
+ exports.extname = extname;
14
+ exports.joinWin32 = joinWin32;
18
15
  let cachedFs = null;
19
16
  let cachedPath = null;
20
17
  let cachedOs = null;
@@ -131,10 +128,16 @@ function encodeText(text) {
131
128
  }
132
129
  return new TextEncoder().encode(text);
133
130
  }
131
+ // extname algorithm from node:path
132
+ const splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; //eslint-disable-line
133
+ const splitTailRe = /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; //eslint-disable-line
134
+ function extname(path) {
135
+ const tail = splitDeviceRe.exec(path)?.at(3) ?? '';
136
+ return splitTailRe.exec(tail)?.at(3) ?? '';
137
+ }
134
138
  function readBinaryFromInput(input) {
135
139
  if (typeof input === 'string') {
136
- const fs = getFs();
137
- return fs.readFileSync(input);
140
+ return getFs().readFileSync(input);
138
141
  }
139
142
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
140
143
  return input;
@@ -146,8 +149,7 @@ function readBinaryFromInput(input) {
146
149
  }
147
150
  function readTextFromInput(input, encoding = 'utf8') {
148
151
  if (typeof input === 'string') {
149
- const fs = getFs();
150
- return fs.readFileSync(input, encoding);
152
+ return getFs().readFileSync(input, encoding);
151
153
  }
152
154
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
153
155
  return input.toString(encoding);
@@ -158,10 +160,58 @@ function readTextFromInput(input, encoding = 'utf8') {
158
160
  return decodeText(input);
159
161
  }
160
162
  function writeBinaryToPath(outputPath, data) {
161
- const fs = getFs();
162
- fs.writeFileSync(outputPath, data);
163
+ getFs().writeFileSync(outputPath, data);
163
164
  }
164
165
  function writeTextToPath(outputPath, text) {
165
- const fs = getFs();
166
- fs.writeFileSync(outputPath, text, 'utf8');
166
+ getFs().writeFileSync(outputPath, text, 'utf8');
167
+ }
168
+ function pathExists(path) {
169
+ return getFs().existsSync(path);
170
+ }
171
+ function isDirectory(path) {
172
+ return getFs().statSync(path).isDirectory();
173
+ }
174
+ function getFileSize(path) {
175
+ return getFs().statSync(path).size;
176
+ }
177
+ function mkDir(path, options) {
178
+ getFs().mkdirSync(path, options);
179
+ }
180
+ function listDir(path) {
181
+ return getFs().readdirSync(path);
182
+ }
183
+ function removePath(path, options) {
184
+ getFs().rmSync(path, options);
185
+ }
186
+ function mkTempDir(prefix) {
187
+ const path = join(getOs().tmpdir(), prefix);
188
+ return getFs().mkdtempSync(path);
189
+ }
190
+ function join(...pathParts) {
191
+ return getPath().join(...pathParts);
192
+ }
193
+ function joinWin32(...pathParts) {
194
+ return getPath().win32.join(...pathParts);
195
+ }
196
+ function dirname(path) {
197
+ return getPath().dirname(path);
198
+ }
199
+ function basename(path, suffix) {
200
+ return getPath().basename(path, suffix);
167
201
  }
202
+ exports.defaultFileAdapter = {
203
+ readBinaryFromInput,
204
+ readTextFromInput,
205
+ writeBinaryToPath,
206
+ writeTextToPath,
207
+ pathExists,
208
+ isDirectory,
209
+ getFileSize,
210
+ mkDir,
211
+ listDir,
212
+ removePath,
213
+ mkTempDir,
214
+ join,
215
+ dirname,
216
+ basename,
217
+ };
@@ -1,4 +1,5 @@
1
1
  import type { SqlJsConfig } from 'sql.js';
2
+ import { FileAdapter } from './io';
2
3
  export interface SqliteStatementAdapter {
3
4
  all(...params: unknown[]): any[];
4
5
  get(...params: unknown[]): any;
@@ -11,6 +12,7 @@ export interface SqliteDatabaseAdapter {
11
12
  }
12
13
  export interface SqliteOpenOptions {
13
14
  readonly?: boolean;
15
+ fileAdapter?: FileAdapter;
14
16
  }
15
17
  export interface SqliteOpenResult {
16
18
  db: SqliteDatabaseAdapter;
@@ -98,6 +98,7 @@ function requireBetterSqlite3() {
98
98
  return getBetterSqlite3();
99
99
  }
100
100
  async function openSqliteDatabase(input, options = {}) {
101
+ const { readBinaryFromInput, mkTempDir, writeBinaryToPath, removePath, join } = options.fileAdapter ?? io_1.defaultFileAdapter;
101
102
  if (typeof input === 'string') {
102
103
  if (!(0, io_1.isNodeRuntime)()) {
103
104
  throw new Error('SQLite file paths are not supported in browser environments.');
@@ -106,18 +107,15 @@ async function openSqliteDatabase(input, options = {}) {
106
107
  const db = new Database(input, { readonly: options.readonly ?? true });
107
108
  return { db };
108
109
  }
109
- const data = (0, io_1.readBinaryFromInput)(input);
110
+ const data = readBinaryFromInput(input);
110
111
  if (!(0, io_1.isNodeRuntime)()) {
111
112
  const SQL = await getSqlJs();
112
113
  const db = new SQL.Database(data);
113
114
  return { db: createSqlJsAdapter(db) };
114
115
  }
115
- const fs = (0, io_1.getFs)();
116
- const path = (0, io_1.getPath)();
117
- const os = (0, io_1.getOs)();
118
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aac-sqlite-'));
119
- const dbPath = path.join(tempDir, 'input.sqlite');
120
- fs.writeFileSync(dbPath, data);
116
+ const tempDir = mkTempDir('aac-sqlite-');
117
+ const dbPath = join(tempDir, 'input.sqlite');
118
+ writeBinaryToPath(dbPath, data);
121
119
  const Database = getBetterSqlite3();
122
120
  const db = new Database(dbPath, { readonly: options.readonly ?? true });
123
121
  const cleanup = () => {
@@ -126,7 +124,7 @@ async function openSqliteDatabase(input, options = {}) {
126
124
  }
127
125
  finally {
128
126
  try {
129
- fs.rmSync(tempDir, { recursive: true, force: true });
127
+ removePath(tempDir, { recursive: true, force: true });
130
128
  }
131
129
  catch (error) {
132
130
  console.warn('Failed to clean up temporary SQLite files:', error);
@@ -1,7 +1,11 @@
1
+ import { ProcessorInput, FileAdapter } from './io';
1
2
  export interface ZipAdapter {
2
3
  listFiles(): string[];
3
4
  readFile(name: string): Promise<Uint8Array>;
5
+ writeFiles(files: ZipFile[]): Promise<Uint8Array>;
4
6
  }
5
- export declare function openZipFromInput(input: string | Uint8Array | ArrayBuffer | Buffer): Promise<{
6
- zip: ZipAdapter;
7
- }>;
7
+ export interface ZipFile {
8
+ name: string;
9
+ data: string | Uint8Array;
10
+ }
11
+ export declare function getZipAdapter(input?: ProcessorInput, fileAdapter?: FileAdapter): Promise<ZipAdapter>;
package/dist/utils/zip.js CHANGED
@@ -23,58 +23,60 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.openZipFromInput = openZipFromInput;
26
+ exports.getZipAdapter = getZipAdapter;
27
27
  const io_1 = require("./io");
28
- async function openZipFromInput(input) {
29
- if (typeof input === 'string') {
30
- if (!(0, io_1.isNodeRuntime)()) {
31
- throw new Error('Zip file paths are not supported in browser environments.');
32
- }
33
- const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
34
- const admZip = new AdmZip(input);
35
- return {
36
- zip: {
37
- listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
38
- readFile: (name) => {
39
- const entry = admZip.getEntry(name);
40
- if (!entry) {
41
- throw new Error(`Zip entry not found: ${name}`);
42
- }
43
- return Promise.resolve(entry.getData());
44
- },
45
- },
46
- };
47
- }
48
- const data = (0, io_1.readBinaryFromInput)(input);
28
+ async function getZipAdapter(input, fileAdapter) {
29
+ const adapter = fileAdapter ?? io_1.defaultFileAdapter;
49
30
  if ((0, io_1.isNodeRuntime)()) {
50
31
  const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
51
- const admZip = new AdmZip(Buffer.from(data));
32
+ const zip = input === undefined
33
+ ? new AdmZip(input)
34
+ : typeof input === 'string'
35
+ ? new AdmZip(input)
36
+ : new AdmZip(Buffer.from(adapter.readBinaryFromInput(input)));
52
37
  return {
53
- zip: {
54
- listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
55
- readFile: (name) => {
56
- const entry = admZip.getEntry(name);
57
- if (!entry) {
58
- throw new Error(`Zip entry not found: ${name}`);
59
- }
60
- return Promise.resolve(entry.getData());
61
- },
38
+ listFiles: () => {
39
+ return zip
40
+ .getEntries()
41
+ .filter((entry) => !entry.isDirectory)
42
+ .map((entry) => entry.entryName);
43
+ },
44
+ readFile: (name) => {
45
+ const entry = zip.getEntry(name);
46
+ if (!entry)
47
+ throw new Error(`Zip entry not found: ${name}`);
48
+ return Promise.resolve(entry.getData());
49
+ },
50
+ writeFiles: (files) => {
51
+ files.forEach((file) => {
52
+ zip.addFile(file.name, Buffer.from(file.data));
53
+ });
54
+ return Promise.resolve(zip.toBuffer());
62
55
  },
63
56
  };
64
57
  }
65
58
  const module = await Promise.resolve().then(() => __importStar(require('jszip')));
66
- const init = module.default || module;
67
- const zip = await init.loadAsync(data);
59
+ const JSZip = module.default || module;
60
+ if (input !== undefined && typeof input === 'string')
61
+ throw new Error('Zip file paths are not supported in browser environments.');
62
+ const zip = input ? await JSZip.loadAsync(adapter.readBinaryFromInput(input)) : new JSZip();
68
63
  return {
69
- zip: {
70
- listFiles: () => Object.keys(zip.files),
71
- readFile: async (name) => {
72
- const file = zip.file(name);
73
- if (!file) {
74
- throw new Error(`Zip entry not found: ${name}`);
75
- }
76
- return file.async('uint8array');
77
- },
64
+ listFiles: () => {
65
+ return Object.entries(zip.files)
66
+ .filter(([_, entry]) => !entry.dir)
67
+ .map(([name, _]) => name);
68
+ },
69
+ readFile: async (name) => {
70
+ const file = zip.file(name);
71
+ if (!file)
72
+ throw new Error(`Zip entry not found: ${name}`);
73
+ return file.async('uint8array');
74
+ },
75
+ writeFiles: async (files) => {
76
+ files.forEach((file) => {
77
+ zip.file(file.name, file.data);
78
+ });
79
+ return await zip.generateAsync({ type: 'uint8array' });
78
80
  },
79
81
  };
80
82
  }
@@ -1,10 +1,11 @@
1
1
  import { BaseValidator } from './baseValidator';
2
2
  import { ValidationResult } from './validationTypes';
3
+ import { FileAdapter } from '../utils/io';
3
4
  /**
4
5
  * Validator for Apple Panels (.plist or .ascconfig directory)
5
6
  */
6
7
  export declare class ApplePanelsValidator extends BaseValidator {
7
- static validateFile(filePath: string): Promise<ValidationResult>;
8
+ static validateFile(filePath: string, fileAdapter?: FileAdapter): Promise<ValidationResult>;
8
9
  static identifyFormat(content: any, filename: string): Promise<boolean>;
9
10
  validate(content: Buffer | Uint8Array, filename: string, filesize: number): Promise<ValidationResult>;
10
11
  }
@@ -12,25 +12,23 @@ const io_1 = require("../utils/io");
12
12
  * Validator for Apple Panels (.plist or .ascconfig directory)
13
13
  */
14
14
  class ApplePanelsValidator extends baseValidator_1.BaseValidator {
15
- static async validateFile(filePath) {
15
+ static async validateFile(filePath, fileAdapter = io_1.defaultFileAdapter) {
16
+ const { pathExists, isDirectory, getFileSize, readBinaryFromInput, join } = fileAdapter;
16
17
  const validator = new ApplePanelsValidator();
17
- const fs = (0, io_1.getFs)();
18
- const path = (0, io_1.getPath)();
19
18
  let content;
20
19
  const filename = (0, io_1.getBasename)(filePath);
21
20
  let size = 0;
22
- const stats = fs.existsSync(filePath) ? fs.statSync(filePath) : null;
23
- if (stats?.isDirectory() && filename.toLowerCase().endsWith('.ascconfig')) {
24
- const panelPath = path.join(filePath, 'Contents', 'Resources', 'PanelDefinitions.plist');
25
- if (!fs.existsSync(panelPath)) {
21
+ if (isDirectory(filePath) && filename.toLowerCase().endsWith('.ascconfig')) {
22
+ const panelPath = join(filePath, 'Contents', 'Resources', 'PanelDefinitions.plist');
23
+ if (!pathExists(panelPath)) {
26
24
  return validator.validate(Buffer.alloc(0), filename, 0);
27
25
  }
28
- content = fs.readFileSync(panelPath);
29
- size = fs.statSync(panelPath).size;
26
+ content = readBinaryFromInput(panelPath);
27
+ size = getFileSize(panelPath);
30
28
  }
31
29
  else {
32
- content = fs.readFileSync(filePath);
33
- size = stats?.size || content.byteLength;
30
+ content = readBinaryFromInput(filePath);
31
+ size = getFileSize(filePath) || content.byteLength;
34
32
  }
35
33
  return validator.validate(content, filename, size);
36
34
  }
@@ -1,5 +1,6 @@
1
1
  import { BaseValidator } from './baseValidator';
2
2
  import { ValidationResult } from './validationTypes';
3
+ import { FileAdapter } from '../utils/io';
3
4
  /**
4
5
  * Validator for Asterics Grid (.grd) JSON files
5
6
  */
@@ -7,7 +8,7 @@ export declare class AstericsGridValidator extends BaseValidator {
7
8
  /**
8
9
  * Validate from disk
9
10
  */
10
- static validateFile(filePath: string): Promise<ValidationResult>;
11
+ static validateFile(filePath: string, fileAdapter?: FileAdapter): Promise<ValidationResult>;
11
12
  /**
12
13
  * Identify whether the content appears to be an Asterics .grd file
13
14
  */
@@ -11,11 +11,12 @@ class AstericsGridValidator extends baseValidator_1.BaseValidator {
11
11
  /**
12
12
  * Validate from disk
13
13
  */
14
- static async validateFile(filePath) {
14
+ static async validateFile(filePath, fileAdapter) {
15
+ const { readBinaryFromInput, getFileSize } = fileAdapter ?? io_1.defaultFileAdapter;
15
16
  const validator = new AstericsGridValidator();
16
- const content = (0, io_1.readBinaryFromInput)(filePath);
17
- const stats = (0, io_1.getFs)().statSync(filePath);
18
- return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
17
+ const content = readBinaryFromInput(filePath);
18
+ const size = getFileSize(filePath);
19
+ return validator.validate(content, (0, io_1.getBasename)(filePath), size);
19
20
  }
20
21
  /**
21
22
  * Identify whether the content appears to be an Asterics .grd file
@@ -1,4 +1,4 @@
1
- import { ValidationResult, ValidationCheck, ValidationOptions } from './validationTypes';
1
+ import { ValidationResult, ValidationCheck, ValidationOptions, ValidationConfig } from './validationTypes';
2
2
  /**
3
3
  * Base class for all format validators
4
4
  * Provides the check-based validation system
@@ -9,7 +9,7 @@ export declare abstract class BaseValidator {
9
9
  protected _checks: ValidationCheck[];
10
10
  protected _sub_checks: ValidationResult[];
11
11
  protected _blocked: boolean;
12
- protected _options: ValidationOptions;
12
+ protected _options: ValidationConfig;
13
13
  constructor(options?: ValidationOptions);
14
14
  /**
15
15
  * Reset validator state
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseValidator = void 0;
4
+ const io_1 = require("../utils/io");
5
+ const zip_1 = require("../utils/zip");
4
6
  const validationTypes_1 = require("./validationTypes");
5
7
  /**
6
8
  * Base class for all format validators
@@ -17,6 +19,9 @@ class BaseValidator {
17
19
  includeWarnings: options.includeWarnings ?? true,
18
20
  stopOnBlocker: options.stopOnBlocker ?? true,
19
21
  customRules: options.customRules || [],
22
+ fileAdapter: io_1.defaultFileAdapter,
23
+ zipAdapter: zip_1.getZipAdapter,
24
+ ...options,
20
25
  };
21
26
  this.reset();
22
27
  }
@@ -1,10 +1,11 @@
1
1
  import { BaseValidator } from './baseValidator';
2
2
  import { ValidationResult } from './validationTypes';
3
+ import { FileAdapter } from '../utils/io';
3
4
  /**
4
5
  * Validator for Graphviz DOT files
5
6
  */
6
7
  export declare class DotValidator extends BaseValidator {
7
- static validateFile(filePath: string): Promise<ValidationResult>;
8
+ static validateFile(filePath: string, fileAdapter?: FileAdapter): Promise<ValidationResult>;
8
9
  static identifyFormat(content: any, filename: string): Promise<boolean>;
9
10
  validate(content: Buffer | Uint8Array, filename: string, filesize: number): Promise<ValidationResult>;
10
11
  }
@@ -8,11 +8,12 @@ const io_1 = require("../utils/io");
8
8
  * Validator for Graphviz DOT files
9
9
  */
10
10
  class DotValidator extends baseValidator_1.BaseValidator {
11
- static async validateFile(filePath) {
11
+ static async validateFile(filePath, fileAdapter) {
12
+ const { readBinaryFromInput, getFileSize } = fileAdapter ?? io_1.defaultFileAdapter;
12
13
  const validator = new DotValidator();
13
- const content = (0, io_1.readBinaryFromInput)(filePath);
14
- const stats = (0, io_1.getFs)().statSync(filePath);
15
- return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
14
+ const content = readBinaryFromInput(filePath);
15
+ const size = getFileSize(filePath);
16
+ return validator.validate(content, (0, io_1.getBasename)(filePath), size);
16
17
  }
17
18
  static async identifyFormat(content, filename) {
18
19
  const name = filename.toLowerCase();
@@ -1,10 +1,11 @@
1
1
  import { BaseValidator } from './baseValidator';
2
2
  import { ValidationResult } from './validationTypes';
3
+ import { FileAdapter } from '../utils/io';
3
4
  /**
4
5
  * Validator for Excel imports (.xlsx/.xls)
5
6
  */
6
7
  export declare class ExcelValidator extends BaseValidator {
7
- static validateFile(filePath: string): Promise<ValidationResult>;
8
+ static validateFile(filePath: string, fileAdapter?: FileAdapter): Promise<ValidationResult>;
8
9
  static identifyFormat(_content: any, filename: string): Promise<boolean>;
9
10
  validate(content: Buffer | Uint8Array, filename: string, filesize: number): Promise<ValidationResult>;
10
11
  }
@@ -32,11 +32,12 @@ const io_1 = require("../utils/io");
32
32
  * Validator for Excel imports (.xlsx/.xls)
33
33
  */
34
34
  class ExcelValidator extends baseValidator_1.BaseValidator {
35
- static async validateFile(filePath) {
35
+ static async validateFile(filePath, fileAdapter) {
36
+ const { readBinaryFromInput, getFileSize } = fileAdapter ?? io_1.defaultFileAdapter;
36
37
  const validator = new ExcelValidator();
37
- const content = (0, io_1.readBinaryFromInput)(filePath);
38
- const stats = (0, io_1.getFs)().statSync(filePath);
39
- return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
38
+ const content = readBinaryFromInput(filePath);
39
+ const size = getFileSize(filePath);
40
+ return validator.validate(content, (0, io_1.getBasename)(filePath), size);
40
41
  }
41
42
  static async identifyFormat(_content, filename) {
42
43
  const name = filename.toLowerCase();
@@ -1,5 +1,6 @@
1
1
  import { BaseValidator } from './baseValidator';
2
2
  import { ValidationResult } from './validationTypes';
3
+ import { FileAdapter } from '../utils/io';
3
4
  /**
4
5
  * Validator for Grid3/Smartbox Gridset files (.gridset, .gridsetx)
5
6
  */
@@ -8,7 +9,7 @@ export declare class GridsetValidator extends BaseValidator {
8
9
  /**
9
10
  * Validate a Gridset file from disk
10
11
  */
11
- static validateFile(filePath: string): Promise<ValidationResult>;
12
+ static validateFile(filePath: string, fileAdapter?: FileAdapter): Promise<ValidationResult>;
12
13
  /**
13
14
  * Check if content is Gridset format
14
15
  */