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