@willwade/aac-processors 0.0.29 → 0.1.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 (92) hide show
  1. package/README.md +52 -852
  2. package/dist/browser/core/baseProcessor.js +241 -0
  3. package/dist/browser/core/stringCasing.js +179 -0
  4. package/dist/browser/core/treeStructure.js +255 -0
  5. package/dist/browser/index.browser.js +73 -0
  6. package/dist/browser/processors/applePanelsProcessor.js +582 -0
  7. package/dist/browser/processors/astericsGridProcessor.js +1509 -0
  8. package/dist/browser/processors/dotProcessor.js +221 -0
  9. package/dist/browser/processors/gridset/commands.js +962 -0
  10. package/dist/browser/processors/gridset/crypto.js +53 -0
  11. package/dist/browser/processors/gridset/password.js +43 -0
  12. package/dist/browser/processors/gridset/pluginTypes.js +277 -0
  13. package/dist/browser/processors/gridset/resolver.js +137 -0
  14. package/dist/browser/processors/gridset/symbolAlignment.js +276 -0
  15. package/dist/browser/processors/gridset/symbols.js +421 -0
  16. package/dist/browser/processors/gridsetProcessor.js +2002 -0
  17. package/dist/browser/processors/obfProcessor.js +705 -0
  18. package/dist/browser/processors/opmlProcessor.js +274 -0
  19. package/dist/browser/types/aac.js +38 -0
  20. package/dist/browser/utilities/analytics/utils/idGenerator.js +89 -0
  21. package/dist/browser/utilities/translation/translationProcessor.js +200 -0
  22. package/dist/browser/utils/io.js +95 -0
  23. package/dist/browser/validation/baseValidator.js +156 -0
  24. package/dist/browser/validation/gridsetValidator.js +355 -0
  25. package/dist/browser/validation/obfValidator.js +500 -0
  26. package/dist/browser/validation/validationTypes.js +46 -0
  27. package/dist/cli/index.js +5 -5
  28. package/dist/core/analyze.d.ts +2 -2
  29. package/dist/core/analyze.js +2 -2
  30. package/dist/core/baseProcessor.d.ts +5 -4
  31. package/dist/core/baseProcessor.js +22 -27
  32. package/dist/core/treeStructure.d.ts +5 -5
  33. package/dist/core/treeStructure.js +1 -4
  34. package/dist/index.browser.d.ts +37 -0
  35. package/dist/index.browser.js +99 -0
  36. package/dist/index.d.ts +1 -48
  37. package/dist/index.js +1 -136
  38. package/dist/index.node.d.ts +48 -0
  39. package/dist/index.node.js +152 -0
  40. package/dist/processors/applePanelsProcessor.d.ts +5 -4
  41. package/dist/processors/applePanelsProcessor.js +58 -62
  42. package/dist/processors/astericsGridProcessor.d.ts +7 -6
  43. package/dist/processors/astericsGridProcessor.js +31 -42
  44. package/dist/processors/dotProcessor.d.ts +5 -4
  45. package/dist/processors/dotProcessor.js +25 -33
  46. package/dist/processors/excelProcessor.d.ts +4 -3
  47. package/dist/processors/excelProcessor.js +6 -3
  48. package/dist/processors/gridset/crypto.d.ts +18 -0
  49. package/dist/processors/gridset/crypto.js +57 -0
  50. package/dist/processors/gridset/helpers.d.ts +1 -1
  51. package/dist/processors/gridset/helpers.js +18 -8
  52. package/dist/processors/gridset/password.d.ts +20 -3
  53. package/dist/processors/gridset/password.js +17 -3
  54. package/dist/processors/gridset/wordlistHelpers.d.ts +3 -3
  55. package/dist/processors/gridset/wordlistHelpers.js +21 -20
  56. package/dist/processors/gridsetProcessor.d.ts +7 -12
  57. package/dist/processors/gridsetProcessor.js +118 -77
  58. package/dist/processors/obfProcessor.d.ts +9 -7
  59. package/dist/processors/obfProcessor.js +131 -56
  60. package/dist/processors/obfsetProcessor.d.ts +5 -4
  61. package/dist/processors/obfsetProcessor.js +10 -16
  62. package/dist/processors/opmlProcessor.d.ts +5 -4
  63. package/dist/processors/opmlProcessor.js +27 -34
  64. package/dist/processors/snapProcessor.d.ts +8 -7
  65. package/dist/processors/snapProcessor.js +15 -12
  66. package/dist/processors/touchchatProcessor.d.ts +8 -7
  67. package/dist/processors/touchchatProcessor.js +22 -17
  68. package/dist/types/aac.d.ts +0 -2
  69. package/dist/types/aac.js +2 -0
  70. package/dist/utils/io.d.ts +12 -0
  71. package/dist/utils/io.js +107 -0
  72. package/dist/validation/gridsetValidator.js +7 -7
  73. package/dist/validation/snapValidator.js +28 -35
  74. package/docs/BROWSER_USAGE.md +618 -0
  75. package/examples/README.md +77 -0
  76. package/examples/browser-test-server.js +81 -0
  77. package/examples/browser-test.html +331 -0
  78. package/examples/vitedemo/QUICKSTART.md +74 -0
  79. package/examples/vitedemo/README.md +157 -0
  80. package/examples/vitedemo/index.html +376 -0
  81. package/examples/vitedemo/package-lock.json +1221 -0
  82. package/examples/vitedemo/package.json +18 -0
  83. package/examples/vitedemo/src/main.ts +519 -0
  84. package/examples/vitedemo/test-files/example.dot +14 -0
  85. package/examples/vitedemo/test-files/example.grd +1 -0
  86. package/examples/vitedemo/test-files/example.gridset +0 -0
  87. package/examples/vitedemo/test-files/example.obz +0 -0
  88. package/examples/vitedemo/test-files/example.opml +18 -0
  89. package/examples/vitedemo/test-files/simple.obf +53 -0
  90. package/examples/vitedemo/tsconfig.json +24 -0
  91. package/examples/vitedemo/vite.config.ts +34 -0
  92. package/package.json +20 -4
@@ -1,13 +1,14 @@
1
1
  import { BaseProcessor, ProcessorOptions, ExtractStringsResult, TranslatedString, SourceString } from '../core/baseProcessor';
2
2
  import { AACTree } from '../core/treeStructure';
3
+ import { ProcessorInput } from '../utils/io';
3
4
  declare class ApplePanelsProcessor extends BaseProcessor {
4
5
  constructor(options?: ProcessorOptions);
5
6
  private parseRect;
6
7
  private pixelToGrid;
7
- extractTexts(filePathOrBuffer: string | Buffer): string[];
8
- loadIntoTree(filePathOrBuffer: string | Buffer): AACTree;
9
- processTexts(filePathOrBuffer: string | Buffer, translations: Map<string, string>, outputPath: string): Buffer;
10
- saveFromTree(tree: AACTree, outputPath: string): void;
8
+ extractTexts(filePathOrBuffer: ProcessorInput): Promise<string[]>;
9
+ loadIntoTree(filePathOrBuffer: ProcessorInput): Promise<AACTree>;
10
+ processTexts(filePathOrBuffer: ProcessorInput, translations: Map<string, string>, outputPath: string): Promise<Uint8Array>;
11
+ saveFromTree(tree: AACTree, outputPath: string): Promise<void>;
11
12
  private createApplePanelsAction;
12
13
  /**
13
14
  * Extract strings with metadata for aac-tools-platform compatibility
@@ -8,9 +8,8 @@ const baseProcessor_1 = require("../core/baseProcessor");
8
8
  const treeStructure_1 = require("../core/treeStructure");
9
9
  // Removed unused import: FileProcessor
10
10
  const plist_1 = __importDefault(require("plist"));
11
- const fs_1 = __importDefault(require("fs"));
12
- const path_1 = __importDefault(require("path"));
13
- const validation_1 = require("../validation");
11
+ const validationTypes_1 = require("../validation/validationTypes");
12
+ const io_1 = require("../utils/io");
14
13
  function isNormalizedPanel(panel) {
15
14
  return typeof panel.id === 'string';
16
15
  }
@@ -76,8 +75,8 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
76
75
  gridY: Math.floor(pixelY / cellSize),
77
76
  };
78
77
  }
79
- extractTexts(filePathOrBuffer) {
80
- const tree = this.loadIntoTree(filePathOrBuffer);
78
+ async extractTexts(filePathOrBuffer) {
79
+ const tree = await this.loadIntoTree(filePathOrBuffer);
81
80
  const texts = [];
82
81
  for (const pageId in tree.pages) {
83
82
  const page = tree.pages[pageId];
@@ -92,21 +91,21 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
92
91
  }
93
92
  return texts;
94
93
  }
95
- loadIntoTree(filePathOrBuffer) {
96
- const filename = typeof filePathOrBuffer === 'string' ? path_1.default.basename(filePathOrBuffer) : 'upload.plist';
94
+ async loadIntoTree(filePathOrBuffer) {
95
+ await Promise.resolve();
96
+ const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.plist';
97
97
  let buffer;
98
98
  try {
99
- if (Buffer.isBuffer(filePathOrBuffer)) {
100
- buffer = filePathOrBuffer;
101
- }
102
- else if (typeof filePathOrBuffer === 'string') {
99
+ if (typeof filePathOrBuffer === 'string') {
100
+ const fs = (0, io_1.getFs)();
101
+ const path = (0, io_1.getPath)();
103
102
  if (filePathOrBuffer.endsWith('.ascconfig')) {
104
- const panelDefsPath = `${filePathOrBuffer}/Contents/Resources/PanelDefinitions.plist`;
105
- if (fs_1.default.existsSync(panelDefsPath)) {
106
- buffer = fs_1.default.readFileSync(panelDefsPath);
103
+ const panelDefsPath = path.join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
104
+ if (fs.existsSync(panelDefsPath)) {
105
+ buffer = fs.readFileSync(panelDefsPath);
107
106
  }
108
107
  else {
109
- const validation = (0, validation_1.buildValidationResultFromMessage)({
108
+ const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
110
109
  filename,
111
110
  filesize: 0,
112
111
  format: 'applepanels',
@@ -114,25 +113,17 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
114
113
  type: 'missing',
115
114
  description: 'PanelDefinitions.plist',
116
115
  });
117
- throw new validation_1.ValidationFailureError('Apple Panels file not found', validation);
116
+ throw new validationTypes_1.ValidationFailureError('Apple Panels file not found', validation);
118
117
  }
119
118
  }
120
119
  else {
121
- buffer = fs_1.default.readFileSync(filePathOrBuffer);
120
+ buffer = fs.readFileSync(filePathOrBuffer);
122
121
  }
123
122
  }
124
123
  else {
125
- const validation = (0, validation_1.buildValidationResultFromMessage)({
126
- filename,
127
- filesize: 0,
128
- format: 'applepanels',
129
- message: 'Invalid input: expected string path or Buffer',
130
- type: 'input',
131
- description: 'Apple Panels input',
132
- });
133
- throw new validation_1.ValidationFailureError('Invalid Apple Panels input', validation);
124
+ buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
134
125
  }
135
- const content = buffer.toString('utf8');
126
+ const content = (0, io_1.readTextFromInput)(buffer);
136
127
  const parsedData = plist_1.default.parse(content);
137
128
  let panelsData = [];
138
129
  if (Array.isArray(parsedData.panels)) {
@@ -154,7 +145,7 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
154
145
  });
155
146
  }
156
147
  if (panelsData.length === 0) {
157
- const validation = (0, validation_1.buildValidationResultFromMessage)({
148
+ const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
158
149
  filename,
159
150
  filesize: buffer.byteLength,
160
151
  format: 'applepanels',
@@ -162,7 +153,7 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
162
153
  type: 'structure',
163
154
  description: 'Panels definition',
164
155
  });
165
- throw new validation_1.ValidationFailureError('Apple Panels has no panels', validation);
156
+ throw new validationTypes_1.ValidationFailureError('Apple Panels has no panels', validation);
166
157
  }
167
158
  const data = { panels: panelsData };
168
159
  const tree = new treeStructure_1.AACTree();
@@ -255,29 +246,28 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
255
246
  return tree;
256
247
  }
257
248
  catch (err) {
258
- if (err instanceof validation_1.ValidationFailureError) {
249
+ if (err instanceof validationTypes_1.ValidationFailureError) {
259
250
  throw err;
260
251
  }
261
- const validation = (0, validation_1.buildValidationResultFromMessage)({
252
+ const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
262
253
  filename,
263
- filesize: Buffer.isBuffer(filePathOrBuffer)
264
- ? filePathOrBuffer.byteLength
265
- : typeof filePathOrBuffer === 'string'
266
- ? fs_1.default.existsSync(filePathOrBuffer)
267
- ? fs_1.default.statSync(filePathOrBuffer).size
268
- : 0
269
- : 0,
254
+ filesize: typeof filePathOrBuffer === 'string'
255
+ ? (() => {
256
+ const fs = (0, io_1.getFs)();
257
+ return fs.existsSync(filePathOrBuffer) ? fs.statSync(filePathOrBuffer).size : 0;
258
+ })()
259
+ : (0, io_1.readBinaryFromInput)(filePathOrBuffer).byteLength,
270
260
  format: 'applepanels',
271
261
  message: err?.message || 'Failed to parse Apple Panels file',
272
262
  type: 'parse',
273
263
  description: 'Parse Apple Panels plist',
274
264
  });
275
- throw new validation_1.ValidationFailureError('Failed to load Apple Panels file', validation, err);
265
+ throw new validationTypes_1.ValidationFailureError('Failed to load Apple Panels file', validation, err);
276
266
  }
277
267
  }
278
- processTexts(filePathOrBuffer, translations, outputPath) {
268
+ async processTexts(filePathOrBuffer, translations, outputPath) {
279
269
  // Load the tree, apply translations, and save to new file
280
- const tree = this.loadIntoTree(filePathOrBuffer);
270
+ const tree = await this.loadIntoTree(filePathOrBuffer);
281
271
  // Apply translations to all text content
282
272
  Object.values(tree.pages).forEach((page) => {
283
273
  // Translate page names
@@ -323,16 +313,17 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
323
313
  });
324
314
  });
325
315
  // Save the translated tree to the requested location and return its content
326
- this.saveFromTree(tree, outputPath);
316
+ await this.saveFromTree(tree, outputPath);
327
317
  if (outputPath.endsWith('.plist')) {
328
- return fs_1.default.readFileSync(outputPath);
318
+ return (0, io_1.readBinaryFromInput)(outputPath);
329
319
  }
330
- // In bundle mode, return the PanelDefinitions.plist content
320
+ const path = (0, io_1.getPath)();
331
321
  const configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
332
- const panelDefsPath = path_1.default.join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
333
- return fs_1.default.readFileSync(panelDefsPath);
322
+ const panelDefsPath = path.join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
323
+ return (0, io_1.readBinaryFromInput)(panelDefsPath);
334
324
  }
335
- saveFromTree(tree, outputPath) {
325
+ async saveFromTree(tree, outputPath) {
326
+ await Promise.resolve();
336
327
  // Support two output modes:
337
328
  // 1) Single-file .plist (PanelDefinitions.plist content written directly)
338
329
  // 2) Apple Panels bundle folder (*.ascconfig) with Contents/Resources structure
@@ -342,15 +333,17 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
342
333
  let contentsPath = '';
343
334
  let resourcesPath = '';
344
335
  if (!isSinglePlist) {
336
+ const fs = (0, io_1.getFs)();
337
+ const path = (0, io_1.getPath)();
345
338
  configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
346
- contentsPath = path_1.default.join(configPath, 'Contents');
347
- resourcesPath = path_1.default.join(contentsPath, 'Resources');
348
- if (!fs_1.default.existsSync(configPath))
349
- fs_1.default.mkdirSync(configPath, { recursive: true });
350
- if (!fs_1.default.existsSync(contentsPath))
351
- fs_1.default.mkdirSync(contentsPath, { recursive: true });
352
- if (!fs_1.default.existsSync(resourcesPath))
353
- fs_1.default.mkdirSync(resourcesPath, { recursive: true });
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 });
354
347
  // Create Info.plist (bundle mode only)
355
348
  const infoPlist = {
356
349
  ASCConfigurationDisplayName: tree.metadata?.name || 'AAC Processors Export',
@@ -366,10 +359,10 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
366
359
  `Generated by AAC Processors${tree.metadata?.author ? ` - Author: ${tree.metadata.author}` : ''}`,
367
360
  };
368
361
  const infoPlistContent = plist_1.default.build(infoPlist);
369
- fs_1.default.writeFileSync(path_1.default.join(contentsPath, 'Info.plist'), infoPlistContent);
362
+ (0, io_1.writeTextToPath)(path.join(contentsPath, 'Info.plist'), infoPlistContent);
370
363
  // Create AssetIndex.plist (empty)
371
364
  const assetIndexContent = plist_1.default.build({});
372
- fs_1.default.writeFileSync(path_1.default.join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
365
+ (0, io_1.writeTextToPath)(path.join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
373
366
  }
374
367
  // Build PanelDefinitions content from tree
375
368
  const panelsDict = {};
@@ -495,14 +488,17 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
495
488
  const panelDefsContent = plist_1.default.build(panelDefinitions);
496
489
  if (isSinglePlist) {
497
490
  // Write single PanelDefinitions.plist file directly
498
- const dir = path_1.default.dirname(outputPath);
499
- if (!fs_1.default.existsSync(dir))
500
- fs_1.default.mkdirSync(dir, { recursive: true });
501
- fs_1.default.writeFileSync(outputPath, panelDefsContent);
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);
502
497
  }
503
498
  else {
504
499
  // Write into bundle structure
505
- fs_1.default.writeFileSync(path_1.default.join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
500
+ const path = (0, io_1.getPath)();
501
+ (0, io_1.writeTextToPath)(path.join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
506
502
  }
507
503
  }
508
504
  createApplePanelsAction(button) {
@@ -1,5 +1,6 @@
1
1
  import { BaseProcessor, ProcessorOptions, ExtractStringsResult, TranslatedString, SourceString } from '../core/baseProcessor';
2
2
  import { AACTree } from '../core/treeStructure';
3
+ import { ProcessorInput } from '../utils/io';
3
4
  export declare function normalizeHexColor(hexColor: string): string | null;
4
5
  export declare function adjustHexColor(hexColor: string, amount: number): string;
5
6
  export declare function getHighContrastNeutralColor(backgroundColor: string): string;
@@ -20,17 +21,17 @@ declare class AstericsGridProcessor extends BaseProcessor {
20
21
  constructor(options?: ProcessorOptions & {
21
22
  loadAudio?: boolean;
22
23
  });
23
- extractTexts(filePathOrBuffer: string | Buffer): string[];
24
+ extractTexts(filePathOrBuffer: ProcessorInput): Promise<string[]>;
24
25
  private extractRawTexts;
25
26
  private extractActionTexts;
26
- loadIntoTree(filePathOrBuffer: string | Buffer): AACTree;
27
+ loadIntoTree(filePathOrBuffer: ProcessorInput): Promise<AACTree>;
27
28
  private getLocalizedLabel;
28
29
  private getLocalizedText;
29
30
  private createButtonFromElement;
30
- processTexts(filePathOrBuffer: string | Buffer, translations: Map<string, string>, outputPath: string): Buffer;
31
+ processTexts(filePathOrBuffer: ProcessorInput, translations: Map<string, string>, outputPath: string): Promise<Uint8Array>;
31
32
  private applyTranslationsToGridFile;
32
33
  private applyTranslationsToAction;
33
- saveFromTree(tree: AACTree, outputPath: string): void;
34
+ saveFromTree(tree: AACTree, outputPath: string): Promise<void>;
34
35
  /**
35
36
  * Add audio recording to a specific grid element
36
37
  */
@@ -45,11 +46,11 @@ declare class AstericsGridProcessor extends BaseProcessor {
45
46
  /**
46
47
  * Extract all element IDs from the grid file for audio mapping
47
48
  */
48
- getElementIds(filePathOrBuffer: string | Buffer): string[];
49
+ getElementIds(filePathOrBuffer: ProcessorInput): string[];
49
50
  /**
50
51
  * Check if an element has audio recording
51
52
  */
52
- hasAudioRecording(filePathOrBuffer: string | Buffer, elementId: string): boolean;
53
+ hasAudioRecording(filePathOrBuffer: ProcessorInput, elementId: string): boolean;
53
54
  /**
54
55
  * Extract strings with metadata for aac-tools-platform compatibility
55
56
  * Uses the generic implementation from BaseProcessor
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.AstericsGridProcessor = void 0;
7
4
  exports.normalizeHexColor = normalizeHexColor;
@@ -11,9 +8,8 @@ exports.calculateLuminance = calculateLuminance;
11
8
  exports.getContrastingTextColor = getContrastingTextColor;
12
9
  const baseProcessor_1 = require("../core/baseProcessor");
13
10
  const treeStructure_1 = require("../core/treeStructure");
14
- const fs_1 = __importDefault(require("fs"));
15
- const path_1 = __importDefault(require("path"));
16
- const validation_1 = require("../validation");
11
+ const validationTypes_1 = require("../validation/validationTypes");
12
+ const io_1 = require("../utils/io");
17
13
  const DEFAULT_COLOR_SCHEME_DEFINITIONS = [
18
14
  {
19
15
  name: 'CS_MODIFIED_FITZGERALD_KEY_VERY_LIGHT',
@@ -559,8 +555,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
559
555
  this.loadAudio = false;
560
556
  this.loadAudio = options.loadAudio || false;
561
557
  }
562
- extractTexts(filePathOrBuffer) {
563
- const tree = this.loadIntoTree(filePathOrBuffer);
558
+ async extractTexts(filePathOrBuffer) {
559
+ const tree = await this.loadIntoTree(filePathOrBuffer);
564
560
  const texts = [];
565
561
  for (const pageId in tree.pages) {
566
562
  const page = tree.pages[pageId];
@@ -583,9 +579,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
583
579
  return texts;
584
580
  }
585
581
  extractRawTexts(filePathOrBuffer) {
586
- let content = Buffer.isBuffer(filePathOrBuffer)
587
- ? filePathOrBuffer.toString('utf-8')
588
- : fs_1.default.readFileSync(filePathOrBuffer, 'utf-8');
582
+ let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
589
583
  // Remove BOM if present
590
584
  if (content.charCodeAt(0) === 0xfeff) {
591
585
  content = content.slice(1);
@@ -664,21 +658,20 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
664
658
  // Add more action types as needed
665
659
  }
666
660
  }
667
- loadIntoTree(filePathOrBuffer) {
661
+ async loadIntoTree(filePathOrBuffer) {
662
+ await Promise.resolve();
668
663
  const tree = new treeStructure_1.AACTree();
669
- const filename = typeof filePathOrBuffer === 'string' ? path_1.default.basename(filePathOrBuffer) : 'upload.grd';
670
- const buffer = Buffer.isBuffer(filePathOrBuffer)
671
- ? filePathOrBuffer
672
- : fs_1.default.readFileSync(filePathOrBuffer);
664
+ const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.grd';
665
+ const buffer = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
673
666
  try {
674
- let content = buffer.toString('utf-8');
667
+ let content = (0, io_1.readTextFromInput)(buffer);
675
668
  // Remove BOM if present
676
669
  if (content.charCodeAt(0) === 0xfeff) {
677
670
  content = content.slice(1);
678
671
  }
679
672
  const grdFile = JSON.parse(content);
680
673
  if (!grdFile.grids) {
681
- const validationResult = (0, validation_1.buildValidationResultFromMessage)({
674
+ const validationResult = (0, validationTypes_1.buildValidationResultFromMessage)({
682
675
  filename,
683
676
  filesize: buffer.byteLength,
684
677
  format: 'asterics',
@@ -686,7 +679,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
686
679
  type: 'structure',
687
680
  description: 'Asterics grid collection',
688
681
  });
689
- throw new validation_1.ValidationFailureError('Invalid Asterics grid file', validationResult);
682
+ throw new validationTypes_1.ValidationFailureError('Invalid Asterics grid file', validationResult);
690
683
  }
691
684
  const rawColorConfig = grdFile.metadata?.colorConfig;
692
685
  const colorConfig = isRecord(rawColorConfig)
@@ -783,10 +776,10 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
783
776
  return tree;
784
777
  }
785
778
  catch (err) {
786
- if (err instanceof validation_1.ValidationFailureError) {
779
+ if (err instanceof validationTypes_1.ValidationFailureError) {
787
780
  throw err;
788
781
  }
789
- const validationResult = (0, validation_1.buildValidationResultFromMessage)({
782
+ const validationResult = (0, validationTypes_1.buildValidationResultFromMessage)({
790
783
  filename,
791
784
  filesize: buffer.byteLength,
792
785
  format: 'asterics',
@@ -794,7 +787,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
794
787
  type: 'parse',
795
788
  description: 'Parse Asterics grid JSON',
796
789
  });
797
- throw new validation_1.ValidationFailureError('Failed to load Asterics grid', validationResult, err);
790
+ throw new validationTypes_1.ValidationFailureError('Failed to load Asterics grid', validationResult, err);
798
791
  }
799
792
  }
800
793
  getLocalizedLabel(labelMap) {
@@ -1063,11 +1056,9 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1063
1056
  },
1064
1057
  });
1065
1058
  }
1066
- processTexts(filePathOrBuffer, translations, outputPath) {
1067
- // Load and parse the original file
1068
- let content = Buffer.isBuffer(filePathOrBuffer)
1069
- ? filePathOrBuffer.toString('utf-8')
1070
- : fs_1.default.readFileSync(filePathOrBuffer, 'utf-8');
1059
+ async processTexts(filePathOrBuffer, translations, outputPath) {
1060
+ await Promise.resolve();
1061
+ let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1071
1062
  // Remove BOM if present
1072
1063
  if (content.charCodeAt(0) === 0xfeff) {
1073
1064
  content = content.slice(1);
@@ -1076,8 +1067,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1076
1067
  // Apply translations directly to the JSON structure for comprehensive coverage
1077
1068
  this.applyTranslationsToGridFile(grdFile, translations);
1078
1069
  // Write the translated file
1079
- fs_1.default.writeFileSync(outputPath, JSON.stringify(grdFile, null, 2));
1080
- return fs_1.default.readFileSync(outputPath);
1070
+ (0, io_1.writeTextToPath)(outputPath, JSON.stringify(grdFile, null, 2));
1071
+ return (0, io_1.readBinaryFromInput)(outputPath);
1081
1072
  }
1082
1073
  applyTranslationsToGridFile(grdFile, translations) {
1083
1074
  grdFile.grids.forEach((grid) => {
@@ -1188,7 +1179,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1188
1179
  // Add more action types as needed
1189
1180
  }
1190
1181
  }
1191
- saveFromTree(tree, outputPath) {
1182
+ async saveFromTree(tree, outputPath) {
1183
+ await Promise.resolve();
1192
1184
  // Use default Asterics Grid styling instead of taking from first page
1193
1185
  // This prevents issues where the first page has unusual colors (like purple)
1194
1186
  const defaultPageStyle = {
@@ -1321,7 +1313,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1321
1313
  id: button.audioRecording.id?.toString() || `grid-action-audio-${button.id}`,
1322
1314
  modelName: 'GridActionAudio',
1323
1315
  modelVersion: '{"major": 5, "minor": 0, "patch": 0}',
1324
- dataBase64: button.audioRecording.data.toString('base64'),
1316
+ dataBase64: (0, io_1.encodeBase64)(button.audioRecording.data),
1325
1317
  mimeType: metadata.mimeType || 'audio/wav',
1326
1318
  durationMs: metadata.durationMs || 0,
1327
1319
  filename: button.audioRecording.identifier || `audio-${button.id}`,
@@ -1391,13 +1383,13 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1391
1383
  },
1392
1384
  },
1393
1385
  };
1394
- fs_1.default.writeFileSync(outputPath, JSON.stringify(grdFile, null, 2));
1386
+ (0, io_1.writeTextToPath)(outputPath, JSON.stringify(grdFile, null, 2));
1395
1387
  }
1396
1388
  /**
1397
1389
  * Add audio recording to a specific grid element
1398
1390
  */
1399
1391
  addAudioToElement(filePath, elementId, audioData, metadata) {
1400
- let content = fs_1.default.readFileSync(filePath, 'utf-8');
1392
+ let content = (0, io_1.readTextFromInput)(filePath);
1401
1393
  // Remove BOM if present
1402
1394
  if (content.charCodeAt(0) === 0xfeff) {
1403
1395
  content = content.slice(1);
@@ -1416,7 +1408,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1416
1408
  id: `grid-action-audio-${elementId}`,
1417
1409
  modelName: 'GridActionAudio',
1418
1410
  modelVersion: '{"major": 5, "minor": 0, "patch": 0}',
1419
- dataBase64: audioData.toString('base64'),
1411
+ dataBase64: (0, io_1.encodeBase64)(audioData),
1420
1412
  mimeType: 'audio/wav',
1421
1413
  durationMs: 0, // Could be calculated from audio data
1422
1414
  filename: `audio-${elementId}.wav`,
@@ -1440,14 +1432,15 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1440
1432
  throw new Error(`Element with ID ${elementId} not found`);
1441
1433
  }
1442
1434
  // Write back to file
1443
- fs_1.default.writeFileSync(filePath, JSON.stringify(grdFile, null, 2));
1435
+ (0, io_1.writeTextToPath)(filePath, JSON.stringify(grdFile, null, 2));
1444
1436
  }
1445
1437
  /**
1446
1438
  * Create a copy of the grid file with audio recordings added
1447
1439
  */
1448
1440
  createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
1449
1441
  // Copy the source file to target
1450
- fs_1.default.copyFileSync(sourceFilePath, targetFilePath);
1442
+ const fs = (0, io_1.getFs)();
1443
+ fs.copyFileSync(sourceFilePath, targetFilePath);
1451
1444
  // Add audio recordings to the copy
1452
1445
  audioMappings.forEach((audioInfo, elementId) => {
1453
1446
  try {
@@ -1463,9 +1456,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1463
1456
  * Extract all element IDs from the grid file for audio mapping
1464
1457
  */
1465
1458
  getElementIds(filePathOrBuffer) {
1466
- let content = Buffer.isBuffer(filePathOrBuffer)
1467
- ? filePathOrBuffer.toString('utf-8')
1468
- : fs_1.default.readFileSync(filePathOrBuffer, 'utf-8');
1459
+ let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1469
1460
  // Remove BOM if present
1470
1461
  if (content.charCodeAt(0) === 0xfeff) {
1471
1462
  content = content.slice(1);
@@ -1488,9 +1479,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
1488
1479
  * Check if an element has audio recording
1489
1480
  */
1490
1481
  hasAudioRecording(filePathOrBuffer, elementId) {
1491
- let content = Buffer.isBuffer(filePathOrBuffer)
1492
- ? filePathOrBuffer.toString('utf-8')
1493
- : fs_1.default.readFileSync(filePathOrBuffer, 'utf-8');
1482
+ let content = (0, io_1.readTextFromInput)(filePathOrBuffer);
1494
1483
  // Remove BOM if present
1495
1484
  if (content.charCodeAt(0) === 0xfeff) {
1496
1485
  content = content.slice(1);
@@ -1,12 +1,13 @@
1
1
  import { BaseProcessor, ProcessorOptions, ExtractStringsResult, TranslatedString, SourceString } from '../core/baseProcessor';
2
2
  import { AACTree } from '../core/treeStructure';
3
+ import { ProcessorInput } from '../utils/io';
3
4
  declare class DotProcessor extends BaseProcessor {
4
5
  constructor(options?: ProcessorOptions);
5
6
  private parseDotFile;
6
- extractTexts(filePathOrBuffer: string | Buffer): string[];
7
- loadIntoTree(filePathOrBuffer: string | Buffer): AACTree;
8
- processTexts(filePathOrBuffer: string | Buffer, translations: Map<string, string>, outputPath: string): Buffer;
9
- saveFromTree(tree: AACTree, _outputPath: string): void;
7
+ extractTexts(filePathOrBuffer: ProcessorInput): Promise<string[]>;
8
+ loadIntoTree(filePathOrBuffer: ProcessorInput): Promise<AACTree>;
9
+ processTexts(filePathOrBuffer: ProcessorInput, translations: Map<string, string>, outputPath: string): Promise<Uint8Array>;
10
+ saveFromTree(tree: AACTree, _outputPath: string): Promise<void>;
10
11
  /**
11
12
  * Extract strings with metadata for aac-tools-platform compatibility
12
13
  * Uses the generic implementation from BaseProcessor