@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,30 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
2
  Object.defineProperty(exports, "__esModule", { value: true });
29
3
  exports.getPageTokenImageMap = getPageTokenImageMap;
30
4
  exports.getAllowedImageEntries = getAllowedImageEntries;
@@ -44,13 +18,11 @@ exports.readGrid3HistoryForUser = readGrid3HistoryForUser;
44
18
  exports.readAllGrid3History = readAllGrid3History;
45
19
  const fast_xml_parser_1 = require("fast-xml-parser");
46
20
  const treeStructure_1 = require("../../core/treeStructure");
47
- const fs = __importStar(require("fs"));
48
- const path = __importStar(require("path"));
49
- const child_process_1 = require("child_process");
50
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
51
21
  const dotnetTicks_1 = require("../../utils/dotnetTicks");
52
22
  const password_1 = require("./password");
23
+ const io_1 = require("../../utils/io");
53
24
  const zip_1 = require("../../utils/zip");
25
+ const sqlite_1 = require("../../utils/sqlite");
54
26
  function normalizeZipPath(p) {
55
27
  const unified = p.replace(/\\/g, '/');
56
28
  try {
@@ -96,11 +68,11 @@ function getAllowedImageEntries(tree) {
96
68
  * @param entryPath Entry name inside the zip
97
69
  * @returns Image data buffer or null if not found
98
70
  */
99
- async function openImage(gridsetBuffer, entryPath, password = (0, password_1.resolveGridsetPasswordFromEnv)(), zipAdapter) {
71
+ async function openImage(gridsetBuffer, entryPath, password = (0, password_1.resolveGridsetPasswordFromEnv)(), fileAdapter = io_1.defaultFileAdapter, zipAdapter) {
100
72
  try {
101
- const { zip } = zipAdapter
73
+ const zip = zipAdapter
102
74
  ? await zipAdapter(gridsetBuffer)
103
- : await (0, zip_1.openZipFromInput)(gridsetBuffer);
75
+ : await (0, zip_1.getZipAdapter)(gridsetBuffer, fileAdapter);
104
76
  const entries = (0, password_1.getZipEntriesFromAdapter)(zip, password);
105
77
  const want = normalizeZipPath(entryPath);
106
78
  const entry = entries.find((e) => normalizeZipPath(e.entryName) === want);
@@ -193,8 +165,9 @@ function getCommonDocumentsPath() {
193
165
  }
194
166
  try {
195
167
  // Query registry for Common Documents path
168
+ const child_process = (0, io_1.getNodeRequire)()('child_process');
196
169
  const command = 'REG.EXE QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders" /V "Common Documents"';
197
- const output = (0, child_process_1.execSync)(command, { encoding: 'utf-8', windowsHide: true });
170
+ const output = child_process.execSync(command, { encoding: 'utf-8', windowsHide: true });
198
171
  // Parse the output to extract the path
199
172
  const match = output.match(/Common Documents\s+REG_SZ\s+(.+)/);
200
173
  if (match && match[1]) {
@@ -215,7 +188,8 @@ function getCommonDocumentsPath() {
215
188
  * C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
216
189
  * @returns Array of Grid3 user path information
217
190
  */
218
- function findGrid3UserPaths() {
191
+ function findGrid3UserPaths(fileAdapter = io_1.defaultFileAdapter) {
192
+ const { pathExists, listDir, isDirectory } = fileAdapter;
219
193
  const results = [];
220
194
  // Only works on Windows
221
195
  if (process.platform !== 'win32') {
@@ -224,28 +198,28 @@ function findGrid3UserPaths() {
224
198
  try {
225
199
  const commonDocs = getCommonDocumentsPath();
226
200
  // Use Windows path joining so tests that mock a Windows platform stay consistent even on POSIX runners
227
- const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
201
+ const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
228
202
  // Check if Grid3 Users directory exists
229
- if (!fs.existsSync(grid3BasePath)) {
203
+ if (!pathExists(grid3BasePath)) {
230
204
  return results;
231
205
  }
232
206
  // Enumerate users
233
- const users = fs.readdirSync(grid3BasePath, { withFileTypes: true });
207
+ const users = listDir(grid3BasePath);
234
208
  for (const userDir of users) {
235
- if (!userDir.isDirectory())
209
+ if (!isDirectory(userDir))
236
210
  continue;
237
- const userName = userDir.name;
238
- const userPath = path.win32.join(grid3BasePath, userName);
211
+ const userName = userDir;
212
+ const userPath = (0, io_1.joinWin32)(grid3BasePath, userName);
239
213
  // Enumerate language codes
240
- const langDirs = fs.readdirSync(userPath, { withFileTypes: true });
214
+ const langDirs = listDir(userPath);
241
215
  for (const langDir of langDirs) {
242
- if (!langDir.isDirectory())
216
+ if (!isDirectory(langDir))
243
217
  continue;
244
- const langCode = langDir.name;
245
- const basePath = path.win32.join(userPath, langCode);
246
- const historyDbPath = path.win32.join(basePath, 'Phrases', 'history.sqlite');
218
+ const langCode = langDir;
219
+ const basePath = (0, io_1.joinWin32)(userPath, langCode);
220
+ const historyDbPath = (0, io_1.joinWin32)(basePath, 'Phrases', 'history.sqlite');
247
221
  // Only include if history database exists
248
- if (fs.existsSync(historyDbPath)) {
222
+ if (pathExists(historyDbPath)) {
249
223
  results.push({
250
224
  userName,
251
225
  langCode,
@@ -266,8 +240,8 @@ function findGrid3UserPaths() {
266
240
  * Convenience method that returns just the database file paths
267
241
  * @returns Array of paths to history.sqlite files
268
242
  */
269
- function findGrid3HistoryDatabases() {
270
- return findGrid3UserPaths().map((userPath) => userPath.historyDbPath);
243
+ function findGrid3HistoryDatabases(fileAdapter) {
244
+ return findGrid3UserPaths(fileAdapter).map((userPath) => userPath.historyDbPath);
271
245
  }
272
246
  /**
273
247
  * Get Grid 3 users (alias of findGrid3UserPaths for clarity)
@@ -280,36 +254,37 @@ function findGrid3Users() {
280
254
  * @param userName Optional user filter; matches case-insensitively
281
255
  * @returns Array of user/gridset path pairs
282
256
  */
283
- function findGrid3Vocabularies(userName) {
257
+ function findGrid3Vocabularies(userName, fileAdapter = io_1.defaultFileAdapter) {
258
+ const { pathExists, listDir, isDirectory } = fileAdapter;
284
259
  const results = [];
285
260
  if (process.platform !== 'win32') {
286
261
  return results;
287
262
  }
288
263
  const commonDocs = getCommonDocumentsPath();
289
- const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
290
- if (!fs.existsSync(grid3BasePath)) {
264
+ const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
265
+ if (!pathExists(grid3BasePath)) {
291
266
  return results;
292
267
  }
293
268
  const normalizedUser = userName?.toLowerCase();
294
- const users = fs.readdirSync(grid3BasePath, { withFileTypes: true });
269
+ const users = listDir(grid3BasePath);
295
270
  for (const userDir of users) {
296
- if (!userDir.isDirectory())
271
+ if (!isDirectory(userDir))
297
272
  continue;
298
- if (normalizedUser && userDir.name.toLowerCase() !== normalizedUser)
273
+ if (normalizedUser && userDir.toLowerCase() !== normalizedUser)
299
274
  continue;
300
- const userRoot = path.win32.join(grid3BasePath, userDir.name);
301
- const gridSetsDir = path.win32.join(userRoot, 'Grid Sets');
302
- if (!fs.existsSync(gridSetsDir))
275
+ const userRoot = (0, io_1.joinWin32)(grid3BasePath, userDir);
276
+ const gridSetsDir = (0, io_1.joinWin32)(userRoot, 'Grid Sets');
277
+ if (!pathExists(gridSetsDir))
303
278
  continue;
304
- const entries = fs.readdirSync(gridSetsDir, { withFileTypes: true });
279
+ const entries = listDir(gridSetsDir);
305
280
  for (const entry of entries) {
306
- if (!entry.isFile())
281
+ if (!pathExists(entry) || isDirectory(entry))
307
282
  continue;
308
- const ext = path.extname(entry.name).toLowerCase();
283
+ const ext = (0, io_1.extname)(entry).toLowerCase();
309
284
  if (ext === '.gridset' || ext === '.gridsetx' || ext === '.grd' || ext === '.grdl') {
310
285
  results.push({
311
- userName: userDir.name,
312
- gridsetPath: path.win32.join(gridSetsDir, entry.name),
286
+ userName: userDir,
287
+ gridsetPath: (0, io_1.joinWin32)(gridSetsDir, entry),
313
288
  });
314
289
  }
315
290
  }
@@ -322,26 +297,27 @@ function findGrid3Vocabularies(userName) {
322
297
  * @param langCode Optional language code filter (case-insensitive)
323
298
  * @returns Path to history.sqlite or null if not found
324
299
  */
325
- function findGrid3UserHistory(userName, langCode) {
300
+ function findGrid3UserHistory(userName, langCode, fileAdapter) {
326
301
  if (!userName)
327
302
  return null;
328
303
  const normalizedUser = userName.toLowerCase();
329
304
  const normalizedLang = langCode?.toLowerCase();
330
- const match = findGrid3UserPaths().find((u) => u.userName.toLowerCase() === normalizedUser &&
305
+ const match = findGrid3UserPaths(fileAdapter).find((u) => u.userName.toLowerCase() === normalizedUser &&
331
306
  (!normalizedLang || u.langCode.toLowerCase() === normalizedLang));
332
307
  return match?.historyDbPath ?? null;
333
308
  }
334
309
  /**
335
310
  * Check whether Grid 3 appears to be installed (Windows only)
336
311
  */
337
- function isGrid3Installed() {
312
+ function isGrid3Installed(fileAdapter = io_1.defaultFileAdapter) {
313
+ const { pathExists } = fileAdapter;
338
314
  if (process.platform !== 'win32')
339
315
  return false;
340
316
  const commonDocs = getCommonDocumentsPath();
341
317
  if (!commonDocs)
342
318
  return false;
343
- const grid3BasePath = path.win32.join(commonDocs, 'Smartbox', 'Grid 3', 'Users');
344
- return fs.existsSync(grid3BasePath);
319
+ const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
320
+ return pathExists(grid3BasePath);
345
321
  }
346
322
  function parseGrid3ContentXml(xmlContent) {
347
323
  const regex = /<r>(?:<!\[CDATA\[)?(.*?)(?:\]\]>)?<\/r>/gis;
@@ -360,10 +336,12 @@ function parseGrid3ContentXml(xmlContent) {
360
336
  * @param historyDbPath Absolute path to the history database
361
337
  * @returns Parsed history entries grouped by phrase
362
338
  */
363
- function readGrid3History(historyDbPath) {
364
- if (!fs.existsSync(historyDbPath))
339
+ function readGrid3History(historyDbPath, fileAdapter = io_1.defaultFileAdapter) {
340
+ const { pathExists } = fileAdapter;
341
+ if (!pathExists(historyDbPath))
365
342
  return [];
366
- const db = new better_sqlite3_1.default(historyDbPath, { readonly: true });
343
+ const Database = (0, sqlite_1.requireBetterSqlite3)();
344
+ const db = new Database(historyDbPath, { readonly: true });
367
345
  const rows = db
368
346
  .prepare(`
369
347
  SELECT p.Id as PhraseId,
@@ -4,8 +4,8 @@
4
4
  * These utilities help developers understand why images might not be resolving
5
5
  * correctly in Grid3 gridsets.
6
6
  */
7
- import { type ZipAdapter } from '../../utils/zip';
8
- import { type ProcessorInput } from '../../utils/io';
7
+ import { FileAdapter, type ProcessorInput } from '../../utils/io';
8
+ import { ZipAdapter } from '../../utils/zip';
9
9
  export interface ImageIssue {
10
10
  gridName: string;
11
11
  cellX: number;
@@ -36,9 +36,7 @@ export interface ImageAuditResult {
36
36
  * console.log(`Cell (${issue.cellX}, ${issue.cellY}): ${issue.suggestion}`);
37
37
  * });
38
38
  */
39
- export declare function auditGridsetImages(gridsetBuffer: Uint8Array, password?: string | undefined, zipAdapter?: (input: ProcessorInput) => Promise<{
40
- zip: ZipAdapter;
41
- }>): Promise<ImageAuditResult>;
39
+ export declare function auditGridsetImages(gridsetBuffer: Uint8Array, password?: string | undefined, fileAdapter?: FileAdapter, zipAdapter?: (input: ProcessorInput) => Promise<ZipAdapter>): Promise<ImageAuditResult>;
42
40
  /**
43
41
  * Get a human-readable summary of image audit results
44
42
  */
@@ -8,11 +8,11 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.auditGridsetImages = auditGridsetImages;
10
10
  exports.formatImageAuditSummary = formatImageAuditSummary;
11
- const zip_1 = require("../../utils/zip");
12
11
  const password_1 = require("./password");
13
12
  const password_2 = require("./password");
14
13
  const fast_xml_parser_1 = require("fast-xml-parser");
15
14
  const io_1 = require("../../utils/io");
15
+ const zip_1 = require("../../utils/zip");
16
16
  /**
17
17
  * Audit a gridset file to find image resolution issues
18
18
  *
@@ -26,7 +26,7 @@ const io_1 = require("../../utils/io");
26
26
  * console.log(`Cell (${issue.cellX}, ${issue.cellY}): ${issue.suggestion}`);
27
27
  * });
28
28
  */
29
- async function auditGridsetImages(gridsetBuffer, password = (0, password_2.resolveGridsetPasswordFromEnv)(), zipAdapter) {
29
+ async function auditGridsetImages(gridsetBuffer, password = (0, password_2.resolveGridsetPasswordFromEnv)(), fileAdapter = io_1.defaultFileAdapter, zipAdapter) {
30
30
  const issues = [];
31
31
  const availableImages = new Set();
32
32
  let totalCells = 0;
@@ -34,9 +34,9 @@ async function auditGridsetImages(gridsetBuffer, password = (0, password_2.resol
34
34
  let resolvedImages = 0;
35
35
  let unresolvedImages = 0;
36
36
  try {
37
- const { zip } = zipAdapter
37
+ const zip = zipAdapter
38
38
  ? await zipAdapter(gridsetBuffer)
39
- : await (0, zip_1.openZipFromInput)(gridsetBuffer);
39
+ : await (0, zip_1.getZipAdapter)(gridsetBuffer, fileAdapter);
40
40
  const entries = (0, password_1.getZipEntriesFromAdapter)(zip, password);
41
41
  const parser = new fast_xml_parser_1.XMLParser();
42
42
  // Collect all image files in the gridset
@@ -1,7 +1,7 @@
1
1
  import type JSZip from 'jszip';
2
2
  import { ProcessorOptions } from '../../core/baseProcessor';
3
3
  import { ProcessorInput } from '../../utils/io';
4
- import { type ZipAdapter } from '../../utils/zip';
4
+ import { ZipAdapter } from '../../utils/zip';
5
5
  /**
6
6
  * Resolve the password to use for Grid3 archives.
7
7
  * Preference order:
@@ -12,6 +12,8 @@
12
12
  * c. For Tawasol: provide alternative sources
13
13
  */
14
14
  import { type SymbolReference } from './symbols';
15
+ import { FileAdapter, ProcessorInput } from '../../utils/io';
16
+ import { ZipAdapter } from '../../utils/zip';
15
17
  /**
16
18
  * Image extraction result
17
19
  */
@@ -50,14 +52,14 @@ export interface SymbolExtractionOptions {
50
52
  * @param options - Extraction options
51
53
  * @returns Extracted image data
52
54
  */
53
- export declare function extractButtonImage(gridsetBuffer: Buffer, resolvedImageEntry: string | undefined, symbolReference: string | undefined, options?: SymbolExtractionOptions): ExtractedImage;
55
+ export declare function extractButtonImage(gridsetBuffer: Buffer, resolvedImageEntry: string | undefined, symbolReference: string | undefined, options?: SymbolExtractionOptions, fileAdapter?: FileAdapter, zipAdapter?: (input: ProcessorInput) => Promise<ZipAdapter>): Promise<ExtractedImage>;
54
56
  /**
55
57
  * Extract image from symbol library
56
58
  * @param reference - Symbol reference like "[tawasl]/food/apple.png"
57
59
  * @param options - Extraction options
58
60
  * @returns Extracted image or reference info
59
61
  */
60
- export declare function extractSymbolLibraryImage(reference: string, options?: SymbolExtractionOptions): ExtractedImage;
62
+ export declare function extractSymbolLibraryImage(reference: string, options?: SymbolExtractionOptions): Promise<ExtractedImage>;
61
63
  /**
62
64
  * Convert extracted image to Asterics Grid format
63
65
  * @param extracted - Extracted image
@@ -95,7 +97,7 @@ export declare function suggestExtractionStrategy(report: SymbolReport): string;
95
97
  /**
96
98
  * Export symbol references to CSV for manual extraction
97
99
  */
98
- export declare function exportSymbolReferencesToCsv(report: SymbolReport, outputPath: string): void;
100
+ export declare function exportSymbolReferencesToCsv(report: SymbolReport, outputPath: string, fileAdapter?: FileAdapter): void;
99
101
  /**
100
102
  * Create a manifest file for missing symbols
101
103
  */
@@ -12,32 +12,6 @@
12
12
  * b. Provide reference/URL for manual resolution
13
13
  * c. For Tawasol: provide alternative sources
14
14
  */
15
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- var desc = Object.getOwnPropertyDescriptor(m, k);
18
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
- desc = { enumerable: true, get: function() { return m[k]; } };
20
- }
21
- Object.defineProperty(o, k2, desc);
22
- }) : (function(o, m, k, k2) {
23
- if (k2 === undefined) k2 = k;
24
- o[k2] = m[k];
25
- }));
26
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
- Object.defineProperty(o, "default", { enumerable: true, value: v });
28
- }) : function(o, v) {
29
- o["default"] = v;
30
- });
31
- var __importStar = (this && this.__importStar) || function (mod) {
32
- if (mod && mod.__esModule) return mod;
33
- var result = {};
34
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
35
- __setModuleDefault(result, mod);
36
- return result;
37
- };
38
- var __importDefault = (this && this.__importDefault) || function (mod) {
39
- return (mod && mod.__esModule) ? mod : { "default": mod };
40
- };
41
15
  Object.defineProperty(exports, "__esModule", { value: true });
42
16
  exports.extractButtonImage = extractButtonImage;
43
17
  exports.extractSymbolLibraryImage = extractSymbolLibraryImage;
@@ -46,9 +20,9 @@ exports.analyzeSymbolExtraction = analyzeSymbolExtraction;
46
20
  exports.suggestExtractionStrategy = suggestExtractionStrategy;
47
21
  exports.exportSymbolReferencesToCsv = exportSymbolReferencesToCsv;
48
22
  exports.createSymbolManifest = createSymbolManifest;
49
- const fs = __importStar(require("fs"));
50
- const adm_zip_1 = __importDefault(require("adm-zip"));
51
23
  const symbols_1 = require("./symbols");
24
+ const io_1 = require("../../utils/io");
25
+ const zip_1 = require("../../utils/zip");
52
26
  /**
53
27
  * Known open-license symbol sources
54
28
  */
@@ -80,15 +54,17 @@ const OPEN_LICENSE_SYMBOLS = {
80
54
  * @param options - Extraction options
81
55
  * @returns Extracted image data
82
56
  */
83
- function extractButtonImage(gridsetBuffer, resolvedImageEntry, symbolReference, options = {}) {
57
+ async function extractButtonImage(gridsetBuffer, resolvedImageEntry, symbolReference, options = {}, fileAdapter = io_1.defaultFileAdapter, zipAdapter) {
84
58
  // Priority 1: Use embedded image if available
85
59
  if (resolvedImageEntry && options.preferEmbedded !== false) {
86
60
  try {
87
- const zip = new adm_zip_1.default(gridsetBuffer);
88
- const entries = zip.getEntries();
89
- const entry = entries.find((e) => e.entryName === resolvedImageEntry);
61
+ const zip = zipAdapter
62
+ ? await zipAdapter(gridsetBuffer)
63
+ : await (0, zip_1.getZipAdapter)(gridsetBuffer, fileAdapter);
64
+ const entries = zip.listFiles();
65
+ const entry = entries.find((e) => e === resolvedImageEntry);
90
66
  if (entry) {
91
- const data = entry.getData();
67
+ const data = Buffer.from(await zip.readFile(entry));
92
68
  const format = detectImageFormat(data);
93
69
  return {
94
70
  found: true,
@@ -105,7 +81,7 @@ function extractButtonImage(gridsetBuffer, resolvedImageEntry, symbolReference,
105
81
  }
106
82
  // Priority 2: Check symbol library reference
107
83
  if (symbolReference) {
108
- return extractSymbolLibraryImage(symbolReference, options);
84
+ return await extractSymbolLibraryImage(symbolReference, options);
109
85
  }
110
86
  // Not found
111
87
  return {
@@ -119,7 +95,7 @@ function extractButtonImage(gridsetBuffer, resolvedImageEntry, symbolReference,
119
95
  * @param options - Extraction options
120
96
  * @returns Extracted image or reference info
121
97
  */
122
- function extractSymbolLibraryImage(reference, options = {}) {
98
+ async function extractSymbolLibraryImage(reference, options = {}) {
123
99
  const ref = parseSymbolReferenceSafe(reference);
124
100
  if (!ref || !ref.isValid) {
125
101
  return {
@@ -131,7 +107,7 @@ function extractSymbolLibraryImage(reference, options = {}) {
131
107
  // Get library metadata
132
108
  const libInfo = OPEN_LICENSE_SYMBOLS[ref.library];
133
109
  // Resolve symbol reference and extract from .symbols file
134
- const resolved = (0, symbols_1.resolveSymbolReference)(reference, {
110
+ const resolved = await (0, symbols_1.resolveSymbolReference)(reference, {
135
111
  grid3Path: options.grid3Path,
136
112
  });
137
113
  const metadata = {
@@ -310,12 +286,13 @@ function parseSymbolReferenceSafe(reference) {
310
286
  /**
311
287
  * Export symbol references to CSV for manual extraction
312
288
  */
313
- function exportSymbolReferencesToCsv(report, outputPath) {
289
+ function exportSymbolReferencesToCsv(report, outputPath, fileAdapter = io_1.defaultFileAdapter) {
290
+ const { writeTextToPath } = fileAdapter;
314
291
  const lines = ['Reference,Library,Path,Attribution,License'];
315
292
  for (const symbol of report.missingSymbols) {
316
293
  lines.push(`"${symbol.reference}","${symbol.library}","${symbol.path}","${symbol.attribution || ''}","${symbol.license || ''}"`);
317
294
  }
318
- fs.writeFileSync(outputPath, lines.join('\n'));
295
+ writeTextToPath(outputPath, lines.join('\n'));
319
296
  }
320
297
  function createSymbolManifest(tree, gridsetName) {
321
298
  const manifest = {
@@ -8,6 +8,7 @@
8
8
  * above bw=above bw.png=above bw
9
9
  * active family=active family.png=active family
10
10
  */
11
+ import { FileAdapter } from '../../utils/io';
11
12
  /**
12
13
  * Symbol search result
13
14
  */
@@ -41,13 +42,13 @@ export interface LibrarySearchIndex {
41
42
  * @param pixFilePath - Path to .pix file
42
43
  * @returns Search index
43
44
  */
44
- export declare function parsePixFile(pixFilePath: string): LibrarySearchIndex;
45
+ export declare function parsePixFile(pixFilePath: string, fileAdapter?: FileAdapter): LibrarySearchIndex;
45
46
  /**
46
47
  * Load search indexes for all available libraries
47
48
  * @param options - Search options
48
49
  * @returns Map of library name to search index
49
50
  */
50
- export declare function loadSearchIndexes(options?: SymbolSearchOptions): Map<string, LibrarySearchIndex>;
51
+ export declare function loadSearchIndexes(options?: SymbolSearchOptions, fileAdapter?: FileAdapter): Map<string, LibrarySearchIndex>;
51
52
  /**
52
53
  * Search for symbols by term
53
54
  * @param searchTerm - Term to search for
@@ -9,29 +9,6 @@
9
9
  * above bw=above bw.png=above bw
10
10
  * active family=active family.png=active family
11
11
  */
12
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- var desc = Object.getOwnPropertyDescriptor(m, k);
15
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
- desc = { enumerable: true, get: function() { return m[k]; } };
17
- }
18
- Object.defineProperty(o, k2, desc);
19
- }) : (function(o, m, k, k2) {
20
- if (k2 === undefined) k2 = k;
21
- o[k2] = m[k];
22
- }));
23
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
- Object.defineProperty(o, "default", { enumerable: true, value: v });
25
- }) : function(o, v) {
26
- o["default"] = v;
27
- });
28
- var __importStar = (this && this.__importStar) || function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
12
  Object.defineProperty(exports, "__esModule", { value: true });
36
13
  exports.parsePixFile = parsePixFile;
37
14
  exports.loadSearchIndexes = loadSearchIndexes;
@@ -43,16 +20,16 @@ exports.getSearchSuggestions = getSearchSuggestions;
43
20
  exports.searchSymbolsWithReferences = searchSymbolsWithReferences;
44
21
  exports.countLibrarySymbols = countLibrarySymbols;
45
22
  exports.getSymbolSearchStats = getSymbolSearchStats;
46
- const fs = __importStar(require("fs"));
47
- const path = __importStar(require("path"));
23
+ const io_1 = require("../../utils/io");
48
24
  /**
49
25
  * Parse a .pix file into search index
50
26
  * @param pixFilePath - Path to .pix file
51
27
  * @returns Search index
52
28
  */
53
- function parsePixFile(pixFilePath) {
54
- const content = fs.readFileSync(pixFilePath, 'utf-8');
55
- const library = path.basename(pixFilePath, '.pix');
29
+ function parsePixFile(pixFilePath, fileAdapter = io_1.defaultFileAdapter) {
30
+ const { readTextFromInput, basename } = fileAdapter;
31
+ const content = readTextFromInput(pixFilePath);
32
+ const library = basename(pixFilePath, '.pix');
56
33
  const searchTerms = new Map();
57
34
  const filenames = new Map();
58
35
  const lines = content.split('\n');
@@ -78,22 +55,23 @@ function parsePixFile(pixFilePath) {
78
55
  * @param options - Search options
79
56
  * @returns Map of library name to search index
80
57
  */
81
- function loadSearchIndexes(options = {}) {
58
+ function loadSearchIndexes(options = {}, fileAdapter = io_1.defaultFileAdapter) {
59
+ const { listDir, pathExists, join, basename } = fileAdapter;
82
60
  const { grid3Path, locale = 'en-GB', libraries: specifiedLibs } = options;
83
61
  if (!grid3Path) {
84
62
  throw new Error('grid3Path is required for symbol search');
85
63
  }
86
- const searchIndexesDir = path.join(grid3Path, 'Locale', locale, 'symbolsearch');
87
- if (!fs.existsSync(searchIndexesDir)) {
64
+ const searchIndexesDir = join(grid3Path, 'Locale', locale, 'symbolsearch');
65
+ if (!pathExists(searchIndexesDir)) {
88
66
  throw new Error(`Symbol search directory not found: ${searchIndexesDir}`);
89
67
  }
90
68
  const indexes = new Map();
91
- const files = fs.readdirSync(searchIndexesDir);
69
+ const files = listDir(searchIndexesDir);
92
70
  for (const file of files) {
93
71
  if (!file.endsWith('.pix')) {
94
72
  continue;
95
73
  }
96
- const libraryName = path.basename(file, '.pix');
74
+ const libraryName = basename(file, '.pix');
97
75
  // Filter libraries if specified
98
76
  if (specifiedLibs && specifiedLibs.length > 0) {
99
77
  if (!specifiedLibs.some((lib) => lib.toLowerCase() === libraryName.toLowerCase())) {
@@ -101,7 +79,7 @@ function loadSearchIndexes(options = {}) {
101
79
  }
102
80
  }
103
81
  try {
104
- const pixFilePath = path.join(searchIndexesDir, file);
82
+ const pixFilePath = join(searchIndexesDir, file);
105
83
  const index = parsePixFile(pixFilePath);
106
84
  indexes.set(libraryName, index);
107
85
  }
@@ -12,6 +12,8 @@
12
12
  *
13
13
  * This module provides symbol resolution and metadata extraction.
14
14
  */
15
+ import { FileAdapter, ProcessorInput } from '../../utils/io';
16
+ import { ZipAdapter } from '../../utils/zip';
15
17
  /**
16
18
  * Known symbol libraries in Grid 3
17
19
  */
@@ -92,14 +94,14 @@ export declare function isSymbolReference(reference: string): boolean;
92
94
  * Get the default Grid 3 installation path for the current platform
93
95
  * @returns Default Grid 3 path or empty string if not found
94
96
  */
95
- export declare function getDefaultGrid3Path(): string;
97
+ export declare function getDefaultGrid3Path(fileAdapter?: FileAdapter): string;
96
98
  /**
97
99
  * Get the Symbol Libraries directory path
98
100
  * Contains .symbols ZIP archives with actual image files
99
101
  * @param grid3Path - Grid 3 installation path
100
102
  * @returns Path to Symbol Libraries directory (e.g., "C:\...\Grid 3\Resources\Symbols")
101
103
  */
102
- export declare function getSymbolLibrariesDir(grid3Path: string): string;
104
+ export declare function getSymbolLibrariesDir(grid3Path: string, fileAdapter?: FileAdapter): string;
103
105
  /**
104
106
  * Get the symbol search indexes directory path for a given locale
105
107
  * Contains .pix index files for searching symbols
@@ -107,27 +109,27 @@ export declare function getSymbolLibrariesDir(grid3Path: string): string;
107
109
  * @param locale - Locale code (e.g., 'en-GB')
108
110
  * @returns Path to symbol search indexes directory (e.g., "C:\...\Grid 3\Locale\en-GB\symbolsearch")
109
111
  */
110
- export declare function getSymbolSearchIndexesDir(grid3Path: string, locale?: string): string;
112
+ export declare function getSymbolSearchIndexesDir(grid3Path: string, locale?: string, fileAdapter?: FileAdapter): string;
111
113
  /**
112
114
  * Get all available symbol libraries in the Grid 3 installation
113
115
  * @param options - Resolution options
114
116
  * @returns Array of symbol library information
115
117
  */
116
- export declare function getAvailableSymbolLibraries(options?: SymbolResolutionOptions): SymbolLibraryInfo[];
118
+ export declare function getAvailableSymbolLibraries(options?: SymbolResolutionOptions, fileAdapter?: FileAdapter): SymbolLibraryInfo[];
117
119
  /**
118
120
  * Check if a symbol library exists
119
121
  * @param libraryName - Name of the library (e.g., 'widgit', 'tawasl')
120
122
  * @param options - Resolution options
121
123
  * @returns Symbol library info or undefined if not found
122
124
  */
123
- export declare function getSymbolLibraryInfo(libraryName: string, options?: SymbolResolutionOptions): SymbolLibraryInfo | undefined;
125
+ export declare function getSymbolLibraryInfo(libraryName: string, options?: SymbolResolutionOptions, fileAdapter?: FileAdapter): SymbolLibraryInfo | undefined;
124
126
  /**
125
127
  * Resolve a symbol reference to extract the actual image data
126
128
  * @param reference - Symbol reference like "[tawasl]/above bw.png"
127
129
  * @param options - Resolution options
128
130
  * @returns Resolution result with image data if found
129
131
  */
130
- export declare function resolveSymbolReference(reference: string, options?: SymbolResolutionOptions): SymbolResolutionResult;
132
+ export declare function resolveSymbolReference(reference: string, options?: SymbolResolutionOptions, fileAdapter?: FileAdapter, zipAdapter?: (input: ProcessorInput) => Promise<ZipAdapter>): Promise<SymbolResolutionResult>;
131
133
  /**
132
134
  * Get all symbol references from a gridset
133
135
  * This scans button images for symbol references