@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
package/dist/cli/index.js CHANGED
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
4
  const commander_1 = require("commander");
8
5
  const prettyPrint_1 = require("./prettyPrint");
@@ -10,14 +7,12 @@ const analyze_1 = require("../core/analyze");
10
7
  const history_1 = require("../utilities/analytics/history");
11
8
  const analytics_1 = require("../utilities/analytics");
12
9
  const aac_1 = require("../types/aac");
13
- const path_1 = __importDefault(require("path"));
14
- const fs_1 = __importDefault(require("fs"));
10
+ const io_1 = require("../utils/io");
11
+ const { pathExists, isDirectory, join, readTextFromInput, basename, writeTextToPath } = io_1.defaultFileAdapter;
15
12
  // Helper function to detect format from file/folder path
16
13
  function detectFormat(filePath) {
17
14
  // Check if it's a folder ending with .ascconfig
18
- if (fs_1.default.existsSync(filePath) &&
19
- fs_1.default.statSync(filePath).isDirectory() &&
20
- filePath.endsWith('.ascconfig')) {
15
+ if (pathExists(filePath) && isDirectory(filePath) && filePath.endsWith('.ascconfig')) {
21
16
  return 'ascconfig';
22
17
  }
23
18
  // Map multi-file formats to their base processor
@@ -28,7 +23,7 @@ function detectFormat(filePath) {
28
23
  return 'gridset';
29
24
  }
30
25
  // Otherwise use file extension
31
- return path_1.default.extname(filePath).slice(1);
26
+ return (0, io_1.extname)(filePath).slice(1);
32
27
  }
33
28
  // Helper function to parse filtering options from CLI arguments
34
29
  function parseFilteringOptions(options) {
@@ -66,7 +61,7 @@ function parseFilteringOptions(options) {
66
61
  return processorOptions;
67
62
  }
68
63
  // Set version from package.json
69
- const packageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../../package.json'), 'utf8'));
64
+ const packageJson = JSON.parse(readTextFromInput(join(__dirname, '../../package.json')));
70
65
  commander_1.program.version(packageJson.version);
71
66
  commander_1.program
72
67
  .command('analyze <file>')
@@ -290,12 +285,12 @@ commander_1.program
290
285
  .option('--version <version>', 'Baton export version', '1.0')
291
286
  .action((input, options) => {
292
287
  try {
293
- if (!fs_1.default.existsSync(input)) {
288
+ if (!pathExists(input)) {
294
289
  throw new Error(`File not found: ${input}`);
295
290
  }
296
291
  const normalizedSource = (options.source || 'auto').toLowerCase();
297
- const ext = path_1.default.extname(input).toLowerCase();
298
- const isGrid3Db = ext === '.sqlite' || path_1.default.basename(input).toLowerCase() === 'history.sqlite';
292
+ const ext = (0, io_1.extname)(input).toLowerCase();
293
+ const isGrid3Db = ext === '.sqlite' || basename(input).toLowerCase() === 'history.sqlite';
299
294
  const isSnap = ext === '.sps' || ext === '.spb';
300
295
  let entries;
301
296
  if (normalizedSource === 'grid3' || (normalizedSource === 'auto' && isGrid3Db)) {
@@ -322,7 +317,7 @@ commander_1.program
322
317
  }
323
318
  const output = JSON.stringify(payload, null, 2);
324
319
  if (options.out) {
325
- fs_1.default.writeFileSync(options.out, output);
320
+ writeTextToPath(options.out, output);
326
321
  }
327
322
  else {
328
323
  console.log(output);
@@ -426,7 +421,7 @@ commander_1.program
426
421
  };
427
422
  const output = options.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
428
423
  if (options.out) {
429
- fs_1.default.writeFileSync(options.out, output);
424
+ writeTextToPath(options.out, output);
430
425
  }
431
426
  else {
432
427
  console.log(output);
@@ -42,9 +42,9 @@
42
42
  import { AACTree, AACButton } from './treeStructure';
43
43
  import { StringCasing } from './stringCasing';
44
44
  import { ValidationResult } from '../validation/validationTypes';
45
- import { BinaryOutput, ProcessorInput } from '../utils/io';
46
- import type { ZipAdapter } from '../utils/zip';
47
- export interface ProcessorOptions {
45
+ import { BinaryOutput, FileAdapter, ProcessorInput } from '../utils/io';
46
+ import { ZipAdapter } from '../utils/zip';
47
+ export interface ProcessorConfig {
48
48
  excludeNavigationButtons?: boolean;
49
49
  excludeSystemButtons?: boolean;
50
50
  gridsetPassword?: string;
@@ -53,10 +53,10 @@ export interface ProcessorOptions {
53
53
  grid3SymbolDir?: string;
54
54
  grid3Path?: string;
55
55
  grid3Locale?: string;
56
- zipAdapter?: (input: ProcessorInput) => Promise<{
57
- zip: ZipAdapter;
58
- }>;
56
+ fileAdapter: FileAdapter;
57
+ zipAdapter: (input?: ProcessorInput) => Promise<ZipAdapter>;
59
58
  }
59
+ export type ProcessorOptions = Partial<ProcessorConfig>;
60
60
  export interface ExtractedString {
61
61
  string: string;
62
62
  vocabPlacementMeta: VocabPlacementMetadata;
@@ -89,7 +89,7 @@ export interface SourceString {
89
89
  vocabplacementmetadata: VocabPlacementMetadata;
90
90
  }
91
91
  declare abstract class BaseProcessor {
92
- protected options: ProcessorOptions;
92
+ protected options: ProcessorConfig;
93
93
  constructor(options?: ProcessorOptions);
94
94
  abstract extractTexts(filePathOrBuffer: ProcessorInput): Promise<string[]>;
95
95
  abstract loadIntoTree(filePathOrBuffer: ProcessorInput): Promise<AACTree>;
@@ -44,6 +44,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
44
44
  exports.BaseProcessor = void 0;
45
45
  const treeStructure_1 = require("./treeStructure");
46
46
  const stringCasing_1 = require("./stringCasing");
47
+ const io_1 = require("../utils/io");
48
+ const zip_1 = require("../utils/zip");
47
49
  class BaseProcessor {
48
50
  constructor(options = {}) {
49
51
  // Default configuration: exclude navigation/system buttons
@@ -51,6 +53,8 @@ class BaseProcessor {
51
53
  excludeNavigationButtons: true,
52
54
  excludeSystemButtons: true,
53
55
  preserveAllButtons: false,
56
+ fileAdapter: io_1.defaultFileAdapter,
57
+ zipAdapter: zip_1.getZipAdapter,
54
58
  ...options,
55
59
  };
56
60
  }
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ApplePanelsProcessor = void 0;
7
7
  const baseProcessor_1 = require("../core/baseProcessor");
8
8
  const treeStructure_1 = require("../core/treeStructure");
9
- // Removed unused import: FileProcessor
10
9
  const plist_1 = __importDefault(require("plist"));
11
10
  const validationTypes_1 = require("../validation/validationTypes");
12
11
  const io_1 = require("../utils/io");
@@ -92,17 +91,16 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
92
91
  return texts;
93
92
  }
94
93
  async loadIntoTree(filePathOrBuffer) {
94
+ const { readBinaryFromInput, readTextFromInput, pathExists, getFileSize, join } = this.options.fileAdapter;
95
95
  await Promise.resolve();
96
96
  const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.plist';
97
97
  let buffer;
98
98
  try {
99
99
  if (typeof filePathOrBuffer === 'string') {
100
- const fs = (0, io_1.getFs)();
101
- const path = (0, io_1.getPath)();
102
100
  if (filePathOrBuffer.endsWith('.ascconfig')) {
103
- const panelDefsPath = path.join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
104
- if (fs.existsSync(panelDefsPath)) {
105
- buffer = fs.readFileSync(panelDefsPath);
101
+ const panelDefsPath = join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
102
+ if (pathExists(panelDefsPath)) {
103
+ buffer = readBinaryFromInput(panelDefsPath);
106
104
  }
107
105
  else {
108
106
  const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
@@ -117,13 +115,13 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
117
115
  }
118
116
  }
119
117
  else {
120
- buffer = fs.readFileSync(filePathOrBuffer);
118
+ buffer = readBinaryFromInput(filePathOrBuffer);
121
119
  }
122
120
  }
123
121
  else {
124
- buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
122
+ buffer = readBinaryFromInput(filePathOrBuffer);
125
123
  }
126
- const content = (0, io_1.readTextFromInput)(buffer);
124
+ const content = readTextFromInput(buffer);
127
125
  const parsedData = plist_1.default.parse(content);
128
126
  let panelsData = [];
129
127
  if (Array.isArray(parsedData.panels)) {
@@ -253,10 +251,9 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
253
251
  filename,
254
252
  filesize: typeof filePathOrBuffer === 'string'
255
253
  ? (() => {
256
- const fs = (0, io_1.getFs)();
257
- return fs.existsSync(filePathOrBuffer) ? fs.statSync(filePathOrBuffer).size : 0;
254
+ return pathExists(filePathOrBuffer) ? getFileSize(filePathOrBuffer) : 0;
258
255
  })()
259
- : (0, io_1.readBinaryFromInput)(filePathOrBuffer).byteLength,
256
+ : readBinaryFromInput(filePathOrBuffer).byteLength,
260
257
  format: 'applepanels',
261
258
  message: err?.message || 'Failed to parse Apple Panels file',
262
259
  type: 'parse',
@@ -266,6 +263,7 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
266
263
  }
267
264
  }
268
265
  async processTexts(filePathOrBuffer, translations, outputPath) {
266
+ const { readBinaryFromInput, join } = this.options.fileAdapter;
269
267
  // Load the tree, apply translations, and save to new file
270
268
  const tree = await this.loadIntoTree(filePathOrBuffer);
271
269
  // Apply translations to all text content
@@ -315,14 +313,14 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
315
313
  // Save the translated tree to the requested location and return its content
316
314
  await this.saveFromTree(tree, outputPath);
317
315
  if (outputPath.endsWith('.plist')) {
318
- return (0, io_1.readBinaryFromInput)(outputPath);
316
+ return readBinaryFromInput(outputPath);
319
317
  }
320
- const path = (0, io_1.getPath)();
321
318
  const configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
322
- const panelDefsPath = path.join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
323
- return (0, io_1.readBinaryFromInput)(panelDefsPath);
319
+ const panelDefsPath = join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
320
+ return readBinaryFromInput(panelDefsPath);
324
321
  }
325
322
  async saveFromTree(tree, outputPath) {
323
+ const { writeTextToPath, pathExists, mkDir, join, dirname } = this.options.fileAdapter;
326
324
  await Promise.resolve();
327
325
  // Support two output modes:
328
326
  // 1) Single-file .plist (PanelDefinitions.plist content written directly)
@@ -333,17 +331,15 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
333
331
  let contentsPath = '';
334
332
  let resourcesPath = '';
335
333
  if (!isSinglePlist) {
336
- const fs = (0, io_1.getFs)();
337
- const path = (0, io_1.getPath)();
338
334
  configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
339
- contentsPath = path.join(configPath, 'Contents');
340
- resourcesPath = path.join(contentsPath, 'Resources');
341
- if (!fs.existsSync(configPath))
342
- fs.mkdirSync(configPath, { recursive: true });
343
- if (!fs.existsSync(contentsPath))
344
- fs.mkdirSync(contentsPath, { recursive: true });
345
- if (!fs.existsSync(resourcesPath))
346
- fs.mkdirSync(resourcesPath, { recursive: true });
335
+ contentsPath = join(configPath, 'Contents');
336
+ resourcesPath = join(contentsPath, 'Resources');
337
+ if (!pathExists(configPath))
338
+ mkDir(configPath, { recursive: true });
339
+ if (!pathExists(contentsPath))
340
+ mkDir(contentsPath, { recursive: true });
341
+ if (!pathExists(resourcesPath))
342
+ mkDir(resourcesPath, { recursive: true });
347
343
  // Create Info.plist (bundle mode only)
348
344
  const infoPlist = {
349
345
  ASCConfigurationDisplayName: tree.metadata?.name || 'AAC Processors Export',
@@ -359,10 +355,10 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
359
355
  `Generated by AAC Processors${tree.metadata?.author ? ` - Author: ${tree.metadata.author}` : ''}`,
360
356
  };
361
357
  const infoPlistContent = plist_1.default.build(infoPlist);
362
- (0, io_1.writeTextToPath)(path.join(contentsPath, 'Info.plist'), infoPlistContent);
358
+ writeTextToPath(join(contentsPath, 'Info.plist'), infoPlistContent);
363
359
  // Create AssetIndex.plist (empty)
364
360
  const assetIndexContent = plist_1.default.build({});
365
- (0, io_1.writeTextToPath)(path.join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
361
+ writeTextToPath(join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
366
362
  }
367
363
  // Build PanelDefinitions content from tree
368
364
  const panelsDict = {};
@@ -488,17 +484,14 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
488
484
  const panelDefsContent = plist_1.default.build(panelDefinitions);
489
485
  if (isSinglePlist) {
490
486
  // Write single PanelDefinitions.plist file directly
491
- const fs = (0, io_1.getFs)();
492
- const path = (0, io_1.getPath)();
493
- const dir = path.dirname(outputPath);
494
- if (!fs.existsSync(dir))
495
- fs.mkdirSync(dir, { recursive: true });
496
- (0, io_1.writeTextToPath)(outputPath, panelDefsContent);
487
+ const dir = dirname(outputPath);
488
+ if (!pathExists(dir))
489
+ mkDir(dir, { recursive: true });
490
+ writeTextToPath(outputPath, panelDefsContent);
497
491
  }
498
492
  else {
499
493
  // Write into bundle structure
500
- const path = (0, io_1.getPath)();
501
- (0, io_1.writeTextToPath)(path.join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
494
+ writeTextToPath(join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
502
495
  }
503
496
  }
504
497
  createApplePanelsAction(button) {
@@ -579,7 +579,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
579
579
  return texts;
580
580
  }
581
581
  extractRawTexts(filePathOrBuffer) {
582
- let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
582
+ const { readTextFromInput } = this.options.fileAdapter;
583
+ let content = readTextFromInput(filePathOrBuffer);
583
584
  // Remove BOM if present
584
585
  if (content.charCodeAt(0) === 0xfeff) {
585
586
  content = content.slice(1);
@@ -659,12 +660,13 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
659
660
  }
660
661
  }
661
662
  async loadIntoTree(filePathOrBuffer) {
663
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
662
664
  await Promise.resolve();
663
665
  const tree = new treeStructure_1.AACTree();
664
666
  const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.grd';
665
- const buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
667
+ const buffer = readBinaryFromInput(filePathOrBuffer);
666
668
  try {
667
- let content = (0, io_1.readTextFromInput)(buffer);
669
+ let content = readTextFromInput(buffer);
668
670
  // Remove BOM if present
669
671
  if (content.charCodeAt(0) === 0xfeff) {
670
672
  content = content.slice(1);
@@ -1057,8 +1059,9 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1057
1059
  });
1058
1060
  }
1059
1061
  async processTexts(filePathOrBuffer, translations, outputPath) {
1062
+ const { readTextFromInput, readBinaryFromInput, writeTextToPath } = this.options.fileAdapter;
1060
1063
  await Promise.resolve();
1061
- let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1064
+ let content = readTextFromInput(filePathOrBuffer);
1062
1065
  // Remove BOM if present
1063
1066
  if (content.charCodeAt(0) === 0xfeff) {
1064
1067
  content = content.slice(1);
@@ -1067,8 +1070,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1067
1070
  // Apply translations directly to the JSON structure for comprehensive coverage
1068
1071
  this.applyTranslationsToGridFile(grdFile, translations);
1069
1072
  // Write the translated file
1070
- (0, io_1.writeTextToPath)(outputPath, JSON.stringify(grdFile, null, 2));
1071
- return (0, io_1.readBinaryFromInput)(outputPath);
1073
+ writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1074
+ return readBinaryFromInput(outputPath);
1072
1075
  }
1073
1076
  applyTranslationsToGridFile(grdFile, translations) {
1074
1077
  grdFile.grids.forEach((grid) => {
@@ -1180,6 +1183,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1180
1183
  }
1181
1184
  }
1182
1185
  async saveFromTree(tree, outputPath) {
1186
+ const { writeTextToPath } = this.options.fileAdapter;
1183
1187
  await Promise.resolve();
1184
1188
  // Use default Asterics Grid styling instead of taking from first page
1185
1189
  // This prevents issues where the first page has unusual colors (like purple)
@@ -1383,13 +1387,14 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1383
1387
  },
1384
1388
  },
1385
1389
  };
1386
- (0, io_1.writeTextToPath)(outputPath, JSON.stringify(grdFile, null, 2));
1390
+ writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1387
1391
  }
1388
1392
  /**
1389
1393
  * Add audio recording to a specific grid element
1390
1394
  */
1391
1395
  addAudioToElement(filePath, elementId, audioData, metadata) {
1392
- let content = (0, io_1.readTextFromInput)(filePath);
1396
+ const { readTextFromInput, writeTextToPath } = this.options.fileAdapter;
1397
+ let content = readTextFromInput(filePath);
1393
1398
  // Remove BOM if present
1394
1399
  if (content.charCodeAt(0) === 0xfeff) {
1395
1400
  content = content.slice(1);
@@ -1432,15 +1437,15 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1432
1437
  throw new Error(`Element with ID ${elementId} not found`);
1433
1438
  }
1434
1439
  // Write back to file
1435
- (0, io_1.writeTextToPath)(filePath, JSON.stringify(grdFile, null, 2));
1440
+ writeTextToPath(filePath, JSON.stringify(grdFile, null, 2));
1436
1441
  }
1437
1442
  /**
1438
1443
  * Create a copy of the grid file with audio recordings added
1439
1444
  */
1440
1445
  createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
1446
+ const { writeBinaryToPath, readBinaryFromInput } = this.options.fileAdapter;
1441
1447
  // Copy the source file to target
1442
- const fs = (0, io_1.getFs)();
1443
- fs.copyFileSync(sourceFilePath, targetFilePath);
1448
+ writeBinaryToPath(targetFilePath, readBinaryFromInput(sourceFilePath));
1444
1449
  // Add audio recordings to the copy
1445
1450
  audioMappings.forEach((audioInfo, elementId) => {
1446
1451
  try {
@@ -1456,7 +1461,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1456
1461
  * Extract all element IDs from the grid file for audio mapping
1457
1462
  */
1458
1463
  getElementIds(filePathOrBuffer) {
1459
- let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1464
+ const { readTextFromInput } = this.options.fileAdapter;
1465
+ let content = readTextFromInput(filePathOrBuffer);
1460
1466
  // Remove BOM if present
1461
1467
  if (content.charCodeAt(0) === 0xfeff) {
1462
1468
  content = content.slice(1);
@@ -1479,7 +1485,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1479
1485
  * Check if an element has audio recording
1480
1486
  */
1481
1487
  hasAudioRecording(filePathOrBuffer, elementId) {
1482
- let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1488
+ const { readTextFromInput } = this.options.fileAdapter;
1489
+ let content = readTextFromInput(filePathOrBuffer);
1483
1490
  // Remove BOM if present
1484
1491
  if (content.charCodeAt(0) === 0xfeff) {
1485
1492
  content = content.slice(1);
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DotProcessor = 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 validationTypes_1 = require("../validation/validationTypes");
8
7
  const io_1 = require("../utils/io");
9
8
  class DotProcessor extends baseProcessor_1.BaseProcessor {
@@ -52,8 +51,9 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
52
51
  return { nodes: Array.from(nodes.values()), edges };
53
52
  }
54
53
  async extractTexts(filePathOrBuffer) {
54
+ const { readTextFromInput } = this.options.fileAdapter;
55
55
  await Promise.resolve();
56
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
56
+ const content = readTextFromInput(filePathOrBuffer);
57
57
  const { nodes, edges } = this.parseDotFile(content);
58
58
  const texts = [];
59
59
  // Collect node labels
@@ -69,12 +69,13 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
69
69
  return texts;
70
70
  }
71
71
  async loadIntoTree(filePathOrBuffer) {
72
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
72
73
  await Promise.resolve();
73
74
  const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.dot';
74
- const buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
75
+ const buffer = readBinaryFromInput(filePathOrBuffer);
75
76
  const filesize = buffer.byteLength;
76
77
  try {
77
- const content = (0, io_1.readTextFromInput)(buffer);
78
+ const content = readTextFromInput(buffer);
78
79
  if (!content || content.trim().length === 0) {
79
80
  const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
80
81
  filename,
@@ -158,8 +159,9 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
158
159
  }
159
160
  }
160
161
  async processTexts(filePathOrBuffer, translations, outputPath) {
162
+ const { readTextFromInput, writeBinaryToPath } = this.options.fileAdapter;
161
163
  await Promise.resolve();
162
- const content = (0, io_1.readTextFromInput)(filePathOrBuffer);
164
+ const content = readTextFromInput(filePathOrBuffer);
163
165
  let translatedContent = content;
164
166
  translations.forEach((translation, text) => {
165
167
  if (typeof text === 'string' && typeof translation === 'string') {
@@ -170,10 +172,11 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
170
172
  }
171
173
  });
172
174
  const resultBuffer = (0, io_1.encodeText)(translatedContent || '');
173
- (0, io_1.writeBinaryToPath)(outputPath, resultBuffer);
175
+ writeBinaryToPath(outputPath, resultBuffer);
174
176
  return resultBuffer;
175
177
  }
176
178
  async saveFromTree(tree, _outputPath) {
179
+ const { writeTextToPath } = this.options.fileAdapter;
177
180
  await Promise.resolve();
178
181
  let dotContent = `digraph "${tree.metadata?.name || 'AACBoard'}" {\n`;
179
182
  // Helper to escape DOT string
@@ -204,7 +207,7 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
204
207
  });
205
208
  }
206
209
  dotContent += '}\n';
207
- (0, io_1.writeTextToPath)(_outputPath, dotContent);
210
+ writeTextToPath(_outputPath, dotContent);
208
211
  }
209
212
  /**
210
213
  * Extract strings with metadata for aac-tools-platform compatibility
@@ -22,13 +22,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.ExcelProcessor = void 0;
30
- const fs_1 = __importDefault(require("fs"));
31
- const path_1 = __importDefault(require("path"));
32
27
  const ExcelJS = __importStar(require("exceljs"));
33
28
  const baseProcessor_1 = require("../core/baseProcessor");
34
29
  const treeStructure_1 = require("../core/treeStructure");
@@ -68,11 +63,12 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
68
63
  * @returns Buffer containing the translated Excel file
69
64
  */
70
65
  async processTexts(_filePathOrBuffer, _translations, outputPath) {
66
+ const { dirname, pathExists, mkDir } = this.options.fileAdapter;
71
67
  await Promise.resolve();
72
68
  console.warn('ExcelProcessor.processTexts is not implemented yet.');
73
- const outputDir = path_1.default.dirname(outputPath);
74
- if (!fs_1.default.existsSync(outputDir)) {
75
- fs_1.default.mkdirSync(outputDir, { recursive: true });
69
+ const outputDir = dirname(outputPath);
70
+ if (!pathExists(outputDir)) {
71
+ mkDir(outputDir, { recursive: true });
76
72
  }
77
73
  return Buffer.alloc(0);
78
74
  }
@@ -468,8 +464,9 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
468
464
  * Note: This method is async but maintains the sync interface for compatibility
469
465
  */
470
466
  async saveFromTree(tree, outputPath) {
471
- const outputDir = path_1.default.dirname(outputPath);
472
- fs_1.default.mkdirSync(outputDir, { recursive: true });
467
+ const { mkDir, dirname, writeTextToPath } = this.options.fileAdapter;
468
+ const outputDir = dirname(outputPath);
469
+ mkDir(outputDir, { recursive: true });
473
470
  try {
474
471
  await this.saveFromTreeAsync(tree, outputPath);
475
472
  }
@@ -478,8 +475,8 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
478
475
  console.error('Failed to save Excel file:', message);
479
476
  try {
480
477
  const fallbackPath = outputPath.replace(/\.xlsx$/i, '_error.txt');
481
- fs_1.default.mkdirSync(path_1.default.dirname(fallbackPath), { recursive: true });
482
- fs_1.default.writeFileSync(fallbackPath, `Error saving Excel file: ${message}`);
478
+ mkDir(dirname(fallbackPath), { recursive: true });
479
+ writeTextToPath(fallbackPath, `Error saving Excel file: ${message}`);
483
480
  }
484
481
  catch (writeError) {
485
482
  console.error('Failed to write Excel error file:', writeError);
@@ -1,6 +1,6 @@
1
1
  import { AACTree, AACSemanticCategory, AACSemanticIntent } from '../../core/treeStructure';
2
- import { type ZipAdapter } from '../../utils/zip';
3
- import type { ProcessorInput } from '../../utils/io';
2
+ import { FileAdapter, ProcessorInput } from '../../utils/io';
3
+ import { ZipAdapter } from '../../utils/zip';
4
4
  /**
5
5
  * Build a map of button IDs to resolved image entry paths for a specific page.
6
6
  * Helpful when rewriting zip entry names or validating images referenced in a grid.
@@ -17,9 +17,7 @@ export declare function getAllowedImageEntries(tree: AACTree): Set<string>;
17
17
  * @param entryPath Entry name inside the zip
18
18
  * @returns Image data buffer or null if not found
19
19
  */
20
- export declare function openImage(gridsetBuffer: Uint8Array, entryPath: string, password?: string | undefined, zipAdapter?: (input: ProcessorInput) => Promise<{
21
- zip: ZipAdapter;
22
- }>): Promise<Uint8Array | null>;
20
+ export declare function openImage(gridsetBuffer: Uint8Array, entryPath: string, password?: string | undefined, fileAdapter?: FileAdapter, zipAdapter?: (input?: ProcessorInput) => Promise<ZipAdapter>): Promise<Uint8Array | null>;
23
21
  /**
24
22
  * Generate a random GUID for Grid3 elements
25
23
  * Grid3 uses GUIDs for grid identification
@@ -90,13 +88,13 @@ export declare function getCommonDocumentsPath(): string;
90
88
  * C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
91
89
  * @returns Array of Grid3 user path information
92
90
  */
93
- export declare function findGrid3UserPaths(): Grid3UserPath[];
91
+ export declare function findGrid3UserPaths(fileAdapter?: FileAdapter): Grid3UserPath[];
94
92
  /**
95
93
  * Find all Grid3 history database paths
96
94
  * Convenience method that returns just the database file paths
97
95
  * @returns Array of paths to history.sqlite files
98
96
  */
99
- export declare function findGrid3HistoryDatabases(): string[];
97
+ export declare function findGrid3HistoryDatabases(fileAdapter?: FileAdapter): string[];
100
98
  /**
101
99
  * Get Grid 3 users (alias of findGrid3UserPaths for clarity)
102
100
  */
@@ -106,24 +104,24 @@ export declare function findGrid3Users(): Grid3UserPath[];
106
104
  * @param userName Optional user filter; matches case-insensitively
107
105
  * @returns Array of user/gridset path pairs
108
106
  */
109
- export declare function findGrid3Vocabularies(userName?: string): Grid3VocabularyPath[];
107
+ export declare function findGrid3Vocabularies(userName?: string, fileAdapter?: FileAdapter): Grid3VocabularyPath[];
110
108
  /**
111
109
  * Find a specific user's Grid 3 history database
112
110
  * @param userName User name to search for (case-insensitive)
113
111
  * @param langCode Optional language code filter (case-insensitive)
114
112
  * @returns Path to history.sqlite or null if not found
115
113
  */
116
- export declare function findGrid3UserHistory(userName: string, langCode?: string): string | null;
114
+ export declare function findGrid3UserHistory(userName: string, langCode?: string, fileAdapter?: FileAdapter): string | null;
117
115
  /**
118
116
  * Check whether Grid 3 appears to be installed (Windows only)
119
117
  */
120
- export declare function isGrid3Installed(): boolean;
118
+ export declare function isGrid3Installed(fileAdapter?: FileAdapter): boolean;
121
119
  /**
122
120
  * Read history events from a Grid 3 history.sqlite database.
123
121
  * @param historyDbPath Absolute path to the history database
124
122
  * @returns Parsed history entries grouped by phrase
125
123
  */
126
- export declare function readGrid3History(historyDbPath: string): Grid3HistoryEntry[];
124
+ export declare function readGrid3History(historyDbPath: string, fileAdapter?: FileAdapter): Grid3HistoryEntry[];
127
125
  /**
128
126
  * Convenience wrapper to load history for a specific Grid 3 user/lang combination.
129
127
  * @param userName Grid 3 user name (case-insensitive)