@willwade/aac-processors 0.1.21 → 0.2.1
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.
- package/README.md +3 -2
- package/dist/browser/processors/applePanelsProcessor.js +24 -24
- package/dist/browser/processors/astericsGridProcessor.js +22 -24
- package/dist/browser/processors/dotProcessor.js +6 -10
- package/dist/browser/processors/gridset/helpers.js +33 -30
- package/dist/browser/processors/gridset/symbolExtractor.js +2 -2
- package/dist/browser/processors/gridset/symbolSearch.js +22 -22
- package/dist/browser/processors/gridset/symbols.js +14 -14
- package/dist/browser/processors/gridsetProcessor.js +7 -7
- package/dist/browser/processors/obfProcessor.js +54 -47
- package/dist/browser/processors/opmlProcessor.js +6 -10
- package/dist/browser/processors/snap/helpers.js +34 -30
- package/dist/browser/processors/snapProcessor.js +28 -28
- package/dist/browser/processors/touchchatProcessor.js +24 -25
- package/dist/browser/utilities/analytics/history.js +24 -18
- package/dist/browser/utilities/analytics/metrics/comparison.js +16 -16
- package/dist/browser/utilities/analytics/metrics/vocabulary.js +2 -2
- package/dist/browser/utilities/analytics/reference/browser.js +16 -16
- package/dist/browser/utilities/analytics/reference/index.js +25 -24
- package/dist/browser/utils/io.js +29 -25
- package/dist/browser/utils/sqlite.js +5 -5
- package/dist/browser/utils/zip.js +2 -4
- package/dist/browser/validation/gridsetValidator.js +2 -2
- package/dist/browser/validation/obfValidator.js +2 -2
- package/dist/browser/validation/snapValidator.js +3 -3
- package/dist/browser/validation/touchChatValidator.js +3 -3
- package/dist/cli/index.js +19 -16
- package/dist/core/baseProcessor.d.ts +1 -1
- package/dist/processors/applePanelsProcessor.js +24 -24
- package/dist/processors/astericsGridProcessor.d.ts +4 -4
- package/dist/processors/astericsGridProcessor.js +22 -24
- package/dist/processors/dotProcessor.js +6 -10
- package/dist/processors/excelProcessor.d.ts +3 -3
- package/dist/processors/excelProcessor.js +10 -13
- package/dist/processors/gridset/helpers.d.ts +9 -9
- package/dist/processors/gridset/helpers.js +33 -30
- package/dist/processors/gridset/symbolExtractor.d.ts +1 -1
- package/dist/processors/gridset/symbolExtractor.js +2 -2
- package/dist/processors/gridset/symbolSearch.d.ts +10 -10
- package/dist/processors/gridset/symbolSearch.js +22 -22
- package/dist/processors/gridset/symbols.d.ts +3 -3
- package/dist/processors/gridset/symbols.js +14 -14
- package/dist/processors/gridsetProcessor.d.ts +2 -2
- package/dist/processors/gridsetProcessor.js +7 -7
- package/dist/processors/obfProcessor.d.ts +2 -2
- package/dist/processors/obfProcessor.js +54 -47
- package/dist/processors/obfsetProcessor.js +1 -2
- package/dist/processors/opmlProcessor.js +6 -10
- package/dist/processors/snap/helpers.d.ts +8 -8
- package/dist/processors/snap/helpers.js +34 -30
- package/dist/processors/snapProcessor.d.ts +2 -2
- package/dist/processors/snapProcessor.js +28 -28
- package/dist/processors/touchchatProcessor.d.ts +2 -2
- package/dist/processors/touchchatProcessor.js +24 -25
- package/dist/types/aac.d.ts +2 -2
- package/dist/utilities/analytics/history.d.ts +8 -8
- package/dist/utilities/analytics/history.js +24 -18
- package/dist/utilities/analytics/index.d.ts +1 -1
- package/dist/utilities/analytics/index.js +3 -2
- package/dist/utilities/analytics/metrics/comparison.d.ts +1 -1
- package/dist/utilities/analytics/metrics/comparison.js +16 -16
- package/dist/utilities/analytics/metrics/vocabulary.d.ts +1 -1
- package/dist/utilities/analytics/metrics/vocabulary.js +2 -2
- package/dist/utilities/analytics/reference/browser.d.ts +9 -9
- package/dist/utilities/analytics/reference/browser.js +16 -16
- package/dist/utilities/analytics/reference/index.d.ts +21 -21
- package/dist/utilities/analytics/reference/index.js +25 -24
- package/dist/utilities/symbolTools.d.ts +5 -5
- package/dist/utilities/symbolTools.js +10 -8
- package/dist/utils/io.d.ts +11 -11
- package/dist/utils/io.js +29 -25
- package/dist/utils/sqlite.d.ts +1 -1
- package/dist/utils/sqlite.js +5 -5
- package/dist/utils/zip.js +2 -4
- package/dist/validation/applePanelsValidator.js +7 -6
- package/dist/validation/astericsValidator.js +2 -2
- package/dist/validation/dotValidator.js +2 -2
- package/dist/validation/excelValidator.js +2 -2
- package/dist/validation/gridsetValidator.js +2 -2
- package/dist/validation/index.js +2 -2
- package/dist/validation/obfValidator.js +2 -2
- package/dist/validation/obfsetValidator.js +2 -2
- package/dist/validation/opmlValidator.js +2 -2
- package/dist/validation/snapValidator.js +3 -3
- package/dist/validation/touchChatValidator.js +3 -3
- package/docs/BROWSER_USAGE.md +0 -40
- package/package.json +1 -1
|
@@ -570,7 +570,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
570
570
|
});
|
|
571
571
|
}
|
|
572
572
|
// Also extract texts from the raw file for comprehensive coverage
|
|
573
|
-
const rawTexts = this.extractRawTexts(filePathOrBuffer);
|
|
573
|
+
const rawTexts = await this.extractRawTexts(filePathOrBuffer);
|
|
574
574
|
rawTexts.forEach((text) => {
|
|
575
575
|
if (text && !texts.includes(text)) {
|
|
576
576
|
texts.push(text);
|
|
@@ -578,9 +578,9 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
578
578
|
});
|
|
579
579
|
return texts;
|
|
580
580
|
}
|
|
581
|
-
extractRawTexts(filePathOrBuffer) {
|
|
581
|
+
async extractRawTexts(filePathOrBuffer) {
|
|
582
582
|
const { readTextFromInput } = this.options.fileAdapter;
|
|
583
|
-
let content = readTextFromInput(filePathOrBuffer);
|
|
583
|
+
let content = await readTextFromInput(filePathOrBuffer);
|
|
584
584
|
// Remove BOM if present
|
|
585
585
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
586
586
|
content = content.slice(1);
|
|
@@ -661,12 +661,11 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
661
661
|
}
|
|
662
662
|
async loadIntoTree(filePathOrBuffer) {
|
|
663
663
|
const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
|
|
664
|
-
await Promise.resolve();
|
|
665
664
|
const tree = new treeStructure_1.AACTree();
|
|
666
665
|
const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.grd';
|
|
667
|
-
const buffer = readBinaryFromInput(filePathOrBuffer);
|
|
666
|
+
const buffer = await readBinaryFromInput(filePathOrBuffer);
|
|
668
667
|
try {
|
|
669
|
-
let content = readTextFromInput(buffer);
|
|
668
|
+
let content = await readTextFromInput(buffer);
|
|
670
669
|
// Remove BOM if present
|
|
671
670
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
672
671
|
content = content.slice(1);
|
|
@@ -1060,8 +1059,7 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1060
1059
|
}
|
|
1061
1060
|
async processTexts(filePathOrBuffer, translations, outputPath) {
|
|
1062
1061
|
const { readTextFromInput, readBinaryFromInput, writeTextToPath } = this.options.fileAdapter;
|
|
1063
|
-
await
|
|
1064
|
-
let content = readTextFromInput(filePathOrBuffer);
|
|
1062
|
+
let content = await readTextFromInput(filePathOrBuffer);
|
|
1065
1063
|
// Remove BOM if present
|
|
1066
1064
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
1067
1065
|
content = content.slice(1);
|
|
@@ -1070,8 +1068,8 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1070
1068
|
// Apply translations directly to the JSON structure for comprehensive coverage
|
|
1071
1069
|
this.applyTranslationsToGridFile(grdFile, translations);
|
|
1072
1070
|
// Write the translated file
|
|
1073
|
-
writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
|
|
1074
|
-
return readBinaryFromInput(outputPath);
|
|
1071
|
+
await writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
|
|
1072
|
+
return await readBinaryFromInput(outputPath);
|
|
1075
1073
|
}
|
|
1076
1074
|
applyTranslationsToGridFile(grdFile, translations) {
|
|
1077
1075
|
grdFile.grids.forEach((grid) => {
|
|
@@ -1184,7 +1182,6 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1184
1182
|
}
|
|
1185
1183
|
async saveFromTree(tree, outputPath) {
|
|
1186
1184
|
const { writeTextToPath } = this.options.fileAdapter;
|
|
1187
|
-
await Promise.resolve();
|
|
1188
1185
|
// Use default Asterics Grid styling instead of taking from first page
|
|
1189
1186
|
// This prevents issues where the first page has unusual colors (like purple)
|
|
1190
1187
|
const defaultPageStyle = {
|
|
@@ -1387,14 +1384,14 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1387
1384
|
},
|
|
1388
1385
|
},
|
|
1389
1386
|
};
|
|
1390
|
-
writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
|
|
1387
|
+
await writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
|
|
1391
1388
|
}
|
|
1392
1389
|
/**
|
|
1393
1390
|
* Add audio recording to a specific grid element
|
|
1394
1391
|
*/
|
|
1395
|
-
addAudioToElement(filePath, elementId, audioData, metadata) {
|
|
1392
|
+
async addAudioToElement(filePath, elementId, audioData, metadata) {
|
|
1396
1393
|
const { readTextFromInput, writeTextToPath } = this.options.fileAdapter;
|
|
1397
|
-
let content = readTextFromInput(filePath);
|
|
1394
|
+
let content = await readTextFromInput(filePath);
|
|
1398
1395
|
// Remove BOM if present
|
|
1399
1396
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
1400
1397
|
content = content.slice(1);
|
|
@@ -1437,32 +1434,33 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1437
1434
|
throw new Error(`Element with ID ${elementId} not found`);
|
|
1438
1435
|
}
|
|
1439
1436
|
// Write back to file
|
|
1440
|
-
writeTextToPath(filePath, JSON.stringify(grdFile, null, 2));
|
|
1437
|
+
await writeTextToPath(filePath, JSON.stringify(grdFile, null, 2));
|
|
1441
1438
|
}
|
|
1442
1439
|
/**
|
|
1443
1440
|
* Create a copy of the grid file with audio recordings added
|
|
1444
1441
|
*/
|
|
1445
|
-
createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
|
|
1442
|
+
async createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
|
|
1446
1443
|
const { writeBinaryToPath, readBinaryFromInput } = this.options.fileAdapter;
|
|
1447
1444
|
// Copy the source file to target
|
|
1448
|
-
writeBinaryToPath(targetFilePath, readBinaryFromInput(sourceFilePath));
|
|
1445
|
+
await writeBinaryToPath(targetFilePath, await readBinaryFromInput(sourceFilePath));
|
|
1449
1446
|
// Add audio recordings to the copy
|
|
1450
|
-
audioMappings.
|
|
1447
|
+
await Promise.all(Object.entries(audioMappings).map(async (item) => {
|
|
1448
|
+
const [elementId, audioInfo] = item;
|
|
1451
1449
|
try {
|
|
1452
|
-
this.addAudioToElement(targetFilePath, elementId, audioInfo.audioData, audioInfo.metadata);
|
|
1450
|
+
await this.addAudioToElement(targetFilePath, elementId, audioInfo.audioData, audioInfo.metadata);
|
|
1453
1451
|
}
|
|
1454
1452
|
catch (error) {
|
|
1455
1453
|
// Failed to add audio to element - continue with others
|
|
1456
1454
|
console.warn(`Failed to add audio to element ${elementId}:`, error);
|
|
1457
1455
|
}
|
|
1458
|
-
});
|
|
1456
|
+
}));
|
|
1459
1457
|
}
|
|
1460
1458
|
/**
|
|
1461
1459
|
* Extract all element IDs from the grid file for audio mapping
|
|
1462
1460
|
*/
|
|
1463
|
-
getElementIds(filePathOrBuffer) {
|
|
1461
|
+
async getElementIds(filePathOrBuffer) {
|
|
1464
1462
|
const { readTextFromInput } = this.options.fileAdapter;
|
|
1465
|
-
let content = readTextFromInput(filePathOrBuffer);
|
|
1463
|
+
let content = await readTextFromInput(filePathOrBuffer);
|
|
1466
1464
|
// Remove BOM if present
|
|
1467
1465
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
1468
1466
|
content = content.slice(1);
|
|
@@ -1484,9 +1482,9 @@ class AstericsGridProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1484
1482
|
/**
|
|
1485
1483
|
* Check if an element has audio recording
|
|
1486
1484
|
*/
|
|
1487
|
-
hasAudioRecording(filePathOrBuffer, elementId) {
|
|
1485
|
+
async hasAudioRecording(filePathOrBuffer, elementId) {
|
|
1488
1486
|
const { readTextFromInput } = this.options.fileAdapter;
|
|
1489
|
-
let content = readTextFromInput(filePathOrBuffer);
|
|
1487
|
+
let content = await readTextFromInput(filePathOrBuffer);
|
|
1490
1488
|
// Remove BOM if present
|
|
1491
1489
|
if (content.charCodeAt(0) === 0xfeff) {
|
|
1492
1490
|
content = content.slice(1);
|
|
@@ -52,8 +52,7 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
52
52
|
}
|
|
53
53
|
async extractTexts(filePathOrBuffer) {
|
|
54
54
|
const { readTextFromInput } = this.options.fileAdapter;
|
|
55
|
-
await
|
|
56
|
-
const content = readTextFromInput(filePathOrBuffer);
|
|
55
|
+
const content = await readTextFromInput(filePathOrBuffer);
|
|
57
56
|
const { nodes, edges } = this.parseDotFile(content);
|
|
58
57
|
const texts = [];
|
|
59
58
|
// Collect node labels
|
|
@@ -70,12 +69,11 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
70
69
|
}
|
|
71
70
|
async loadIntoTree(filePathOrBuffer) {
|
|
72
71
|
const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
|
|
73
|
-
await Promise.resolve();
|
|
74
72
|
const filename = typeof filePathOrBuffer === 'string' ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload.dot';
|
|
75
|
-
const buffer = readBinaryFromInput(filePathOrBuffer);
|
|
73
|
+
const buffer = await readBinaryFromInput(filePathOrBuffer);
|
|
76
74
|
const filesize = buffer.byteLength;
|
|
77
75
|
try {
|
|
78
|
-
const content = readTextFromInput(buffer);
|
|
76
|
+
const content = await readTextFromInput(buffer);
|
|
79
77
|
if (!content || content.trim().length === 0) {
|
|
80
78
|
const validation = (0, validationTypes_1.buildValidationResultFromMessage)({
|
|
81
79
|
filename,
|
|
@@ -160,8 +158,7 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
160
158
|
}
|
|
161
159
|
async processTexts(filePathOrBuffer, translations, outputPath) {
|
|
162
160
|
const { readTextFromInput, writeBinaryToPath } = this.options.fileAdapter;
|
|
163
|
-
await
|
|
164
|
-
const content = readTextFromInput(filePathOrBuffer);
|
|
161
|
+
const content = await readTextFromInput(filePathOrBuffer);
|
|
165
162
|
let translatedContent = content;
|
|
166
163
|
translations.forEach((translation, text) => {
|
|
167
164
|
if (typeof text === 'string' && typeof translation === 'string') {
|
|
@@ -172,12 +169,11 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
172
169
|
}
|
|
173
170
|
});
|
|
174
171
|
const resultBuffer = (0, io_1.encodeText)(translatedContent || '');
|
|
175
|
-
writeBinaryToPath(outputPath, resultBuffer);
|
|
172
|
+
await writeBinaryToPath(outputPath, resultBuffer);
|
|
176
173
|
return resultBuffer;
|
|
177
174
|
}
|
|
178
175
|
async saveFromTree(tree, _outputPath) {
|
|
179
176
|
const { writeTextToPath } = this.options.fileAdapter;
|
|
180
|
-
await Promise.resolve();
|
|
181
177
|
let dotContent = `digraph "${tree.metadata?.name || 'AACBoard'}" {\n`;
|
|
182
178
|
// Helper to escape DOT string
|
|
183
179
|
const escapeDotString = (str) => {
|
|
@@ -207,7 +203,7 @@ class DotProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
207
203
|
});
|
|
208
204
|
}
|
|
209
205
|
dotContent += '}\n';
|
|
210
|
-
writeTextToPath(_outputPath, dotContent);
|
|
206
|
+
await writeTextToPath(_outputPath, dotContent);
|
|
211
207
|
}
|
|
212
208
|
/**
|
|
213
209
|
* Extract strings with metadata for aac-tools-platform compatibility
|
|
@@ -11,13 +11,13 @@ export declare class ExcelProcessor extends BaseProcessor {
|
|
|
11
11
|
/**
|
|
12
12
|
* Extract all text content from an Excel file
|
|
13
13
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
14
|
-
* @returns
|
|
14
|
+
* @returns Promise resolving to all text content found in the Excel file
|
|
15
15
|
*/
|
|
16
16
|
extractTexts(_filePathOrBuffer: ProcessorInput): Promise<string[]>;
|
|
17
17
|
/**
|
|
18
18
|
* Load Excel file into AACTree structure
|
|
19
19
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
20
|
-
* @returns AACTree representation of the Excel file
|
|
20
|
+
* @returns Promise resolving to an AACTree representation of the Excel file
|
|
21
21
|
*/
|
|
22
22
|
loadIntoTree(_filePathOrBuffer: ProcessorInput): Promise<AACTree>;
|
|
23
23
|
/**
|
|
@@ -25,7 +25,7 @@ export declare class ExcelProcessor extends BaseProcessor {
|
|
|
25
25
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
26
26
|
* @param translations - Map of original text to translated text
|
|
27
27
|
* @param outputPath - Path where translated Excel file should be saved
|
|
28
|
-
* @returns
|
|
28
|
+
* @returns Promise resolving to a buffer containing the translated Excel file
|
|
29
29
|
*/
|
|
30
30
|
processTexts(_filePathOrBuffer: ProcessorInput, _translations: Map<string, string>, outputPath: string): Promise<Uint8Array>;
|
|
31
31
|
/**
|
|
@@ -36,39 +36,36 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
36
36
|
/**
|
|
37
37
|
* Extract all text content from an Excel file
|
|
38
38
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
39
|
-
* @returns
|
|
39
|
+
* @returns Promise resolving to all text content found in the Excel file
|
|
40
40
|
*/
|
|
41
41
|
async extractTexts(_filePathOrBuffer) {
|
|
42
|
-
await Promise.resolve();
|
|
43
42
|
console.warn('ExcelProcessor.extractTexts is not implemented yet.');
|
|
44
|
-
return [];
|
|
43
|
+
return Promise.resolve([]);
|
|
45
44
|
}
|
|
46
45
|
/**
|
|
47
46
|
* Load Excel file into AACTree structure
|
|
48
47
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
49
|
-
* @returns AACTree representation of the Excel file
|
|
48
|
+
* @returns Promise resolving to an AACTree representation of the Excel file
|
|
50
49
|
*/
|
|
51
50
|
async loadIntoTree(_filePathOrBuffer) {
|
|
52
|
-
await Promise.resolve();
|
|
53
51
|
console.warn('ExcelProcessor.loadIntoTree is not implemented yet.');
|
|
54
52
|
const tree = new treeStructure_1.AACTree();
|
|
55
53
|
tree.metadata.format = 'excel';
|
|
56
|
-
return tree;
|
|
54
|
+
return Promise.resolve(tree);
|
|
57
55
|
}
|
|
58
56
|
/**
|
|
59
57
|
* Process texts in Excel file (apply translations)
|
|
60
58
|
* @param filePathOrBuffer - Path to Excel file or Buffer containing Excel data
|
|
61
59
|
* @param translations - Map of original text to translated text
|
|
62
60
|
* @param outputPath - Path where translated Excel file should be saved
|
|
63
|
-
* @returns
|
|
61
|
+
* @returns Promise resolving to a buffer containing the translated Excel file
|
|
64
62
|
*/
|
|
65
63
|
async processTexts(_filePathOrBuffer, _translations, outputPath) {
|
|
66
64
|
const { dirname, pathExists, mkDir } = this.options.fileAdapter;
|
|
67
|
-
await Promise.resolve();
|
|
68
65
|
console.warn('ExcelProcessor.processTexts is not implemented yet.');
|
|
69
66
|
const outputDir = dirname(outputPath);
|
|
70
|
-
if (!pathExists(outputDir)) {
|
|
71
|
-
mkDir(outputDir, { recursive: true });
|
|
67
|
+
if (!(await pathExists(outputDir))) {
|
|
68
|
+
await mkDir(outputDir, { recursive: true });
|
|
72
69
|
}
|
|
73
70
|
return Buffer.alloc(0);
|
|
74
71
|
}
|
|
@@ -466,7 +463,7 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
466
463
|
async saveFromTree(tree, outputPath) {
|
|
467
464
|
const { mkDir, dirname, writeTextToPath } = this.options.fileAdapter;
|
|
468
465
|
const outputDir = dirname(outputPath);
|
|
469
|
-
mkDir(outputDir, { recursive: true });
|
|
466
|
+
await mkDir(outputDir, { recursive: true });
|
|
470
467
|
try {
|
|
471
468
|
await this.saveFromTreeAsync(tree, outputPath);
|
|
472
469
|
}
|
|
@@ -475,8 +472,8 @@ class ExcelProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
475
472
|
console.error('Failed to save Excel file:', message);
|
|
476
473
|
try {
|
|
477
474
|
const fallbackPath = outputPath.replace(/\.xlsx$/i, '_error.txt');
|
|
478
|
-
mkDir(dirname(fallbackPath), { recursive: true });
|
|
479
|
-
writeTextToPath(fallbackPath, `Error saving Excel file: ${message}`);
|
|
475
|
+
await mkDir(dirname(fallbackPath), { recursive: true });
|
|
476
|
+
await writeTextToPath(fallbackPath, `Error saving Excel file: ${message}`);
|
|
480
477
|
}
|
|
481
478
|
catch (writeError) {
|
|
482
479
|
console.error('Failed to write Excel error file:', writeError);
|
|
@@ -88,49 +88,49 @@ export declare function getCommonDocumentsPath(): string;
|
|
|
88
88
|
* C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
|
|
89
89
|
* @returns Array of Grid3 user path information
|
|
90
90
|
*/
|
|
91
|
-
export declare function findGrid3UserPaths(fileAdapter?: FileAdapter): Grid3UserPath[]
|
|
91
|
+
export declare function findGrid3UserPaths(fileAdapter?: FileAdapter): Promise<Grid3UserPath[]>;
|
|
92
92
|
/**
|
|
93
93
|
* Find all Grid3 history database paths
|
|
94
94
|
* Convenience method that returns just the database file paths
|
|
95
95
|
* @returns Array of paths to history.sqlite files
|
|
96
96
|
*/
|
|
97
|
-
export declare function findGrid3HistoryDatabases(fileAdapter?: FileAdapter): string[]
|
|
97
|
+
export declare function findGrid3HistoryDatabases(fileAdapter?: FileAdapter): Promise<string[]>;
|
|
98
98
|
/**
|
|
99
99
|
* Get Grid 3 users (alias of findGrid3UserPaths for clarity)
|
|
100
100
|
*/
|
|
101
|
-
export declare function findGrid3Users(): Grid3UserPath[]
|
|
101
|
+
export declare function findGrid3Users(): Promise<Grid3UserPath[]>;
|
|
102
102
|
/**
|
|
103
103
|
* Find Grid 3 gridset/vocabulary files for each user
|
|
104
104
|
* @param userName Optional user filter; matches case-insensitively
|
|
105
105
|
* @returns Array of user/gridset path pairs
|
|
106
106
|
*/
|
|
107
|
-
export declare function findGrid3Vocabularies(userName?: string, fileAdapter?: FileAdapter): Grid3VocabularyPath[]
|
|
107
|
+
export declare function findGrid3Vocabularies(userName?: string, fileAdapter?: FileAdapter): Promise<Grid3VocabularyPath[]>;
|
|
108
108
|
/**
|
|
109
109
|
* Find a specific user's Grid 3 history database
|
|
110
110
|
* @param userName User name to search for (case-insensitive)
|
|
111
111
|
* @param langCode Optional language code filter (case-insensitive)
|
|
112
112
|
* @returns Path to history.sqlite or null if not found
|
|
113
113
|
*/
|
|
114
|
-
export declare function findGrid3UserHistory(userName: string, langCode?: string, fileAdapter?: FileAdapter): string | null
|
|
114
|
+
export declare function findGrid3UserHistory(userName: string, langCode?: string, fileAdapter?: FileAdapter): Promise<string | null>;
|
|
115
115
|
/**
|
|
116
116
|
* Check whether Grid 3 appears to be installed (Windows only)
|
|
117
117
|
*/
|
|
118
|
-
export declare function isGrid3Installed(fileAdapter?: FileAdapter): boolean
|
|
118
|
+
export declare function isGrid3Installed(fileAdapter?: FileAdapter): Promise<boolean>;
|
|
119
119
|
/**
|
|
120
120
|
* Read history events from a Grid 3 history.sqlite database.
|
|
121
121
|
* @param historyDbPath Absolute path to the history database
|
|
122
122
|
* @returns Parsed history entries grouped by phrase
|
|
123
123
|
*/
|
|
124
|
-
export declare function readGrid3History(historyDbPath: string, fileAdapter?: FileAdapter): Grid3HistoryEntry[]
|
|
124
|
+
export declare function readGrid3History(historyDbPath: string, fileAdapter?: FileAdapter): Promise<Grid3HistoryEntry[]>;
|
|
125
125
|
/**
|
|
126
126
|
* Convenience wrapper to load history for a specific Grid 3 user/lang combination.
|
|
127
127
|
* @param userName Grid 3 user name (case-insensitive)
|
|
128
128
|
* @param langCode Optional language code to narrow selection (case-insensitive)
|
|
129
129
|
* @returns History entries for that user/language, or empty array if none
|
|
130
130
|
*/
|
|
131
|
-
export declare function readGrid3HistoryForUser(userName: string, langCode?: string): Grid3HistoryEntry[]
|
|
131
|
+
export declare function readGrid3HistoryForUser(userName: string, langCode?: string): Promise<Grid3HistoryEntry[]>;
|
|
132
132
|
/**
|
|
133
133
|
* Load all available Grid 3 histories on the machine.
|
|
134
134
|
* @returns Combined history entries from every discovered history.sqlite
|
|
135
135
|
*/
|
|
136
|
-
export declare function readAllGrid3History(): Grid3HistoryEntry[]
|
|
136
|
+
export declare function readAllGrid3History(): Promise<Grid3HistoryEntry[]>;
|
|
@@ -188,7 +188,7 @@ function getCommonDocumentsPath() {
|
|
|
188
188
|
* C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
|
|
189
189
|
* @returns Array of Grid3 user path information
|
|
190
190
|
*/
|
|
191
|
-
function findGrid3UserPaths(fileAdapter = io_1.defaultFileAdapter) {
|
|
191
|
+
async function findGrid3UserPaths(fileAdapter = io_1.defaultFileAdapter) {
|
|
192
192
|
const { pathExists, listDir, isDirectory } = fileAdapter;
|
|
193
193
|
const results = [];
|
|
194
194
|
// Only works on Windows
|
|
@@ -200,26 +200,26 @@ function findGrid3UserPaths(fileAdapter = io_1.defaultFileAdapter) {
|
|
|
200
200
|
// Use Windows path joining so tests that mock a Windows platform stay consistent even on POSIX runners
|
|
201
201
|
const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
202
202
|
// Check if Grid3 Users directory exists
|
|
203
|
-
if (!pathExists(grid3BasePath)) {
|
|
203
|
+
if (!(await pathExists(grid3BasePath))) {
|
|
204
204
|
return results;
|
|
205
205
|
}
|
|
206
206
|
// Enumerate users
|
|
207
|
-
const users = listDir(grid3BasePath);
|
|
207
|
+
const users = await listDir(grid3BasePath);
|
|
208
208
|
for (const userDir of users) {
|
|
209
|
-
if (!isDirectory(userDir))
|
|
209
|
+
if (!(await isDirectory(userDir)))
|
|
210
210
|
continue;
|
|
211
211
|
const userName = userDir;
|
|
212
212
|
const userPath = (0, io_1.joinWin32)(grid3BasePath, userName);
|
|
213
213
|
// Enumerate language codes
|
|
214
|
-
const langDirs = listDir(userPath);
|
|
214
|
+
const langDirs = await listDir(userPath);
|
|
215
215
|
for (const langDir of langDirs) {
|
|
216
|
-
if (!isDirectory(langDir))
|
|
216
|
+
if (!(await isDirectory(langDir)))
|
|
217
217
|
continue;
|
|
218
218
|
const langCode = langDir;
|
|
219
219
|
const basePath = (0, io_1.joinWin32)(userPath, langCode);
|
|
220
220
|
const historyDbPath = (0, io_1.joinWin32)(basePath, 'Phrases', 'history.sqlite');
|
|
221
221
|
// Only include if history database exists
|
|
222
|
-
if (pathExists(historyDbPath)) {
|
|
222
|
+
if (await pathExists(historyDbPath)) {
|
|
223
223
|
results.push({
|
|
224
224
|
userName,
|
|
225
225
|
langCode,
|
|
@@ -240,21 +240,22 @@ function findGrid3UserPaths(fileAdapter = io_1.defaultFileAdapter) {
|
|
|
240
240
|
* Convenience method that returns just the database file paths
|
|
241
241
|
* @returns Array of paths to history.sqlite files
|
|
242
242
|
*/
|
|
243
|
-
function findGrid3HistoryDatabases(fileAdapter) {
|
|
244
|
-
|
|
243
|
+
async function findGrid3HistoryDatabases(fileAdapter) {
|
|
244
|
+
const userPaths = await findGrid3UserPaths(fileAdapter);
|
|
245
|
+
return userPaths.map((userPath) => userPath.historyDbPath);
|
|
245
246
|
}
|
|
246
247
|
/**
|
|
247
248
|
* Get Grid 3 users (alias of findGrid3UserPaths for clarity)
|
|
248
249
|
*/
|
|
249
|
-
function findGrid3Users() {
|
|
250
|
-
return findGrid3UserPaths();
|
|
250
|
+
async function findGrid3Users() {
|
|
251
|
+
return await findGrid3UserPaths();
|
|
251
252
|
}
|
|
252
253
|
/**
|
|
253
254
|
* Find Grid 3 gridset/vocabulary files for each user
|
|
254
255
|
* @param userName Optional user filter; matches case-insensitively
|
|
255
256
|
* @returns Array of user/gridset path pairs
|
|
256
257
|
*/
|
|
257
|
-
function findGrid3Vocabularies(userName, fileAdapter = io_1.defaultFileAdapter) {
|
|
258
|
+
async function findGrid3Vocabularies(userName, fileAdapter = io_1.defaultFileAdapter) {
|
|
258
259
|
const { pathExists, listDir, isDirectory } = fileAdapter;
|
|
259
260
|
const results = [];
|
|
260
261
|
if (process.platform !== 'win32') {
|
|
@@ -262,23 +263,23 @@ function findGrid3Vocabularies(userName, fileAdapter = io_1.defaultFileAdapter)
|
|
|
262
263
|
}
|
|
263
264
|
const commonDocs = getCommonDocumentsPath();
|
|
264
265
|
const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
265
|
-
if (!pathExists(grid3BasePath)) {
|
|
266
|
+
if (!(await pathExists(grid3BasePath))) {
|
|
266
267
|
return results;
|
|
267
268
|
}
|
|
268
269
|
const normalizedUser = userName?.toLowerCase();
|
|
269
|
-
const users = listDir(grid3BasePath);
|
|
270
|
+
const users = await listDir(grid3BasePath);
|
|
270
271
|
for (const userDir of users) {
|
|
271
|
-
if (!isDirectory(userDir))
|
|
272
|
+
if (!(await isDirectory(userDir)))
|
|
272
273
|
continue;
|
|
273
274
|
if (normalizedUser && userDir.toLowerCase() !== normalizedUser)
|
|
274
275
|
continue;
|
|
275
276
|
const userRoot = (0, io_1.joinWin32)(grid3BasePath, userDir);
|
|
276
277
|
const gridSetsDir = (0, io_1.joinWin32)(userRoot, 'Grid Sets');
|
|
277
|
-
if (!pathExists(gridSetsDir))
|
|
278
|
+
if (!(await pathExists(gridSetsDir)))
|
|
278
279
|
continue;
|
|
279
|
-
const entries = listDir(gridSetsDir);
|
|
280
|
+
const entries = await listDir(gridSetsDir);
|
|
280
281
|
for (const entry of entries) {
|
|
281
|
-
if (!pathExists(entry) || isDirectory(entry))
|
|
282
|
+
if (!(await pathExists(entry)) || (await isDirectory(entry)))
|
|
282
283
|
continue;
|
|
283
284
|
const ext = (0, io_1.extname)(entry).toLowerCase();
|
|
284
285
|
if (ext === '.gridset' || ext === '.gridsetx' || ext === '.grd' || ext === '.grdl') {
|
|
@@ -297,19 +298,20 @@ function findGrid3Vocabularies(userName, fileAdapter = io_1.defaultFileAdapter)
|
|
|
297
298
|
* @param langCode Optional language code filter (case-insensitive)
|
|
298
299
|
* @returns Path to history.sqlite or null if not found
|
|
299
300
|
*/
|
|
300
|
-
function findGrid3UserHistory(userName, langCode, fileAdapter) {
|
|
301
|
+
async function findGrid3UserHistory(userName, langCode, fileAdapter) {
|
|
301
302
|
if (!userName)
|
|
302
303
|
return null;
|
|
303
304
|
const normalizedUser = userName.toLowerCase();
|
|
304
305
|
const normalizedLang = langCode?.toLowerCase();
|
|
305
|
-
const
|
|
306
|
+
const userPaths = await findGrid3UserPaths(fileAdapter);
|
|
307
|
+
const match = userPaths.find((u) => u.userName.toLowerCase() === normalizedUser &&
|
|
306
308
|
(!normalizedLang || u.langCode.toLowerCase() === normalizedLang));
|
|
307
309
|
return match?.historyDbPath ?? null;
|
|
308
310
|
}
|
|
309
311
|
/**
|
|
310
312
|
* Check whether Grid 3 appears to be installed (Windows only)
|
|
311
313
|
*/
|
|
312
|
-
function isGrid3Installed(fileAdapter = io_1.defaultFileAdapter) {
|
|
314
|
+
async function isGrid3Installed(fileAdapter = io_1.defaultFileAdapter) {
|
|
313
315
|
const { pathExists } = fileAdapter;
|
|
314
316
|
if (process.platform !== 'win32')
|
|
315
317
|
return false;
|
|
@@ -317,7 +319,7 @@ function isGrid3Installed(fileAdapter = io_1.defaultFileAdapter) {
|
|
|
317
319
|
if (!commonDocs)
|
|
318
320
|
return false;
|
|
319
321
|
const grid3BasePath = (0, io_1.joinWin32)(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
320
|
-
return pathExists(grid3BasePath);
|
|
322
|
+
return await pathExists(grid3BasePath);
|
|
321
323
|
}
|
|
322
324
|
function parseGrid3ContentXml(xmlContent) {
|
|
323
325
|
const regex = /<r>(?:<!\[CDATA\[)?(.*?)(?:\]\]>)?<\/r>/gis;
|
|
@@ -336,9 +338,9 @@ function parseGrid3ContentXml(xmlContent) {
|
|
|
336
338
|
* @param historyDbPath Absolute path to the history database
|
|
337
339
|
* @returns Parsed history entries grouped by phrase
|
|
338
340
|
*/
|
|
339
|
-
function readGrid3History(historyDbPath, fileAdapter = io_1.defaultFileAdapter) {
|
|
341
|
+
async function readGrid3History(historyDbPath, fileAdapter = io_1.defaultFileAdapter) {
|
|
340
342
|
const { pathExists } = fileAdapter;
|
|
341
|
-
if (!pathExists(historyDbPath))
|
|
343
|
+
if (!(await pathExists(historyDbPath)))
|
|
342
344
|
return [];
|
|
343
345
|
const Database = (0, sqlite_1.requireBetterSqlite3)();
|
|
344
346
|
const db = new Database(historyDbPath, { readonly: true });
|
|
@@ -398,17 +400,18 @@ function readGrid3History(historyDbPath, fileAdapter = io_1.defaultFileAdapter)
|
|
|
398
400
|
* @param langCode Optional language code to narrow selection (case-insensitive)
|
|
399
401
|
* @returns History entries for that user/language, or empty array if none
|
|
400
402
|
*/
|
|
401
|
-
function readGrid3HistoryForUser(userName, langCode) {
|
|
402
|
-
const dbPath = findGrid3UserHistory(userName, langCode);
|
|
403
|
+
async function readGrid3HistoryForUser(userName, langCode) {
|
|
404
|
+
const dbPath = await findGrid3UserHistory(userName, langCode);
|
|
403
405
|
if (!dbPath)
|
|
404
406
|
return [];
|
|
405
|
-
return readGrid3History(dbPath);
|
|
407
|
+
return await readGrid3History(dbPath);
|
|
406
408
|
}
|
|
407
409
|
/**
|
|
408
410
|
* Load all available Grid 3 histories on the machine.
|
|
409
411
|
* @returns Combined history entries from every discovered history.sqlite
|
|
410
412
|
*/
|
|
411
|
-
function readAllGrid3History() {
|
|
412
|
-
const paths = findGrid3HistoryDatabases();
|
|
413
|
-
|
|
413
|
+
async function readAllGrid3History() {
|
|
414
|
+
const paths = await findGrid3HistoryDatabases();
|
|
415
|
+
const history = await Promise.all(paths.map(async (p) => await readGrid3History(p)));
|
|
416
|
+
return history.flat();
|
|
414
417
|
}
|
|
@@ -97,7 +97,7 @@ export declare function suggestExtractionStrategy(report: SymbolReport): string;
|
|
|
97
97
|
/**
|
|
98
98
|
* Export symbol references to CSV for manual extraction
|
|
99
99
|
*/
|
|
100
|
-
export declare function exportSymbolReferencesToCsv(report: SymbolReport, outputPath: string, fileAdapter?: FileAdapter): void
|
|
100
|
+
export declare function exportSymbolReferencesToCsv(report: SymbolReport, outputPath: string, fileAdapter?: FileAdapter): Promise<void>;
|
|
101
101
|
/**
|
|
102
102
|
* Create a manifest file for missing symbols
|
|
103
103
|
*/
|
|
@@ -286,13 +286,13 @@ function parseSymbolReferenceSafe(reference) {
|
|
|
286
286
|
/**
|
|
287
287
|
* Export symbol references to CSV for manual extraction
|
|
288
288
|
*/
|
|
289
|
-
function exportSymbolReferencesToCsv(report, outputPath, fileAdapter = io_1.defaultFileAdapter) {
|
|
289
|
+
async function exportSymbolReferencesToCsv(report, outputPath, fileAdapter = io_1.defaultFileAdapter) {
|
|
290
290
|
const { writeTextToPath } = fileAdapter;
|
|
291
291
|
const lines = ['Reference,Library,Path,Attribution,License'];
|
|
292
292
|
for (const symbol of report.missingSymbols) {
|
|
293
293
|
lines.push(`"${symbol.reference}","${symbol.library}","${symbol.path}","${symbol.attribution || ''}","${symbol.license || ''}"`);
|
|
294
294
|
}
|
|
295
|
-
writeTextToPath(outputPath, lines.join('\n'));
|
|
295
|
+
await writeTextToPath(outputPath, lines.join('\n'));
|
|
296
296
|
}
|
|
297
297
|
function createSymbolManifest(tree, gridsetName) {
|
|
298
298
|
const manifest = {
|
|
@@ -42,20 +42,20 @@ export interface LibrarySearchIndex {
|
|
|
42
42
|
* @param pixFilePath - Path to .pix file
|
|
43
43
|
* @returns Search index
|
|
44
44
|
*/
|
|
45
|
-
export declare function parsePixFile(pixFilePath: string, fileAdapter?: FileAdapter): LibrarySearchIndex
|
|
45
|
+
export declare function parsePixFile(pixFilePath: string, fileAdapter?: FileAdapter): Promise<LibrarySearchIndex>;
|
|
46
46
|
/**
|
|
47
47
|
* Load search indexes for all available libraries
|
|
48
48
|
* @param options - Search options
|
|
49
49
|
* @returns Map of library name to search index
|
|
50
50
|
*/
|
|
51
|
-
export declare function loadSearchIndexes(options?: SymbolSearchOptions, fileAdapter?: FileAdapter): Map<string, LibrarySearchIndex
|
|
51
|
+
export declare function loadSearchIndexes(options?: SymbolSearchOptions, fileAdapter?: FileAdapter): Promise<Map<string, LibrarySearchIndex>>;
|
|
52
52
|
/**
|
|
53
53
|
* Search for symbols by term
|
|
54
54
|
* @param searchTerm - Term to search for
|
|
55
55
|
* @param options - Search options
|
|
56
56
|
* @returns Array of search results
|
|
57
57
|
*/
|
|
58
|
-
export declare function searchSymbols(searchTerm: string, options?: SymbolSearchOptions): SymbolSearchResult[]
|
|
58
|
+
export declare function searchSymbols(searchTerm: string, options?: SymbolSearchOptions): Promise<SymbolSearchResult[]>;
|
|
59
59
|
/**
|
|
60
60
|
* Get symbol filename for a specific search term
|
|
61
61
|
* @param searchTerm - Search term to look up
|
|
@@ -63,7 +63,7 @@ export declare function searchSymbols(searchTerm: string, options?: SymbolSearch
|
|
|
63
63
|
* @param options - Search options
|
|
64
64
|
* @returns Symbol filename or undefined
|
|
65
65
|
*/
|
|
66
|
-
export declare function getSymbolFilename(searchTerm: string, library: string, options?: SymbolSearchOptions): string | undefined
|
|
66
|
+
export declare function getSymbolFilename(searchTerm: string, library: string, options?: SymbolSearchOptions): Promise<string | undefined>;
|
|
67
67
|
/**
|
|
68
68
|
* Get display name for a symbol filename
|
|
69
69
|
* @param symbolFilename - Symbol filename (e.g., "above bw.png")
|
|
@@ -71,34 +71,34 @@ export declare function getSymbolFilename(searchTerm: string, library: string, o
|
|
|
71
71
|
* @param options - Search options
|
|
72
72
|
* @returns Display name or undefined
|
|
73
73
|
*/
|
|
74
|
-
export declare function getSymbolDisplayName(symbolFilename: string, library: string, options?: SymbolSearchOptions): string | undefined
|
|
74
|
+
export declare function getSymbolDisplayName(symbolFilename: string, library: string, options?: SymbolSearchOptions): Promise<string | undefined>;
|
|
75
75
|
/**
|
|
76
76
|
* Get all search terms for a library
|
|
77
77
|
* @param library - Library name
|
|
78
78
|
* @param options - Search options
|
|
79
79
|
* @returns Array of search terms
|
|
80
80
|
*/
|
|
81
|
-
export declare function getAllSearchTerms(library: string, options?: SymbolSearchOptions): string[]
|
|
81
|
+
export declare function getAllSearchTerms(library: string, options?: SymbolSearchOptions): Promise<string[]>;
|
|
82
82
|
/**
|
|
83
83
|
* Search suggestions (autocomplete)
|
|
84
84
|
* @param partialTerm - Partial search term
|
|
85
85
|
* @param options - Search options
|
|
86
86
|
* @returns Array of suggested terms
|
|
87
87
|
*/
|
|
88
|
-
export declare function getSearchSuggestions(partialTerm: string, options?: SymbolSearchOptions): string[]
|
|
88
|
+
export declare function getSearchSuggestions(partialTerm: string, options?: SymbolSearchOptions): Promise<string[]>;
|
|
89
89
|
/**
|
|
90
90
|
* Search for symbols and return results with library references
|
|
91
91
|
* @param searchTerm - Term to search for
|
|
92
92
|
* @param options - Search options
|
|
93
93
|
* @returns Array of full symbol references
|
|
94
94
|
*/
|
|
95
|
-
export declare function searchSymbolsWithReferences(searchTerm: string, options?: SymbolSearchOptions): string[]
|
|
95
|
+
export declare function searchSymbolsWithReferences(searchTerm: string, options?: SymbolSearchOptions): Promise<string[]>;
|
|
96
96
|
/**
|
|
97
97
|
* Count symbols in each library
|
|
98
98
|
* @param options - Search options
|
|
99
99
|
* @returns Map of library name to symbol count
|
|
100
100
|
*/
|
|
101
|
-
export declare function countLibrarySymbols(options?: SymbolSearchOptions): Map<string, number
|
|
101
|
+
export declare function countLibrarySymbols(options?: SymbolSearchOptions): Promise<Map<string, number>>;
|
|
102
102
|
/**
|
|
103
103
|
* Get statistics about symbol libraries
|
|
104
104
|
*/
|
|
@@ -115,4 +115,4 @@ export interface SymbolSearchStats {
|
|
|
115
115
|
* @param options - Search options
|
|
116
116
|
* @returns Statistics about available symbols
|
|
117
117
|
*/
|
|
118
|
-
export declare function getSymbolSearchStats(options?: SymbolSearchOptions): SymbolSearchStats
|
|
118
|
+
export declare function getSymbolSearchStats(options?: SymbolSearchOptions): Promise<SymbolSearchStats>;
|