@willwade/aac-processors 0.1.20 → 0.2.0

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 (113) hide show
  1. package/dist/browser/core/baseProcessor.js +4 -0
  2. package/dist/browser/processors/applePanelsProcessor.js +33 -40
  3. package/dist/browser/processors/astericsGridProcessor.js +31 -26
  4. package/dist/browser/processors/dotProcessor.js +11 -12
  5. package/dist/browser/processors/gridset/colorUtils.js +354 -0
  6. package/dist/browser/processors/gridset/helpers.js +60 -53
  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 +39 -72
  12. package/dist/browser/processors/gridsetProcessor.js +39 -48
  13. package/dist/browser/processors/obfProcessor.js +39 -53
  14. package/dist/browser/processors/opmlProcessor.js +11 -12
  15. package/dist/browser/processors/snap/helpers.js +57 -49
  16. package/dist/browser/processors/snapProcessor.js +48 -51
  17. package/dist/browser/processors/touchchatProcessor.js +60 -52
  18. package/dist/browser/utilities/analytics/history.js +24 -18
  19. package/dist/browser/utilities/analytics/metrics/comparison.js +16 -16
  20. package/dist/browser/utilities/analytics/metrics/vocabulary.js +2 -2
  21. package/dist/browser/utilities/analytics/reference/browser.js +16 -16
  22. package/dist/browser/utilities/analytics/reference/index.js +44 -35
  23. package/dist/browser/utils/io.js +78 -21
  24. package/dist/browser/utils/sqlite.js +8 -10
  25. package/dist/browser/utils/zip.js +43 -43
  26. package/dist/browser/validation/baseValidator.js +5 -0
  27. package/dist/browser/validation/gridsetValidator.js +12 -20
  28. package/dist/browser/validation/obfValidator.js +6 -5
  29. package/dist/browser/validation/snapValidator.js +11 -7
  30. package/dist/browser/validation/touchChatValidator.js +23 -13
  31. package/dist/cli/index.js +22 -24
  32. package/dist/core/baseProcessor.d.ts +7 -7
  33. package/dist/core/baseProcessor.js +4 -0
  34. package/dist/processors/applePanelsProcessor.js +32 -39
  35. package/dist/processors/astericsGridProcessor.d.ts +4 -4
  36. package/dist/processors/astericsGridProcessor.js +30 -25
  37. package/dist/processors/dotProcessor.js +10 -11
  38. package/dist/processors/excelProcessor.d.ts +3 -3
  39. package/dist/processors/excelProcessor.js +14 -20
  40. package/dist/processors/gridset/helpers.d.ts +12 -14
  41. package/dist/processors/gridset/helpers.js +60 -79
  42. package/dist/processors/gridset/imageDebug.d.ts +3 -5
  43. package/dist/processors/gridset/imageDebug.js +4 -4
  44. package/dist/processors/gridset/password.d.ts +1 -1
  45. package/dist/processors/gridset/symbolExtractor.d.ts +5 -3
  46. package/dist/processors/gridset/symbolExtractor.js +15 -38
  47. package/dist/processors/gridset/symbolSearch.d.ts +11 -10
  48. package/dist/processors/gridset/symbolSearch.js +29 -51
  49. package/dist/processors/gridset/symbols.d.ts +8 -6
  50. package/dist/processors/gridset/symbols.js +38 -71
  51. package/dist/processors/gridset/wordlistHelpers.d.ts +4 -6
  52. package/dist/processors/gridset/wordlistHelpers.js +15 -74
  53. package/dist/processors/gridsetProcessor.d.ts +2 -2
  54. package/dist/processors/gridsetProcessor.js +38 -70
  55. package/dist/processors/obfProcessor.d.ts +2 -2
  56. package/dist/processors/obfProcessor.js +38 -75
  57. package/dist/processors/obfsetProcessor.js +2 -3
  58. package/dist/processors/opmlProcessor.js +10 -11
  59. package/dist/processors/snap/helpers.d.ts +9 -9
  60. package/dist/processors/snap/helpers.js +58 -76
  61. package/dist/processors/snapProcessor.d.ts +2 -2
  62. package/dist/processors/snapProcessor.js +47 -50
  63. package/dist/processors/touchchatProcessor.d.ts +2 -2
  64. package/dist/processors/touchchatProcessor.js +59 -51
  65. package/dist/types/aac.d.ts +2 -2
  66. package/dist/utilities/analytics/history.d.ts +8 -8
  67. package/dist/utilities/analytics/history.js +24 -18
  68. package/dist/utilities/analytics/index.d.ts +3 -2
  69. package/dist/utilities/analytics/index.js +9 -10
  70. package/dist/utilities/analytics/metrics/comparison.d.ts +1 -1
  71. package/dist/utilities/analytics/metrics/comparison.js +16 -16
  72. package/dist/utilities/analytics/metrics/vocabulary.d.ts +1 -1
  73. package/dist/utilities/analytics/metrics/vocabulary.js +2 -2
  74. package/dist/utilities/analytics/reference/browser.d.ts +9 -9
  75. package/dist/utilities/analytics/reference/browser.js +16 -16
  76. package/dist/utilities/analytics/reference/index.d.ts +25 -23
  77. package/dist/utilities/analytics/reference/index.js +43 -34
  78. package/dist/utilities/symbolTools.d.ts +8 -6
  79. package/dist/utilities/symbolTools.js +21 -18
  80. package/dist/utils/io.d.ts +24 -6
  81. package/dist/utils/io.js +79 -25
  82. package/dist/utils/sqlite.d.ts +3 -1
  83. package/dist/utils/sqlite.js +7 -9
  84. package/dist/utils/zip.d.ts +7 -3
  85. package/dist/utils/zip.js +43 -43
  86. package/dist/validation/applePanelsValidator.d.ts +2 -1
  87. package/dist/validation/applePanelsValidator.js +10 -11
  88. package/dist/validation/astericsValidator.d.ts +2 -1
  89. package/dist/validation/astericsValidator.js +5 -4
  90. package/dist/validation/baseValidator.d.ts +2 -2
  91. package/dist/validation/baseValidator.js +5 -0
  92. package/dist/validation/dotValidator.d.ts +2 -1
  93. package/dist/validation/dotValidator.js +5 -4
  94. package/dist/validation/excelValidator.d.ts +2 -1
  95. package/dist/validation/excelValidator.js +5 -4
  96. package/dist/validation/gridsetValidator.d.ts +2 -1
  97. package/dist/validation/gridsetValidator.js +11 -22
  98. package/dist/validation/index.d.ts +2 -2
  99. package/dist/validation/index.js +5 -4
  100. package/dist/validation/obfValidator.d.ts +2 -1
  101. package/dist/validation/obfValidator.js +5 -4
  102. package/dist/validation/obfsetValidator.d.ts +2 -1
  103. package/dist/validation/obfsetValidator.js +5 -4
  104. package/dist/validation/opmlValidator.d.ts +2 -1
  105. package/dist/validation/opmlValidator.js +5 -4
  106. package/dist/validation/snapValidator.d.ts +2 -1
  107. package/dist/validation/snapValidator.js +10 -6
  108. package/dist/validation/touchChatValidator.d.ts +4 -6
  109. package/dist/validation/touchChatValidator.js +22 -12
  110. package/dist/validation/validationTypes.d.ts +8 -1
  111. package/package.json +1 -1
  112. package/dist/core/fileProcessor.d.ts +0 -7
  113. package/dist/core/fileProcessor.js +0 -57
@@ -1,27 +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
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
3
  exports.GridsetProcessor = void 0;
27
4
  const baseProcessor_1 = require("../core/baseProcessor");
@@ -40,7 +17,6 @@ const resolver_2 = require("./gridset/resolver");
40
17
  const idGenerator_1 = require("../utilities/analytics/utils/idGenerator");
41
18
  const symbolAlignment_1 = require("./gridset/symbolAlignment");
42
19
  const io_1 = require("../utils/io");
43
- const zip_1 = require("../utils/zip");
44
20
  class GridsetProcessor extends baseProcessor_1.BaseProcessor {
45
21
  constructor(options) {
46
22
  super(options);
@@ -421,19 +397,18 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
421
397
  return texts;
422
398
  }
423
399
  async loadIntoTree(filePathOrBuffer) {
400
+ const { readBinaryFromInput } = this.options.fileAdapter;
424
401
  const tree = new treeStructure_1.AACTree();
425
402
  let zipResult;
426
403
  try {
427
- const zipInput = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
428
- zipResult = this.options.zipAdapter
429
- ? await this.options.zipAdapter(zipInput)
430
- : await (0, zip_1.openZipFromInput)(zipInput);
404
+ const zipInput = await readBinaryFromInput(filePathOrBuffer);
405
+ zipResult = await this.options.zipAdapter(zipInput);
431
406
  }
432
407
  catch (error) {
433
408
  throw new Error(`Invalid ZIP file format: ${error.message}`);
434
409
  }
435
410
  const password = this.getGridsetPassword(filePathOrBuffer);
436
- const entries = (0, password_1.getZipEntriesFromAdapter)(zipResult.zip, password);
411
+ const entries = (0, password_1.getZipEntriesFromAdapter)(zipResult, password);
437
412
  const options = {
438
413
  ignoreAttributes: false,
439
414
  ignoreDeclaration: true,
@@ -1709,6 +1684,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1709
1684
  return tree;
1710
1685
  }
1711
1686
  async processTexts(filePathOrBuffer, translations, outputPath) {
1687
+ const { readBinaryFromInput } = this.options.fileAdapter;
1712
1688
  // Load the tree, apply translations, and save to new file
1713
1689
  const tree = await this.loadIntoTree(filePathOrBuffer);
1714
1690
  // Apply translations to all text content
@@ -1769,7 +1745,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1769
1745
  });
1770
1746
  // Save the translated tree and return its content
1771
1747
  await this.saveFromTree(tree, outputPath);
1772
- return (0, io_1.readBinaryFromInput)(outputPath);
1748
+ return await readBinaryFromInput(outputPath);
1773
1749
  }
1774
1750
  /**
1775
1751
  * Extract symbol information from a gridset for LLM-based translation.
@@ -1778,7 +1754,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1778
1754
  * This method uses shared translation utilities that work across all AAC formats.
1779
1755
  *
1780
1756
  * @param filePathOrBuffer - Path to gridset file or buffer
1781
- * @returns Array of symbol information for LLM processing
1757
+ * @returns Promise resolving to symbol information for LLM processing
1782
1758
  */
1783
1759
  async extractSymbolsForLLM(filePathOrBuffer) {
1784
1760
  const tree = await this.loadIntoTree(filePathOrBuffer);
@@ -1808,9 +1784,10 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1808
1784
  * @param llmTranslations - Array of LLM translations with symbol info
1809
1785
  * @param outputPath - Where to save the translated gridset
1810
1786
  * @param options - Translation options (e.g., allowPartial for testing)
1811
- * @returns Buffer of the translated gridset
1787
+ * @returns Promise resolving to a buffer of the translated gridset
1812
1788
  */
1813
1789
  async processLLMTranslations(filePathOrBuffer, llmTranslations, outputPath, options) {
1790
+ const { readBinaryFromInput } = this.options.fileAdapter;
1814
1791
  const tree = await this.loadIntoTree(filePathOrBuffer);
1815
1792
  // Validate translations using shared utility
1816
1793
  const buttonIds = Object.values(tree.pages).flatMap((page) => page.buttons.map((b) => b.id));
@@ -1849,40 +1826,16 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1849
1826
  });
1850
1827
  // Save and return
1851
1828
  await this.saveFromTree(tree, outputPath);
1852
- return (0, io_1.readBinaryFromInput)(outputPath);
1829
+ return await readBinaryFromInput(outputPath);
1853
1830
  }
1854
1831
  async saveFromTree(tree, outputPath) {
1855
- const useNodeZip = (0, io_1.isNodeRuntime)();
1856
- let addText;
1857
- let addBinary;
1858
- let finalizeZip;
1859
- if (useNodeZip) {
1860
- const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
1861
- const zip = new AdmZip();
1862
- addText = (entryPath, content) => {
1863
- zip.addFile(entryPath, Buffer.from(content, 'utf8'));
1864
- };
1865
- addBinary = (entryPath, content) => {
1866
- zip.addFile(entryPath, Buffer.from(content));
1867
- };
1868
- finalizeZip = () => Promise.resolve(zip.toBuffer());
1869
- }
1870
- else {
1871
- const module = await Promise.resolve().then(() => __importStar(require('jszip')));
1872
- const JSZip = module.default || module;
1873
- const zip = new JSZip();
1874
- addText = (entryPath, content) => {
1875
- zip.file(entryPath, content, { binary: false });
1876
- };
1877
- addBinary = (entryPath, content) => {
1878
- zip.file(entryPath, content);
1879
- };
1880
- finalizeZip = async () => zip.generateAsync({ type: 'uint8array' });
1881
- }
1832
+ const files = [];
1833
+ const { writeBinaryToPath } = this.options.fileAdapter;
1834
+ const zip = await this.options.zipAdapter();
1882
1835
  if (Object.keys(tree.pages).length === 0) {
1883
1836
  // Create empty zip for empty tree
1884
- const zipBuffer = await finalizeZip();
1885
- (0, io_1.writeBinaryToPath)(outputPath, zipBuffer);
1837
+ const zipBuffer = await zip.writeFiles([]);
1838
+ await writeBinaryToPath(outputPath, zipBuffer);
1886
1839
  return;
1887
1840
  }
1888
1841
  // Collect all unique styles from pages and buttons
@@ -1954,7 +1907,10 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1954
1907
  suppressEmptyNode: true,
1955
1908
  });
1956
1909
  const settingsXmlContent = settingsBuilder.build(settingsData);
1957
- addText('Settings0/settings.xml', settingsXmlContent);
1910
+ files.push({
1911
+ name: 'Settings0/settings.xml',
1912
+ data: settingsXmlContent,
1913
+ });
1958
1914
  // Create Settings0/Styles/style.xml if there are styles
1959
1915
  if (uniqueStyles.size > 0) {
1960
1916
  const stylesArray = Array.from(uniqueStyles.values()).map(({ id, style }) => {
@@ -1987,7 +1943,10 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
1987
1943
  indentBy: ' ',
1988
1944
  });
1989
1945
  const styleXmlContent = styleBuilder.build(styleData);
1990
- addText('Settings0/Styles/styles.xml', styleXmlContent);
1946
+ files.push({
1947
+ name: 'Settings0/Styles/styles.xml',
1948
+ data: styleXmlContent,
1949
+ });
1991
1950
  }
1992
1951
  // Collect grid file paths for FileMap.xml
1993
1952
  const gridFilePaths = [];
@@ -2128,14 +2087,20 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
2128
2087
  // Add to zip in Grids folder with proper Grid3 naming
2129
2088
  const gridPath = `Grids/${page.name || page.id}/grid.xml`;
2130
2089
  gridFilePaths.push(gridPath);
2131
- addText(gridPath, xmlContent);
2090
+ files.push({
2091
+ name: gridPath,
2092
+ data: xmlContent,
2093
+ });
2132
2094
  });
2133
2095
  // Write image files to ZIP
2134
2096
  buttonImages.forEach((imgData) => {
2135
2097
  if (imgData.imageData && imgData.imageData.length > 0) {
2136
2098
  // Create image path in the grid's directory
2137
2099
  const imagePath = `Grids/${imgData.pageName}/${imgData.x}-${imgData.y}-0-text-0.${imgData.ext}`;
2138
- addBinary(imagePath, imgData.imageData);
2100
+ files.push({
2101
+ name: imagePath,
2102
+ data: imgData.imageData,
2103
+ });
2139
2104
  }
2140
2105
  });
2141
2106
  // Create FileMap.xml to map all grid files with their dynamic image files
@@ -2174,10 +2139,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
2174
2139
  indentBy: ' ',
2175
2140
  });
2176
2141
  const fileMapXmlContent = fileMapBuilder.build(fileMapData);
2177
- addText('FileMap.xml', fileMapXmlContent);
2142
+ files.push({
2143
+ name: 'FileMap.xml',
2144
+ data: fileMapXmlContent,
2145
+ });
2178
2146
  // Write the zip file
2179
- const zipBuffer = await finalizeZip();
2180
- (0, io_1.writeBinaryToPath)(outputPath, zipBuffer);
2147
+ const zipBuffer = await zip.writeFiles(files);
2148
+ await writeBinaryToPath(outputPath, zipBuffer);
2181
2149
  }
2182
2150
  // Helper method to calculate column definitions based on page layout
2183
2151
  calculateColumnDefinitions(page) {
@@ -2274,7 +2242,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
2274
2242
  * @returns Promise with validation result
2275
2243
  */
2276
2244
  async validate(filePath) {
2277
- return gridsetValidator_1.GridsetValidator.validateFile(filePath);
2245
+ return gridsetValidator_1.GridsetValidator.validateFile(filePath, this.options.fileAdapter);
2278
2246
  }
2279
2247
  }
2280
2248
  exports.GridsetProcessor = GridsetProcessor;
@@ -46,7 +46,7 @@ declare class ObfProcessor extends BaseProcessor {
46
46
  * This method uses shared translation utilities that work across all AAC formats.
47
47
  *
48
48
  * @param filePathOrBuffer - Path to OBF/OBZ file or buffer
49
- * @returns Array of symbol information for LLM processing
49
+ * @returns Promise resolving to symbol information for LLM processing
50
50
  */
51
51
  extractSymbolsForLLM(filePathOrBuffer: ProcessorInput): Promise<ButtonForTranslation[]>;
52
52
  /**
@@ -59,7 +59,7 @@ declare class ObfProcessor extends BaseProcessor {
59
59
  * @param llmTranslations - Array of LLM translations with symbol info
60
60
  * @param outputPath - Where to save the translated OBF/OBZ file
61
61
  * @param options - Translation options (e.g., allowPartial for testing)
62
- * @returns Buffer of the translated OBF/OBZ file
62
+ * @returns Promise resolving to a buffer of the translated OBF/OBZ file
63
63
  */
64
64
  processLLMTranslations(filePathOrBuffer: ProcessorInput, llmTranslations: LLMLTranslationResult[], outputPath: string, options?: {
65
65
  allowPartial?: boolean;
@@ -1,27 +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
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
3
  exports.ObfProcessor = void 0;
27
4
  const baseProcessor_1 = require("../core/baseProcessor");
@@ -29,7 +6,6 @@ const treeStructure_1 = require("../core/treeStructure");
29
6
  const idGenerator_1 = require("../utilities/analytics/utils/idGenerator");
30
7
  const translationProcessor_1 = require("../utilities/translation/translationProcessor");
31
8
  const io_1 = require("../utils/io");
32
- const zip_1 = require("../utils/zip");
33
9
  const OBF_FORMAT_VERSION = 'open-board-0.1';
34
10
  /**
35
11
  * Map OBF hidden value to AAC standard visibility
@@ -193,8 +169,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
193
169
  buttonParameters.image_id = btn.image_id;
194
170
  }
195
171
  return new treeStructure_1.AACButton({
196
- // Make button ID unique by combining page ID and button ID
197
- id: `${pageId}::${btn?.id || ''}`,
172
+ id: String(btn.id),
198
173
  label: String(btn?.label || ''),
199
174
  message: String(btn?.vocalization || btn?.label || ''),
200
175
  visibility: mapObfVisibility(btn.hidden),
@@ -243,7 +218,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
243
218
  return;
244
219
  if (rowIndex >= rows || colIndex >= cols)
245
220
  return;
246
- const aacBtn = buttonMap.get(`${pageId}::${cellId}`);
221
+ const aacBtn = buttonMap.get(String(cellId));
247
222
  if (aacBtn) {
248
223
  grid[rowIndex][colIndex] = aacBtn;
249
224
  }
@@ -256,7 +231,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
256
231
  const row = Math.floor(btn.box_id / cols);
257
232
  const col = btn.box_id % cols;
258
233
  if (row < rows && col < cols) {
259
- const aacBtn = buttonMap.get(`${pageId}::${btn.id}`);
234
+ const aacBtn = buttonMap.get(String(btn.id));
260
235
  if (aacBtn) {
261
236
  grid[row][col] = aacBtn;
262
237
  }
@@ -309,10 +284,11 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
309
284
  return texts;
310
285
  }
311
286
  async loadIntoTree(filePathOrBuffer) {
287
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
312
288
  // Detailed logging for debugging input
313
289
  const bufferLength = typeof filePathOrBuffer === 'string'
314
290
  ? null
315
- : (0, io_1.readBinaryFromInput)(filePathOrBuffer).byteLength;
291
+ : (await readBinaryFromInput(filePathOrBuffer)).byteLength;
316
292
  console.log('[OBF] loadIntoTree called with:', {
317
293
  type: typeof filePathOrBuffer,
318
294
  isBuffer: typeof Buffer !== 'undefined' && Buffer.isBuffer(filePathOrBuffer),
@@ -322,9 +298,9 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
322
298
  });
323
299
  const tree = new treeStructure_1.AACTree();
324
300
  // Helper: try to parse JSON OBF
325
- function tryParseObfJson(data) {
301
+ async function tryParseObfJson(data) {
326
302
  try {
327
- const str = typeof data === 'string' ? data : (0, io_1.readTextFromInput)(data);
303
+ const str = typeof data === 'string' ? data : await readTextFromInput(data);
328
304
  // Check for empty or whitespace-only content
329
305
  if (!str.trim()) {
330
306
  return null;
@@ -346,8 +322,8 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
346
322
  // If input is a string path and ends with .obf, treat as JSON
347
323
  if (typeof filePathOrBuffer === 'string' && filePathOrBuffer.toLowerCase().endsWith('.obf')) {
348
324
  try {
349
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
350
- const boardData = tryParseObfJson(content);
325
+ const content = await readTextFromInput(filePathOrBuffer);
326
+ const boardData = await tryParseObfJson(content);
351
327
  if (boardData) {
352
328
  console.log('[OBF] Detected .obf file, parsed as JSON');
353
329
  const page = await this.processBoard(boardData, filePathOrBuffer, false);
@@ -375,17 +351,17 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
375
351
  }
376
352
  }
377
353
  // Detect likely zip signature first
378
- function isLikelyZip(input) {
354
+ async function isLikelyZip(input) {
379
355
  if (typeof input === 'string') {
380
356
  const lowered = input.toLowerCase();
381
357
  return lowered.endsWith('.zip') || lowered.endsWith('.obz');
382
358
  }
383
- const bytes = (0, io_1.readBinaryFromInput)(input);
359
+ const bytes = await readBinaryFromInput(input);
384
360
  return bytes.length >= 2 && bytes[0] === 0x50 && bytes[1] === 0x4b;
385
361
  }
386
362
  // Check if input is a buffer or string that parses as OBF JSON; throw if neither JSON nor ZIP
387
- if (!isLikelyZip(filePathOrBuffer)) {
388
- const asJson = tryParseObfJson(filePathOrBuffer);
363
+ if (!(await isLikelyZip(filePathOrBuffer))) {
364
+ const asJson = await tryParseObfJson(filePathOrBuffer);
389
365
  if (!asJson)
390
366
  throw new Error('Invalid OBF content: not JSON and not ZIP');
391
367
  console.log('[OBF] Detected buffer/string as OBF JSON');
@@ -406,10 +382,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
406
382
  return tree;
407
383
  }
408
384
  try {
409
- const zipResult = this.options.zipAdapter
410
- ? await this.options.zipAdapter(filePathOrBuffer)
411
- : await (0, zip_1.openZipFromInput)(filePathOrBuffer);
412
- this.zipFile = zipResult.zip;
385
+ this.zipFile = await this.options.zipAdapter(filePathOrBuffer);
413
386
  }
414
387
  catch (err) {
415
388
  console.error('[OBF] Error loading ZIP:', err);
@@ -427,7 +400,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
427
400
  try {
428
401
  const content = await this.zipFile.readFile(manifestFile[0]);
429
402
  const data = (0, io_1.decodeText)(content);
430
- const str = typeof data === 'string' ? data : (0, io_1.readTextFromInput)(data);
403
+ const str = typeof data === 'string' ? data : await readTextFromInput(data);
431
404
  if (!str.trim())
432
405
  throw new Error('Manifest object missing');
433
406
  const manifestObject = JSON.parse(str);
@@ -451,7 +424,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
451
424
  for (const entryName of obfEntries) {
452
425
  try {
453
426
  const content = await this.zipFile.readFile(entryName);
454
- const boardData = tryParseObfJson((0, io_1.decodeText)(content));
427
+ const boardData = await tryParseObfJson((0, io_1.decodeText)(content));
455
428
  if (boardData) {
456
429
  const page = await this.processBoard(boardData, entryName, true);
457
430
  tree.addPage(page);
@@ -565,6 +538,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
565
538
  };
566
539
  }
567
540
  async processTexts(filePathOrBuffer, translations, outputPath) {
541
+ const { readBinaryFromInput } = this.options.fileAdapter;
568
542
  // Load the tree, apply translations, and save to new file
569
543
  const tree = await this.loadIntoTree(filePathOrBuffer);
570
544
  // Apply translations to all text content
@@ -594,9 +568,10 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
594
568
  });
595
569
  // Save the translated tree and return its content
596
570
  await this.saveFromTree(tree, outputPath);
597
- return (0, io_1.readBinaryFromInput)(outputPath);
571
+ return await readBinaryFromInput(outputPath);
598
572
  }
599
573
  async saveFromTree(tree, outputPath) {
574
+ const { writeTextToPath, writeBinaryToPath, pathExists } = this.options.fileAdapter;
600
575
  if (outputPath.endsWith('.obf')) {
601
576
  // Save as single OBF JSON file
602
577
  const rootPage = tree.rootId ? tree.getPage(tree.rootId) : Object.values(tree.pages)[0];
@@ -604,35 +579,22 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
604
579
  throw new Error('No pages to save');
605
580
  }
606
581
  const obfBoard = this.createObfBoardFromPage(rootPage, 'Exported Board', tree.metadata);
607
- (0, io_1.writeTextToPath)(outputPath, JSON.stringify(obfBoard, null, 2));
582
+ await writeTextToPath(outputPath, JSON.stringify(obfBoard, null, 2));
608
583
  }
609
584
  else {
610
- // Save as OBZ (zip with multiple OBF files)
611
- if ((0, io_1.isNodeRuntime)()) {
612
- const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
613
- const zip = new AdmZip();
614
- Object.values(tree.pages).forEach((page) => {
615
- const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
616
- const obfContent = JSON.stringify(obfBoard, null, 2);
617
- zip.addFile(`${page.id}.obf`, Buffer.from(obfContent, 'utf8'));
618
- });
619
- const zipBuffer = zip.toBuffer();
620
- const { writeBinaryToPath } = await Promise.resolve().then(() => __importStar(require('../utils/io')));
621
- writeBinaryToPath(outputPath, zipBuffer);
622
- }
623
- else {
624
- const module = await Promise.resolve().then(() => __importStar(require('jszip')));
625
- const JSZip = module.default || module;
626
- const zip = new JSZip();
627
- Object.values(tree.pages).forEach((page) => {
628
- const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
629
- const obfContent = JSON.stringify(obfBoard, null, 2);
630
- zip.file(`${page.id}.obf`, obfContent);
631
- });
632
- const zipBuffer = await zip.generateAsync({ type: 'uint8array' });
633
- const { writeBinaryToPath } = await Promise.resolve().then(() => __importStar(require('../utils/io')));
634
- writeBinaryToPath(outputPath, zipBuffer);
635
- }
585
+ const files = Object.values(tree.pages).map((page) => {
586
+ const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
587
+ const obfContent = JSON.stringify(obfBoard, null, 2);
588
+ const name = page.id.endsWith('.obf') ? page.id : `${page.id}.obf`;
589
+ return {
590
+ name,
591
+ data: new TextEncoder().encode(obfContent),
592
+ };
593
+ });
594
+ const fileExists = await pathExists(outputPath);
595
+ this.zipFile = await this.options.zipAdapter(fileExists ? outputPath : undefined, this.options.fileAdapter);
596
+ const zipData = await this.zipFile.writeFiles(files);
597
+ await writeBinaryToPath(outputPath, zipData);
636
598
  }
637
599
  }
638
600
  /**
@@ -656,7 +618,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
656
618
  */
657
619
  async validate(filePath) {
658
620
  const ObfValidator = this.getObfValidator();
659
- return ObfValidator.validateFile(filePath);
621
+ return ObfValidator.validateFile(filePath, this.options.fileAdapter);
660
622
  }
661
623
  /**
662
624
  * Extract symbol information from an OBF/OBZ file for LLM-based translation.
@@ -665,7 +627,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
665
627
  * This method uses shared translation utilities that work across all AAC formats.
666
628
  *
667
629
  * @param filePathOrBuffer - Path to OBF/OBZ file or buffer
668
- * @returns Array of symbol information for LLM processing
630
+ * @returns Promise resolving to symbol information for LLM processing
669
631
  */
670
632
  async extractSymbolsForLLM(filePathOrBuffer) {
671
633
  const tree = await this.loadIntoTree(filePathOrBuffer);
@@ -695,9 +657,10 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
695
657
  * @param llmTranslations - Array of LLM translations with symbol info
696
658
  * @param outputPath - Where to save the translated OBF/OBZ file
697
659
  * @param options - Translation options (e.g., allowPartial for testing)
698
- * @returns Buffer of the translated OBF/OBZ file
660
+ * @returns Promise resolving to a buffer of the translated OBF/OBZ file
699
661
  */
700
662
  async processLLMTranslations(filePathOrBuffer, llmTranslations, outputPath, options) {
663
+ const { readBinaryFromInput } = this.options.fileAdapter;
701
664
  const tree = await this.loadIntoTree(filePathOrBuffer);
702
665
  // Validate translations using shared utility
703
666
  const buttonIds = Object.values(tree.pages).flatMap((page) => page.buttons.map((b) => b.id));
@@ -736,7 +699,7 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
736
699
  });
737
700
  // Save and return
738
701
  await this.saveFromTree(tree, outputPath);
739
- return (0, io_1.readBinaryFromInput)(outputPath);
702
+ return await readBinaryFromInput(outputPath);
740
703
  }
741
704
  getObfValidator() {
742
705
  try {
@@ -8,7 +8,6 @@ exports.ObfsetProcessor = void 0;
8
8
  const treeStructure_1 = require("../core/treeStructure");
9
9
  const treeStructure_2 = require("../core/treeStructure");
10
10
  const baseProcessor_1 = require("../core/baseProcessor");
11
- const io_1 = require("../utils/io");
12
11
  class ObfsetProcessor extends baseProcessor_1.BaseProcessor {
13
12
  constructor(options = {}) {
14
13
  super(options);
@@ -33,10 +32,10 @@ class ObfsetProcessor extends baseProcessor_1.BaseProcessor {
33
32
  * Load an .obfset file (JSON array of boards)
34
33
  */
35
34
  async loadIntoTree(filePathOrBuffer) {
36
- await Promise.resolve();
35
+ const { readTextFromInput } = this.options.fileAdapter;
37
36
  const tree = new treeStructure_1.AACTree();
38
37
  tree.metadata.format = 'obfset';
39
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
38
+ const content = await readTextFromInput(filePathOrBuffer);
40
39
  const boards = JSON.parse(content);
41
40
  // Track board ID mappings
42
41
  const boardMap = new Map();
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpmlProcessor = void 0;
4
4
  const baseProcessor_1 = require("../core/baseProcessor");
5
5
  const treeStructure_1 = require("../core/treeStructure");
6
- // Removed unused import: FileProcessor
7
6
  const fast_xml_parser_1 = require("fast-xml-parser");
8
7
  const validationTypes_1 = require("../validation/validationTypes");
9
8
  const io_1 = require("../utils/io");
@@ -53,8 +52,8 @@ class OpmlProcessor extends baseProcessor_1.BaseProcessor {
53
52
  return { page, childPages };
54
53
  }
55
54
  async extractTexts(filePathOrBuffer) {
56
- await Promise.resolve();
57
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
55
+ const { readTextFromInput } = this.options.fileAdapter;
56
+ const content = await readTextFromInput(filePathOrBuffer);
58
57
  const parser = new fast_xml_parser_1.XMLParser({ ignoreAttributes: false });
59
58
  const data = parser.parse(content);
60
59
  const texts = [];
@@ -85,10 +84,10 @@ class OpmlProcessor extends baseProcessor_1.BaseProcessor {
85
84
  return texts;
86
85
  }
87
86
  async loadIntoTree(filePathOrBuffer) {
88
- await Promise.resolve();
87
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
89
88
  const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.opml';
90
- const buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
91
- const content = (0, io_1.readTextFromInput)(buffer);
89
+ const buffer = await readBinaryFromInput(filePathOrBuffer);
90
+ const content = await readTextFromInput(buffer);
92
91
  try {
93
92
  if (!content || !content.trim()) {
94
93
  const validationResult = (0, validationTypes_1.buildValidationResultFromMessage)({
@@ -171,8 +170,8 @@ class OpmlProcessor extends baseProcessor_1.BaseProcessor {
171
170
  }
172
171
  }
173
172
  async processTexts(filePathOrBuffer, translations, outputPath) {
174
- await Promise.resolve();
175
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
173
+ const { writeBinaryToPath, readTextFromInput } = this.options.fileAdapter;
174
+ const content = await readTextFromInput(filePathOrBuffer);
176
175
  let translatedContent = content;
177
176
  // Apply translations to text attributes in OPML outline elements
178
177
  translations.forEach((translation, originalText) => {
@@ -183,11 +182,11 @@ class OpmlProcessor extends baseProcessor_1.BaseProcessor {
183
182
  }
184
183
  });
185
184
  const resultBuffer = (0, io_1.encodeText)(translatedContent);
186
- (0, io_1.writeBinaryToPath)(outputPath, resultBuffer);
185
+ await writeBinaryToPath(outputPath, resultBuffer);
187
186
  return resultBuffer;
188
187
  }
189
188
  async saveFromTree(tree, outputPath) {
190
- await Promise.resolve();
189
+ const { writeTextToPath } = this.options.fileAdapter;
191
190
  // Helper to recursively build outline nodes with cycle detection
192
191
  function buildOutline(page, visited = new Set()) {
193
192
  // Prevent infinite recursion by tracking visited pages
@@ -257,7 +256,7 @@ class OpmlProcessor extends baseProcessor_1.BaseProcessor {
257
256
  attributeNamePrefix: '@_',
258
257
  });
259
258
  const xml = '<?xml version="1.0" encoding="UTF-8"?>\n' + builder.build(opmlObj);
260
- (0, io_1.writeTextToPath)(outputPath, xml);
259
+ await writeTextToPath(outputPath, xml);
261
260
  }
262
261
  /**
263
262
  * Extract strings with metadata for aac-tools-platform compatibility
@@ -1,5 +1,5 @@
1
1
  import { AACTree, AACSemanticCategory, AACSemanticIntent } from '../../core/treeStructure';
2
- import { ProcessorInput } from '../../utils/io';
2
+ import { FileAdapter, ProcessorInput } from '../../utils/io';
3
3
  /**
4
4
  * Build a map of button IDs to resolved image entries for a specific page.
5
5
  * Mirrors the Grid helper for consumers that expect image reference data.
@@ -16,7 +16,7 @@ export declare function getAllowedImageEntries(tree: AACTree): Set<string>;
16
16
  * @param entryPath Symbol identifier (e.g., "SYM:12345")
17
17
  * @returns Image data buffer or null if not found
18
18
  */
19
- export declare function openImage(dbOrFile: ProcessorInput, entryPath: string): Buffer | null;
19
+ export declare function openImage(dbOrFile: ProcessorInput, entryPath: string, fileAdapter?: FileAdapter): Promise<Buffer | null>;
20
20
  /**
21
21
  * Snap package path information
22
22
  */
@@ -53,14 +53,14 @@ export interface SnapUsageEntry {
53
53
  * @param packageNamePattern Optional pattern to filter package names (default: 'TobiiDynavox')
54
54
  * @returns Array of Snap package path information
55
55
  */
56
- export declare function findSnapPackages(packageNamePattern?: string): SnapPackagePath[];
56
+ export declare function findSnapPackages(packageNamePattern?: string, fileAdapter?: FileAdapter): Promise<SnapPackagePath[]>;
57
57
  /**
58
58
  * Find the first Snap package path matching the pattern
59
59
  * Convenience method for when you expect only one Snap installation
60
60
  * @param packageNamePattern Optional pattern to filter package names (default: 'TobiiDynavox')
61
61
  * @returns Path to the first matching Snap package, or null if not found
62
62
  */
63
- export declare function findSnapPackagePath(packageNamePattern?: string): string | null;
63
+ export declare function findSnapPackagePath(packageNamePattern?: string, fileAdapter?: FileAdapter): Promise<string | null>;
64
64
  /**
65
65
  * Find Snap user directories and their vocab files (.sps/.spb)
66
66
  * Typical path:
@@ -68,14 +68,14 @@ export declare function findSnapPackagePath(packageNamePattern?: string): string
68
68
  * @param packageNamePattern Optional package filter (default TobiiDynavox)
69
69
  * @returns Array of user info with vocab paths
70
70
  */
71
- export declare function findSnapUsers(packageNamePattern?: string): SnapUserInfo[];
71
+ export declare function findSnapUsers(packageNamePattern?: string, fileAdapter?: FileAdapter): Promise<SnapUserInfo[]>;
72
72
  /**
73
73
  * Find vocab files for a specific Snap user (or all users)
74
74
  * @param userId Optional user identifier filter (case-sensitive directory name)
75
75
  * @param packageNamePattern Optional package filter
76
76
  * @returns Array of vocab file paths
77
77
  */
78
- export declare function findSnapUserVocabularies(userId?: string, packageNamePattern?: string): string[];
78
+ export declare function findSnapUserVocabularies(userId?: string, packageNamePattern?: string, fileAdapter?: FileAdapter): Promise<string[]>;
79
79
  /**
80
80
  * Attempt to find history/analytics files for a Snap user by name
81
81
  * Currently searches for files containing "history" under the user directory
@@ -83,7 +83,7 @@ export declare function findSnapUserVocabularies(userId?: string, packageNamePat
83
83
  * @param packageNamePattern Optional package filter
84
84
  * @returns Array of history file paths (may be empty if not found)
85
85
  */
86
- export declare function findSnapUserHistory(userId: string, packageNamePattern?: string): string[];
86
+ export declare function findSnapUserHistory(userId: string, packageNamePattern?: string, fileAdapter?: FileAdapter): Promise<string[]>;
87
87
  /**
88
88
  * Check whether TD Snap appears to be installed (Windows only)
89
89
  */
@@ -91,8 +91,8 @@ export declare function isSnapInstalled(packageNamePattern?: string): boolean;
91
91
  /**
92
92
  * Read Snap usage history from a pageset file (.sps/.spb)
93
93
  */
94
- export declare function readSnapUsage(pagesetPath: string): SnapUsageEntry[];
94
+ export declare function readSnapUsage(pagesetPath: string, fileAdapter?: FileAdapter): Promise<SnapUsageEntry[]>;
95
95
  /**
96
96
  * Read Snap usage history for a user (all pagesets)
97
97
  */
98
- export declare function readSnapUsageForUser(userId?: string, packageNamePattern?: string): SnapUsageEntry[];
98
+ export declare function readSnapUsageForUser(userId?: string, packageNamePattern?: string): Promise<SnapUsageEntry[]>;