@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
|
@@ -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
|
-
|
|
136
|
+
const existingPaths = await Promise.all(requiredFiles.map(async (file) => await pathExists(join(dataPath, file))));
|
|
137
|
+
return existingPaths.every((exists) => exists);
|
|
137
138
|
}
|
package/dist/browser/utils/io.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 (
|
|
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(
|
|
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
|
|
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
|