@willwade/aac-processors 0.1.21 → 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 (85) hide show
  1. package/dist/browser/processors/applePanelsProcessor.js +24 -24
  2. package/dist/browser/processors/astericsGridProcessor.js +22 -24
  3. package/dist/browser/processors/dotProcessor.js +6 -10
  4. package/dist/browser/processors/gridset/helpers.js +33 -30
  5. package/dist/browser/processors/gridset/symbolExtractor.js +2 -2
  6. package/dist/browser/processors/gridset/symbolSearch.js +22 -22
  7. package/dist/browser/processors/gridset/symbols.js +14 -14
  8. package/dist/browser/processors/gridsetProcessor.js +7 -7
  9. package/dist/browser/processors/obfProcessor.js +24 -25
  10. package/dist/browser/processors/opmlProcessor.js +6 -10
  11. package/dist/browser/processors/snap/helpers.js +34 -30
  12. package/dist/browser/processors/snapProcessor.js +28 -28
  13. package/dist/browser/processors/touchchatProcessor.js +24 -25
  14. package/dist/browser/utilities/analytics/history.js +24 -18
  15. package/dist/browser/utilities/analytics/metrics/comparison.js +16 -16
  16. package/dist/browser/utilities/analytics/metrics/vocabulary.js +2 -2
  17. package/dist/browser/utilities/analytics/reference/browser.js +16 -16
  18. package/dist/browser/utilities/analytics/reference/index.js +25 -24
  19. package/dist/browser/utils/io.js +29 -25
  20. package/dist/browser/utils/sqlite.js +5 -5
  21. package/dist/browser/utils/zip.js +2 -4
  22. package/dist/browser/validation/gridsetValidator.js +2 -2
  23. package/dist/browser/validation/obfValidator.js +2 -2
  24. package/dist/browser/validation/snapValidator.js +3 -3
  25. package/dist/browser/validation/touchChatValidator.js +3 -3
  26. package/dist/cli/index.js +19 -16
  27. package/dist/core/baseProcessor.d.ts +1 -1
  28. package/dist/processors/applePanelsProcessor.js +24 -24
  29. package/dist/processors/astericsGridProcessor.d.ts +4 -4
  30. package/dist/processors/astericsGridProcessor.js +22 -24
  31. package/dist/processors/dotProcessor.js +6 -10
  32. package/dist/processors/excelProcessor.d.ts +3 -3
  33. package/dist/processors/excelProcessor.js +10 -13
  34. package/dist/processors/gridset/helpers.d.ts +9 -9
  35. package/dist/processors/gridset/helpers.js +33 -30
  36. package/dist/processors/gridset/symbolExtractor.d.ts +1 -1
  37. package/dist/processors/gridset/symbolExtractor.js +2 -2
  38. package/dist/processors/gridset/symbolSearch.d.ts +10 -10
  39. package/dist/processors/gridset/symbolSearch.js +22 -22
  40. package/dist/processors/gridset/symbols.d.ts +3 -3
  41. package/dist/processors/gridset/symbols.js +14 -14
  42. package/dist/processors/gridsetProcessor.d.ts +2 -2
  43. package/dist/processors/gridsetProcessor.js +7 -7
  44. package/dist/processors/obfProcessor.d.ts +2 -2
  45. package/dist/processors/obfProcessor.js +24 -25
  46. package/dist/processors/obfsetProcessor.js +1 -2
  47. package/dist/processors/opmlProcessor.js +6 -10
  48. package/dist/processors/snap/helpers.d.ts +8 -8
  49. package/dist/processors/snap/helpers.js +34 -30
  50. package/dist/processors/snapProcessor.d.ts +2 -2
  51. package/dist/processors/snapProcessor.js +28 -28
  52. package/dist/processors/touchchatProcessor.d.ts +2 -2
  53. package/dist/processors/touchchatProcessor.js +24 -25
  54. package/dist/types/aac.d.ts +2 -2
  55. package/dist/utilities/analytics/history.d.ts +8 -8
  56. package/dist/utilities/analytics/history.js +24 -18
  57. package/dist/utilities/analytics/index.d.ts +1 -1
  58. package/dist/utilities/analytics/index.js +3 -2
  59. package/dist/utilities/analytics/metrics/comparison.d.ts +1 -1
  60. package/dist/utilities/analytics/metrics/comparison.js +16 -16
  61. package/dist/utilities/analytics/metrics/vocabulary.d.ts +1 -1
  62. package/dist/utilities/analytics/metrics/vocabulary.js +2 -2
  63. package/dist/utilities/analytics/reference/browser.d.ts +9 -9
  64. package/dist/utilities/analytics/reference/browser.js +16 -16
  65. package/dist/utilities/analytics/reference/index.d.ts +21 -21
  66. package/dist/utilities/analytics/reference/index.js +25 -24
  67. package/dist/utilities/symbolTools.d.ts +5 -5
  68. package/dist/utilities/symbolTools.js +10 -8
  69. package/dist/utils/io.d.ts +11 -11
  70. package/dist/utils/io.js +29 -25
  71. package/dist/utils/sqlite.d.ts +1 -1
  72. package/dist/utils/sqlite.js +5 -5
  73. package/dist/utils/zip.js +2 -4
  74. package/dist/validation/applePanelsValidator.js +7 -6
  75. package/dist/validation/astericsValidator.js +2 -2
  76. package/dist/validation/dotValidator.js +2 -2
  77. package/dist/validation/excelValidator.js +2 -2
  78. package/dist/validation/gridsetValidator.js +2 -2
  79. package/dist/validation/index.js +2 -2
  80. package/dist/validation/obfValidator.js +2 -2
  81. package/dist/validation/obfsetValidator.js +2 -2
  82. package/dist/validation/opmlValidator.js +2 -2
  83. package/dist/validation/snapValidator.js +3 -3
  84. package/dist/validation/touchChatValidator.js +3 -3
  85. package/package.json +1 -1
@@ -21,46 +21,46 @@ export class ReferenceLoader {
21
21
  /**
22
22
  * Load core vocabulary lists
23
23
  */
24
- loadCoreLists() {
24
+ async loadCoreLists() {
25
25
  const { readTextFromInput } = this.fileAdapter;
26
26
  const filePath = this.fileAdapter.join(this.dataDir, `core_lists.${this.locale}.json`);
27
- const content = readTextFromInput(filePath);
27
+ const content = await readTextFromInput(filePath);
28
28
  return JSON.parse(String(content));
29
29
  }
30
30
  /**
31
31
  * Load common words with baseline effort scores
32
32
  */
33
- loadCommonWords() {
33
+ async loadCommonWords() {
34
34
  const { readTextFromInput, join } = this.fileAdapter;
35
35
  const filePath = join(this.dataDir, `common_words.${this.locale}.json`);
36
- const content = readTextFromInput(filePath);
36
+ const content = await readTextFromInput(filePath);
37
37
  return JSON.parse(String(content));
38
38
  }
39
39
  /**
40
40
  * Load synonym mappings
41
41
  */
42
- loadSynonyms() {
42
+ async loadSynonyms() {
43
43
  const { readTextFromInput, join } = this.fileAdapter;
44
44
  const filePath = join(this.dataDir, `synonyms.${this.locale}.json`);
45
- const content = readTextFromInput(filePath);
45
+ const content = await readTextFromInput(filePath);
46
46
  return JSON.parse(String(content));
47
47
  }
48
48
  /**
49
49
  * Load test sentences
50
50
  */
51
- loadSentences() {
51
+ async loadSentences() {
52
52
  const { readTextFromInput, join } = this.fileAdapter;
53
53
  const filePath = join(this.dataDir, `sentences.${this.locale}.json`);
54
- const content = readTextFromInput(filePath);
54
+ const content = await readTextFromInput(filePath);
55
55
  return JSON.parse(String(content));
56
56
  }
57
57
  /**
58
58
  * Load fringe vocabulary
59
59
  */
60
- loadFringe() {
60
+ async loadFringe() {
61
61
  const { readTextFromInput, join } = this.fileAdapter;
62
62
  const filePath = join(this.dataDir, `fringe.${this.locale}.json`);
63
- const content = readTextFromInput(filePath);
63
+ const content = await readTextFromInput(filePath);
64
64
  const data = JSON.parse(String(content));
65
65
  // Flatten nested category words if needed
66
66
  if (Array.isArray(data) && data.length > 0 && data[0].categories) {
@@ -77,10 +77,10 @@ export class ReferenceLoader {
77
77
  /**
78
78
  * Load base words hash map
79
79
  */
80
- loadBaseWords() {
80
+ async loadBaseWords() {
81
81
  const { readTextFromInput, join } = this.fileAdapter;
82
82
  const filePath = join(this.dataDir, `base_words.${this.locale}.json`);
83
- const content = readTextFromInput(filePath);
83
+ const content = await readTextFromInput(filePath);
84
84
  return JSON.parse(String(content));
85
85
  }
86
86
  /**
@@ -88,10 +88,10 @@ export class ReferenceLoader {
88
88
  * Common words that are NOT in core vocabulary lists
89
89
  * (matching Ruby loader.rb:413-420)
90
90
  */
91
- loadCommonFringe() {
92
- const commonWordsData = this.loadCommonWords();
91
+ async loadCommonFringe() {
92
+ const commonWordsData = await this.loadCommonWords();
93
93
  const commonWords = new Set(commonWordsData.words.map((w) => w.toLowerCase()));
94
- const coreLists = this.loadCoreLists();
94
+ const coreLists = await this.loadCoreLists();
95
95
  const coreWords = new Set();
96
96
  coreLists.forEach((list) => {
97
97
  list.words.forEach((word) => coreWords.add(word.toLowerCase()));
@@ -103,14 +103,14 @@ export class ReferenceLoader {
103
103
  /**
104
104
  * Get all reference data at once
105
105
  */
106
- loadAll() {
106
+ async loadAll() {
107
107
  return {
108
- coreLists: this.loadCoreLists(),
109
- commonWords: this.loadCommonWords(),
110
- synonyms: this.loadSynonyms(),
111
- sentences: this.loadSentences(),
112
- fringe: this.loadFringe(),
113
- baseWords: this.loadBaseWords(),
108
+ coreLists: await this.loadCoreLists(),
109
+ commonWords: await this.loadCommonWords(),
110
+ synonyms: await this.loadSynonyms(),
111
+ sentences: await this.loadSentences(),
112
+ fringe: await this.loadFringe(),
113
+ baseWords: await this.loadBaseWords(),
114
114
  };
115
115
  }
116
116
  }
@@ -123,7 +123,7 @@ export function getReferenceDataPath(fileAdapter = defaultFileAdapter) {
123
123
  /**
124
124
  * Check if reference data files exist
125
125
  */
126
- export function hasReferenceData(fileAdapter = defaultFileAdapter) {
126
+ export async function hasReferenceData(fileAdapter = defaultFileAdapter) {
127
127
  const { pathExists, join } = fileAdapter;
128
128
  const dataPath = getReferenceDataPath();
129
129
  const requiredFiles = [
@@ -133,5 +133,6 @@ export function hasReferenceData(fileAdapter = defaultFileAdapter) {
133
133
  'synonyms.en.json',
134
134
  'fringe.en.json',
135
135
  ];
136
- return requiredFiles.every((file) => pathExists(join(dataPath, file)));
136
+ const existingPaths = await Promise.all(requiredFiles.map(async (file) => await pathExists(join(dataPath, file))));
137
+ return existingPaths.every((exists) => exists);
137
138
  }
@@ -24,7 +24,7 @@ function getFs() {
24
24
  if (!cachedFs) {
25
25
  try {
26
26
  const nodeRequire = getNodeRequire();
27
- const fsModule = 'fs';
27
+ const fsModule = 'node:fs';
28
28
  cachedFs = nodeRequire(fsModule);
29
29
  }
30
30
  catch {
@@ -121,57 +121,61 @@ export function extname(path) {
121
121
  const tail = splitDeviceRe.exec(path)?.at(3) ?? '';
122
122
  return splitTailRe.exec(tail)?.at(3) ?? '';
123
123
  }
124
- function readBinaryFromInput(input) {
124
+ async function readBinaryFromInput(input) {
125
125
  if (typeof input === 'string') {
126
- return getFs().readFileSync(input);
126
+ return Promise.resolve(getFs().readFileSync(input));
127
127
  }
128
128
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
129
- return input;
129
+ return Promise.resolve(input);
130
130
  }
131
131
  if (input instanceof ArrayBuffer) {
132
- return new Uint8Array(input);
132
+ return Promise.resolve(new Uint8Array(input));
133
133
  }
134
- return input;
134
+ return Promise.resolve(input);
135
135
  }
136
- function readTextFromInput(input, encoding = 'utf8') {
136
+ async function readTextFromInput(input, encoding = 'utf8') {
137
137
  if (typeof input === 'string') {
138
- return getFs().readFileSync(input, encoding);
138
+ return Promise.resolve(getFs().readFileSync(input, encoding));
139
139
  }
140
140
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
141
- return input.toString(encoding);
141
+ return Promise.resolve(input.toString(encoding));
142
142
  }
143
143
  if (input instanceof ArrayBuffer) {
144
- return decodeText(new Uint8Array(input));
144
+ return Promise.resolve(decodeText(new Uint8Array(input)));
145
145
  }
146
- return decodeText(input);
146
+ return Promise.resolve(decodeText(input));
147
147
  }
148
- function writeBinaryToPath(outputPath, data) {
148
+ async function writeBinaryToPath(outputPath, data) {
149
149
  getFs().writeFileSync(outputPath, data);
150
+ await Promise.resolve();
150
151
  }
151
- function writeTextToPath(outputPath, text) {
152
+ async function writeTextToPath(outputPath, text) {
152
153
  getFs().writeFileSync(outputPath, text, 'utf8');
154
+ await Promise.resolve();
153
155
  }
154
- function pathExists(path) {
155
- return getFs().existsSync(path);
156
+ async function pathExists(path) {
157
+ return Promise.resolve(getFs().existsSync(path));
156
158
  }
157
- function isDirectory(path) {
158
- return getFs().statSync(path).isDirectory();
159
+ async function isDirectory(path) {
160
+ return Promise.resolve(getFs().statSync(path).isDirectory());
159
161
  }
160
- function getFileSize(path) {
161
- return getFs().statSync(path).size;
162
+ async function getFileSize(path) {
163
+ return Promise.resolve(getFs().statSync(path).size);
162
164
  }
163
- function mkDir(path, options) {
165
+ async function mkDir(path, options) {
164
166
  getFs().mkdirSync(path, options);
167
+ await Promise.resolve();
165
168
  }
166
- function listDir(path) {
167
- return getFs().readdirSync(path);
169
+ async function listDir(path) {
170
+ return Promise.resolve(getFs().readdirSync(path));
168
171
  }
169
- function removePath(path, options) {
172
+ async function removePath(path, options) {
170
173
  getFs().rmSync(path, options);
174
+ await Promise.resolve();
171
175
  }
172
- function mkTempDir(prefix) {
176
+ async function mkTempDir(prefix) {
173
177
  const path = join(getOs().tmpdir(), prefix);
174
- return getFs().mkdtempSync(path);
178
+ return Promise.resolve(getFs().mkdtempSync(path));
175
179
  }
176
180
  function join(...pathParts) {
177
181
  return getPath().join(...pathParts);
@@ -79,24 +79,24 @@ export async function openSqliteDatabase(input, options = {}) {
79
79
  const db = new Database(input, { readonly: options.readonly ?? true });
80
80
  return { db };
81
81
  }
82
- const data = readBinaryFromInput(input);
82
+ const data = await readBinaryFromInput(input);
83
83
  if (!isNodeRuntime()) {
84
84
  const SQL = await getSqlJs();
85
85
  const db = new SQL.Database(data);
86
86
  return { db: createSqlJsAdapter(db) };
87
87
  }
88
- const tempDir = mkTempDir('aac-sqlite-');
88
+ const tempDir = await mkTempDir('aac-sqlite-');
89
89
  const dbPath = join(tempDir, 'input.sqlite');
90
- writeBinaryToPath(dbPath, data);
90
+ await writeBinaryToPath(dbPath, data);
91
91
  const Database = getBetterSqlite3();
92
92
  const db = new Database(dbPath, { readonly: options.readonly ?? true });
93
- const cleanup = () => {
93
+ const cleanup = async () => {
94
94
  try {
95
95
  db.close();
96
96
  }
97
97
  finally {
98
98
  try {
99
- removePath(tempDir, { recursive: true, force: true });
99
+ await removePath(tempDir, { recursive: true, force: true });
100
100
  }
101
101
  catch (error) {
102
102
  console.warn('Failed to clean up temporary SQLite files:', error);
@@ -7,7 +7,7 @@ export async function getZipAdapter(input, fileAdapter) {
7
7
  ? new AdmZip(input)
8
8
  : typeof input === 'string'
9
9
  ? new AdmZip(input)
10
- : new AdmZip(Buffer.from(adapter.readBinaryFromInput(input)));
10
+ : new AdmZip(Buffer.from(await adapter.readBinaryFromInput(input)));
11
11
  return {
12
12
  listFiles: () => {
13
13
  return zip
@@ -31,9 +31,7 @@ export async function getZipAdapter(input, fileAdapter) {
31
31
  }
32
32
  const module = await import('jszip');
33
33
  const JSZip = module.default || module;
34
- if (input !== undefined && typeof input === 'string')
35
- throw new Error('Zip file paths are not supported in browser environments.');
36
- const zip = input ? await JSZip.loadAsync(adapter.readBinaryFromInput(input)) : new JSZip();
34
+ const zip = input ? await JSZip.loadAsync(await adapter.readBinaryFromInput(input)) : new JSZip();
37
35
  return {
38
36
  listFiles: () => {
39
37
  return Object.entries(zip.files)
@@ -17,8 +17,8 @@ export class GridsetValidator extends BaseValidator {
17
17
  static async validateFile(filePath, fileAdapter) {
18
18
  const { readBinaryFromInput, getFileSize } = fileAdapter ?? defaultFileAdapter;
19
19
  const validator = new GridsetValidator();
20
- const content = readBinaryFromInput(filePath);
21
- const size = getFileSize(filePath);
20
+ const content = await readBinaryFromInput(filePath);
21
+ const size = await getFileSize(filePath);
22
22
  return validator.validate(content, getBasename(filePath), size);
23
23
  }
24
24
  /**
@@ -21,8 +21,8 @@ export class ObfValidator extends BaseValidator {
21
21
  static async validateFile(filePath, fileAdapter) {
22
22
  const { readBinaryFromInput, getFileSize } = fileAdapter ?? defaultFileAdapter;
23
23
  const validator = new ObfValidator();
24
- const content = readBinaryFromInput(filePath);
25
- const size = getFileSize(filePath);
24
+ const content = await readBinaryFromInput(filePath);
25
+ const size = await getFileSize(filePath);
26
26
  return validator.validate(content, getBasename(filePath), size);
27
27
  }
28
28
  /**
@@ -19,8 +19,8 @@ export class SnapValidator extends BaseValidator {
19
19
  static async validateFile(filePath, fileAdapter) {
20
20
  const { readBinaryFromInput, getFileSize } = fileAdapter ?? defaultFileAdapter;
21
21
  const validator = new SnapValidator();
22
- const content = readBinaryFromInput(filePath);
23
- const size = getFileSize(filePath);
22
+ const content = await readBinaryFromInput(filePath);
23
+ const size = await getFileSize(filePath);
24
24
  return validator.validate(content, getBasename(filePath), size);
25
25
  }
26
26
  /**
@@ -209,7 +209,7 @@ export class SnapValidator extends BaseValidator {
209
209
  }
210
210
  finally {
211
211
  if (cleanup) {
212
- cleanup();
212
+ await cleanup();
213
213
  }
214
214
  }
215
215
  });
@@ -21,8 +21,8 @@ export class TouchChatValidator extends BaseValidator {
21
21
  static async validateFile(filePath, fileAdapter) {
22
22
  const { readBinaryFromInput, getFileSize } = fileAdapter ?? defaultFileAdapter;
23
23
  const validator = new TouchChatValidator();
24
- const content = readBinaryFromInput(filePath);
25
- const size = getFileSize(filePath);
24
+ const content = await readBinaryFromInput(filePath);
25
+ const size = await getFileSize(filePath);
26
26
  return validator.validate(content, getBasename(filePath), size);
27
27
  }
28
28
  /**
@@ -335,7 +335,7 @@ export class TouchChatValidator extends BaseValidator {
335
335
  }
336
336
  finally {
337
337
  if (cleanup) {
338
- cleanup();
338
+ await cleanup();
339
339
  }
340
340
  }
341
341
  });
package/dist/cli/index.js CHANGED
@@ -8,11 +8,14 @@ const history_1 = require("../utilities/analytics/history");
8
8
  const analytics_1 = require("../utilities/analytics");
9
9
  const aac_1 = require("../types/aac");
10
10
  const io_1 = require("../utils/io");
11
- const { pathExists, isDirectory, join, readTextFromInput, basename, writeTextToPath } = io_1.defaultFileAdapter;
11
+ const node_fs_1 = require("node:fs");
12
+ const { pathExists, isDirectory, join, basename, writeTextToPath } = io_1.defaultFileAdapter;
12
13
  // Helper function to detect format from file/folder path
13
- function detectFormat(filePath) {
14
+ async function detectFormat(filePath) {
14
15
  // Check if it's a folder ending with .ascconfig
15
- if (pathExists(filePath) && isDirectory(filePath) && filePath.endsWith('.ascconfig')) {
16
+ if ((await pathExists(filePath)) &&
17
+ (await isDirectory(filePath)) &&
18
+ filePath.endsWith('.ascconfig')) {
16
19
  return 'ascconfig';
17
20
  }
18
21
  // Map multi-file formats to their base processor
@@ -61,7 +64,7 @@ function parseFilteringOptions(options) {
61
64
  return processorOptions;
62
65
  }
63
66
  // Set version from package.json
64
- const packageJson = JSON.parse(readTextFromInput(join(__dirname, '../../package.json')));
67
+ const packageJson = JSON.parse((0, node_fs_1.readFileSync)(join(__dirname, '../../package.json'), 'utf8'));
65
68
  commander_1.program.version(packageJson.version);
66
69
  commander_1.program
67
70
  .command('analyze <file>')
@@ -77,7 +80,7 @@ commander_1.program
77
80
  // Parse filtering options
78
81
  const filteringOptions = parseFilteringOptions(options);
79
82
  // Auto-detect format if not specified
80
- const format = options.format || detectFormat(file);
83
+ const format = options.format || (await detectFormat(file));
81
84
  const processor = (0, analyze_1.getProcessor)(format, filteringOptions);
82
85
  const tree = await processor.loadIntoTree(file);
83
86
  const result = {
@@ -112,7 +115,7 @@ commander_1.program
112
115
  // Parse filtering options
113
116
  const filteringOptions = parseFilteringOptions(options);
114
117
  // Auto-detect format if not specified
115
- const format = options.format || detectFormat(file);
118
+ const format = options.format || (await detectFormat(file));
116
119
  const processor = (0, analyze_1.getProcessor)(format, filteringOptions);
117
120
  const texts = await processor.extractTexts(file);
118
121
  if (!options.quiet) {
@@ -162,7 +165,7 @@ commander_1.program
162
165
  // Parse filtering options
163
166
  const filteringOptions = parseFilteringOptions(options);
164
167
  // Auto-detect input format
165
- const inputFormat = detectFormat(input);
168
+ const inputFormat = await detectFormat(input);
166
169
  const inputProcessor = (0, analyze_1.getProcessor)(inputFormat, filteringOptions);
167
170
  // Load the tree (handle both files and folders)
168
171
  const tree = await inputProcessor.loadIntoTree(input);
@@ -203,7 +206,7 @@ commander_1.program
203
206
  .action(async (file, options) => {
204
207
  try {
205
208
  // Auto-detect format if not specified
206
- const format = options.format || detectFormat(file);
209
+ const format = options.format || (await detectFormat(file));
207
210
  // Get processor with gridset password if provided
208
211
  const processorOptions = {};
209
212
  if (options.gridsetPassword) {
@@ -283,9 +286,9 @@ commander_1.program
283
286
  .option('--export-date <iso>', 'Export date for baton export (ISO string)')
284
287
  .option('--encryption <mode>', 'Encryption label for baton export', 'none')
285
288
  .option('--version <version>', 'Baton export version', '1.0')
286
- .action((input, options) => {
289
+ .action(async (input, options) => {
287
290
  try {
288
- if (!pathExists(input)) {
291
+ if (!(await pathExists(input))) {
289
292
  throw new Error(`File not found: ${input}`);
290
293
  }
291
294
  const normalizedSource = (options.source || 'auto').toLowerCase();
@@ -294,10 +297,10 @@ commander_1.program
294
297
  const isSnap = ext === '.sps' || ext === '.spb';
295
298
  let entries;
296
299
  if (normalizedSource === 'grid3' || (normalizedSource === 'auto' && isGrid3Db)) {
297
- entries = (0, history_1.readGrid3History)(input);
300
+ entries = await (0, history_1.readGrid3History)(input);
298
301
  }
299
302
  else if (normalizedSource === 'snap' || (normalizedSource === 'auto' && isSnap)) {
300
- entries = (0, history_1.readSnapUsage)(input);
303
+ entries = await (0, history_1.readSnapUsage)(input);
301
304
  }
302
305
  else {
303
306
  throw new Error('Unable to detect history source. Use --source grid3 or --source snap.');
@@ -317,7 +320,7 @@ commander_1.program
317
320
  }
318
321
  const output = JSON.stringify(payload, null, 2);
319
322
  if (options.out) {
320
- writeTextToPath(options.out, output);
323
+ await writeTextToPath(options.out, output);
321
324
  }
322
325
  else {
323
326
  console.log(output);
@@ -348,7 +351,7 @@ commander_1.program
348
351
  .action(async (file, options) => {
349
352
  try {
350
353
  const filteringOptions = parseFilteringOptions(options);
351
- const format = options.format || detectFormat(file);
354
+ const format = options.format || (await detectFormat(file));
352
355
  const processor = (0, analyze_1.getProcessor)(format, filteringOptions);
353
356
  const tree = await processor.loadIntoTree(file);
354
357
  const accessMethod = (options.accessMethod || 'direct').toLowerCase();
@@ -403,7 +406,7 @@ commander_1.program
403
406
  let care = undefined;
404
407
  if (options.care) {
405
408
  const comparison = new analytics_1.ComparisonAnalyzer();
406
- care = comparison.compare(metrics, metrics, {
409
+ care = await comparison.compare(metrics, metrics, {
407
410
  includeSentences: true,
408
411
  usePrediction: !!options.usePrediction,
409
412
  scanningConfig,
@@ -421,7 +424,7 @@ commander_1.program
421
424
  };
422
425
  const output = options.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
423
426
  if (options.out) {
424
- writeTextToPath(options.out, output);
427
+ await writeTextToPath(options.out, output);
425
428
  }
426
429
  else {
427
430
  console.log(output);
@@ -54,7 +54,7 @@ export interface ProcessorConfig {
54
54
  grid3Path?: string;
55
55
  grid3Locale?: string;
56
56
  fileAdapter: FileAdapter;
57
- zipAdapter: (input?: ProcessorInput) => Promise<ZipAdapter>;
57
+ zipAdapter: (input?: ProcessorInput, fileAdapter?: FileAdapter) => Promise<ZipAdapter>;
58
58
  }
59
59
  export type ProcessorOptions = Partial<ProcessorConfig>;
60
60
  export interface ExtractedString {
@@ -92,15 +92,14 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
92
92
  }
93
93
  async loadIntoTree(filePathOrBuffer) {
94
94
  const { readBinaryFromInput, readTextFromInput, pathExists, getFileSize, join } = this.options.fileAdapter;
95
- await Promise.resolve();
96
95
  const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.plist';
97
96
  let buffer;
98
97
  try {
99
98
  if (typeof filePathOrBuffer === 'string') {
100
99
  if (filePathOrBuffer.endsWith('.ascconfig')) {
101
100
  const panelDefsPath = join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
102
- if (pathExists(panelDefsPath)) {
103
- buffer = readBinaryFromInput(panelDefsPath);
101
+ if (await pathExists(panelDefsPath)) {
102
+ buffer = await readBinaryFromInput(panelDefsPath);
104
103
  }
105
104
  else {
106
105
  const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
@@ -115,13 +114,13 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
115
114
  }
116
115
  }
117
116
  else {
118
- buffer = readBinaryFromInput(filePathOrBuffer);
117
+ buffer = await readBinaryFromInput(filePathOrBuffer);
119
118
  }
120
119
  }
121
120
  else {
122
- buffer = readBinaryFromInput(filePathOrBuffer);
121
+ buffer = await readBinaryFromInput(filePathOrBuffer);
123
122
  }
124
- const content = readTextFromInput(buffer);
123
+ const content = await readTextFromInput(buffer);
125
124
  const parsedData = plist_1.default.parse(content);
126
125
  let panelsData = [];
127
126
  if (Array.isArray(parsedData.panels)) {
@@ -250,10 +249,12 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
250
249
  const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
251
250
  filename,
252
251
  filesize: typeof filePathOrBuffer === 'string'
253
- ? (() => {
254
- return pathExists(filePathOrBuffer) ? getFileSize(filePathOrBuffer) : 0;
252
+ ? await (async () => {
253
+ return (await pathExists(filePathOrBuffer))
254
+ ? await getFileSize(filePathOrBuffer)
255
+ : 0;
255
256
  })()
256
- : readBinaryFromInput(filePathOrBuffer).byteLength,
257
+ : (await readBinaryFromInput(filePathOrBuffer)).byteLength,
257
258
  format: 'applepanels',
258
259
  message: err?.message || 'Failed to parse Apple Panels file',
259
260
  type: 'parse',
@@ -313,15 +314,14 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
313
314
  // Save the translated tree to the requested location and return its content
314
315
  await this.saveFromTree(tree, outputPath);
315
316
  if (outputPath.endsWith('.plist')) {
316
- return readBinaryFromInput(outputPath);
317
+ return await readBinaryFromInput(outputPath);
317
318
  }
318
319
  const configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
319
320
  const panelDefsPath = join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
320
- return readBinaryFromInput(panelDefsPath);
321
+ return await readBinaryFromInput(panelDefsPath);
321
322
  }
322
323
  async saveFromTree(tree, outputPath) {
323
324
  const { writeTextToPath, pathExists, mkDir, join, dirname } = this.options.fileAdapter;
324
- await Promise.resolve();
325
325
  // Support two output modes:
326
326
  // 1) Single-file .plist (PanelDefinitions.plist content written directly)
327
327
  // 2) Apple Panels bundle folder (*.ascconfig) with Contents/Resources structure
@@ -334,12 +334,12 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
334
334
  configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
335
335
  contentsPath = join(configPath, 'Contents');
336
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 });
337
+ if (!(await pathExists(configPath)))
338
+ await mkDir(configPath, { recursive: true });
339
+ if (!(await pathExists(contentsPath)))
340
+ await mkDir(contentsPath, { recursive: true });
341
+ if (!(await pathExists(resourcesPath)))
342
+ await mkDir(resourcesPath, { recursive: true });
343
343
  // Create Info.plist (bundle mode only)
344
344
  const infoPlist = {
345
345
  ASCConfigurationDisplayName: tree.metadata?.name || 'AAC Processors Export',
@@ -355,10 +355,10 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
355
355
  `Generated by AAC Processors${tree.metadata?.author ? ` - Author: ${tree.metadata.author}` : ''}`,
356
356
  };
357
357
  const infoPlistContent = plist_1.default.build(infoPlist);
358
- writeTextToPath(join(contentsPath, 'Info.plist'), infoPlistContent);
358
+ await writeTextToPath(join(contentsPath, 'Info.plist'), infoPlistContent);
359
359
  // Create AssetIndex.plist (empty)
360
360
  const assetIndexContent = plist_1.default.build({});
361
- writeTextToPath(join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
361
+ await writeTextToPath(join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
362
362
  }
363
363
  // Build PanelDefinitions content from tree
364
364
  const panelsDict = {};
@@ -485,13 +485,13 @@ class ApplePanelsProcessor extends baseProcessor_1.BaseProcessor {
485
485
  if (isSinglePlist) {
486
486
  // Write single PanelDefinitions.plist file directly
487
487
  const dir = dirname(outputPath);
488
- if (!pathExists(dir))
489
- mkDir(dir, { recursive: true });
490
- writeTextToPath(outputPath, panelDefsContent);
488
+ if (!(await pathExists(dir)))
489
+ await mkDir(dir, { recursive: true });
490
+ await writeTextToPath(outputPath, panelDefsContent);
491
491
  }
492
492
  else {
493
493
  // Write into bundle structure
494
- writeTextToPath(join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
494
+ await writeTextToPath(join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
495
495
  }
496
496
  }
497
497
  createApplePanelsAction(button) {
@@ -35,22 +35,22 @@ declare class AstericsGridProcessor extends BaseProcessor {
35
35
  /**
36
36
  * Add audio recording to a specific grid element
37
37
  */
38
- addAudioToElement(filePath: string, elementId: string, audioData: Buffer, metadata?: string): void;
38
+ addAudioToElement(filePath: string, elementId: string, audioData: Buffer, metadata?: string): Promise<void>;
39
39
  /**
40
40
  * Create a copy of the grid file with audio recordings added
41
41
  */
42
42
  createAudioEnhancedGridFile(sourceFilePath: string, targetFilePath: string, audioMappings: Map<string, {
43
43
  audioData: Buffer;
44
44
  metadata?: string;
45
- }>): void;
45
+ }>): Promise<void>;
46
46
  /**
47
47
  * Extract all element IDs from the grid file for audio mapping
48
48
  */
49
- getElementIds(filePathOrBuffer: ProcessorInput): string[];
49
+ getElementIds(filePathOrBuffer: ProcessorInput): Promise<string[]>;
50
50
  /**
51
51
  * Check if an element has audio recording
52
52
  */
53
- hasAudioRecording(filePathOrBuffer: ProcessorInput, elementId: string): boolean;
53
+ hasAudioRecording(filePathOrBuffer: ProcessorInput, elementId: string): Promise<boolean>;
54
54
  /**
55
55
  * Extract strings with metadata for aac-tools-platform compatibility
56
56
  * Uses the generic implementation from BaseProcessor