@willwade/aac-processors 0.2.15 → 0.2.17
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/processors/gridset/commands.js +56 -1
- package/dist/browser/processors/gridsetProcessor.js +35 -24
- package/dist/browser/processors/obfProcessor.js +15 -28
- package/dist/core/treeStructure.d.ts +1 -0
- package/dist/processors/gridset/commands.js +56 -1
- package/dist/processors/gridsetProcessor.js +35 -47
- package/dist/processors/obfProcessor.js +15 -51
- package/package.json +5 -5
|
@@ -909,6 +909,61 @@ export function getAllPluginIds() {
|
|
|
909
909
|
const plugins = new Set(Object.values(GRID3_COMMANDS).map((cmd) => cmd.pluginId));
|
|
910
910
|
return Array.from(plugins).sort();
|
|
911
911
|
}
|
|
912
|
+
function textOfStructured(val) {
|
|
913
|
+
if (!val || typeof val !== 'object')
|
|
914
|
+
return undefined;
|
|
915
|
+
const parts = [];
|
|
916
|
+
const processS = (s) => {
|
|
917
|
+
if (!s)
|
|
918
|
+
return;
|
|
919
|
+
if (s.r !== undefined) {
|
|
920
|
+
const rElements = Array.isArray(s.r) ? s.r : [s.r];
|
|
921
|
+
for (const r of rElements) {
|
|
922
|
+
if (typeof r === 'number') {
|
|
923
|
+
if (r !== 0)
|
|
924
|
+
parts.push(String(r));
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
if (typeof r === 'object' && r !== null) {
|
|
928
|
+
if ('#text' in r)
|
|
929
|
+
parts.push(String(r['#text']));
|
|
930
|
+
else if ('#cdata' in r)
|
|
931
|
+
parts.push(String(r['#cdata']));
|
|
932
|
+
else
|
|
933
|
+
parts.push(String(r));
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
parts.push(String(r));
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
if (val.p) {
|
|
942
|
+
const sElements = Array.isArray(val.p.s) ? val.p.s : val.p.s ? [val.p.s] : [];
|
|
943
|
+
sElements.forEach(processS);
|
|
944
|
+
}
|
|
945
|
+
else if (val.s) {
|
|
946
|
+
const sElements = Array.isArray(val.s) ? val.s : [val.s];
|
|
947
|
+
sElements.forEach(processS);
|
|
948
|
+
}
|
|
949
|
+
else if (val.r !== undefined) {
|
|
950
|
+
processS(val);
|
|
951
|
+
}
|
|
952
|
+
return parts.length > 0 ? parts.join('').trim() : undefined;
|
|
953
|
+
}
|
|
954
|
+
function extractParamValue(param) {
|
|
955
|
+
if (typeof param === 'string')
|
|
956
|
+
return param;
|
|
957
|
+
if (param.p || param.s || (param.r !== undefined && typeof param.r !== 'string')) {
|
|
958
|
+
const structured = textOfStructured(param);
|
|
959
|
+
if (structured !== undefined)
|
|
960
|
+
return structured;
|
|
961
|
+
}
|
|
962
|
+
const simple = param['#text'] ?? param.text ?? param.value;
|
|
963
|
+
if (simple !== undefined)
|
|
964
|
+
return simple;
|
|
965
|
+
return textOfStructured(param);
|
|
966
|
+
}
|
|
912
967
|
export function extractCommandParameters(command) {
|
|
913
968
|
const parameters = {};
|
|
914
969
|
const params = command.Parameter || command.parameter;
|
|
@@ -917,7 +972,7 @@ export function extractCommandParameters(command) {
|
|
|
917
972
|
const paramArray = Array.isArray(params) ? params : [params];
|
|
918
973
|
for (const param of paramArray) {
|
|
919
974
|
const key = param['@_Key'] || param.Key || param.key;
|
|
920
|
-
let value = param
|
|
975
|
+
let value = extractParamValue(param);
|
|
921
976
|
if (key && value !== undefined) {
|
|
922
977
|
// Try to convert to number if it looks numeric
|
|
923
978
|
if (typeof value === 'string' && /^\d+$/.test(value)) {
|
|
@@ -700,6 +700,13 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
700
700
|
}
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
|
+
if (pageWordListItems.length > 0) {
|
|
704
|
+
page.wordListItems = pageWordListItems.map((item) => ({
|
|
705
|
+
text: item.text,
|
|
706
|
+
image: item.image,
|
|
707
|
+
partOfSpeech: item.partOfSpeech,
|
|
708
|
+
}));
|
|
709
|
+
}
|
|
703
710
|
// Track WordList AutoContent cells and their positions for "more" button placement
|
|
704
711
|
const wordListAutoContentCells = [];
|
|
705
712
|
let wordListCellIndex = 0;
|
|
@@ -1032,6 +1039,15 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
1032
1039
|
const param = getRawParam(key);
|
|
1033
1040
|
if (param === undefined)
|
|
1034
1041
|
return undefined;
|
|
1042
|
+
if (typeof param === 'string')
|
|
1043
|
+
return param;
|
|
1044
|
+
if (param.p ||
|
|
1045
|
+
param.s ||
|
|
1046
|
+
(param.r !== undefined && typeof param.r !== 'string')) {
|
|
1047
|
+
const structuredValue = this.textOf(param);
|
|
1048
|
+
if (structuredValue !== undefined)
|
|
1049
|
+
return structuredValue;
|
|
1050
|
+
}
|
|
1035
1051
|
const simpleValue = param['#text'] ?? param.text ?? param.value;
|
|
1036
1052
|
if (typeof simpleValue === 'string')
|
|
1037
1053
|
return simpleValue;
|
|
@@ -1040,8 +1056,6 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
1040
1056
|
const structuredValue = this.textOf(param);
|
|
1041
1057
|
if (structuredValue !== undefined)
|
|
1042
1058
|
return structuredValue;
|
|
1043
|
-
if (typeof param === 'string')
|
|
1044
|
-
return param;
|
|
1045
1059
|
return undefined;
|
|
1046
1060
|
};
|
|
1047
1061
|
// Skip PredictThis in primary action loop as it was handled in pre-pass
|
|
@@ -2227,9 +2241,8 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
2227
2241
|
await writeBinaryToPath(outputPath, originalBuffer);
|
|
2228
2242
|
return;
|
|
2229
2243
|
}
|
|
2230
|
-
const
|
|
2231
|
-
const
|
|
2232
|
-
const outputZip = new AdmZip();
|
|
2244
|
+
const originalZip = await this.options.zipAdapter(originalPath);
|
|
2245
|
+
const outputZip = await this.options.zipAdapter();
|
|
2233
2246
|
// Check if any page has pending mutations
|
|
2234
2247
|
const hasPendingMutations = Object.values(tree.pages).some((page) => page.pendingMutations.length > 0);
|
|
2235
2248
|
if (hasPendingMutations) {
|
|
@@ -2246,15 +2259,13 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
2246
2259
|
suppressBooleanAttributes: false,
|
|
2247
2260
|
});
|
|
2248
2261
|
GridsetSaveHandler.saveWithMutations(tree, originalZip, outputZip, parser, gridBuilder, (page) => this.createBasicGridXml(page));
|
|
2249
|
-
// Copy
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
outputZip.addFile(entry.entryName, entry.getData());
|
|
2255
|
-
}
|
|
2262
|
+
// Copy files
|
|
2263
|
+
const outputFiles = [];
|
|
2264
|
+
for (const name of originalZip.listFiles()) {
|
|
2265
|
+
const data = await originalZip.readFile(name);
|
|
2266
|
+
outputFiles.push({ name, data });
|
|
2256
2267
|
}
|
|
2257
|
-
const outputBuffer = outputZip.
|
|
2268
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
2258
2269
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
2259
2270
|
return;
|
|
2260
2271
|
}
|
|
@@ -2285,15 +2296,15 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
2285
2296
|
const gridPath = `Grids/${page.name}/grid.xml`;
|
|
2286
2297
|
modifiedGridFiles.add(gridPath);
|
|
2287
2298
|
// Try to get the original grid.xml file
|
|
2288
|
-
const
|
|
2289
|
-
if (!
|
|
2299
|
+
const originalEntries = originalZip.listFiles();
|
|
2300
|
+
if (!originalEntries.includes(gridPath)) {
|
|
2290
2301
|
// If original doesn't exist, create a new basic grid
|
|
2291
2302
|
const basicGrid = this.createBasicGridXml(page);
|
|
2292
2303
|
newGridFiles.set(gridPath, basicGrid);
|
|
2293
2304
|
continue;
|
|
2294
2305
|
}
|
|
2295
2306
|
// Parse the original grid XML
|
|
2296
|
-
const originalContent =
|
|
2307
|
+
const originalContent = (await originalZip.readFile(gridPath)).toString();
|
|
2297
2308
|
const originalGrid = parser.parse(originalContent);
|
|
2298
2309
|
if (!originalGrid.Grid) {
|
|
2299
2310
|
// Invalid grid structure, create a basic one
|
|
@@ -2458,22 +2469,22 @@ class GridsetProcessor extends BaseProcessor {
|
|
|
2458
2469
|
newGridFiles.set(gridPath, builtXml);
|
|
2459
2470
|
}
|
|
2460
2471
|
// Copy all files from original zip, replacing modified grid files
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
continue;
|
|
2472
|
+
const outputFiles = [];
|
|
2473
|
+
for (const entry of originalZip.listFiles()) {
|
|
2464
2474
|
// Skip grid.xml files that we're modifying
|
|
2465
|
-
if (modifiedGridFiles.has(entry
|
|
2466
|
-
const newContent = newGridFiles.get(entry
|
|
2475
|
+
if (modifiedGridFiles.has(entry)) {
|
|
2476
|
+
const newContent = newGridFiles.get(entry);
|
|
2467
2477
|
if (newContent) {
|
|
2468
|
-
|
|
2478
|
+
outputFiles.push({ name: entry, data: Buffer.from(newContent, 'utf8') });
|
|
2469
2479
|
}
|
|
2470
2480
|
continue;
|
|
2471
2481
|
}
|
|
2472
2482
|
// Copy all other files as-is
|
|
2473
|
-
|
|
2483
|
+
const data = await originalZip.readFile(entry);
|
|
2484
|
+
outputFiles.push({ name: entry, data });
|
|
2474
2485
|
}
|
|
2475
2486
|
// Write the output ZIP
|
|
2476
|
-
const outputBuffer = outputZip.
|
|
2487
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
2477
2488
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
2478
2489
|
}
|
|
2479
2490
|
/**
|
|
@@ -741,24 +741,18 @@ class ObfProcessor extends BaseProcessor {
|
|
|
741
741
|
await writeBinaryToPath(outputPath, originalBuffer);
|
|
742
742
|
return;
|
|
743
743
|
}
|
|
744
|
-
const
|
|
745
|
-
const
|
|
746
|
-
const
|
|
747
|
-
// Track which .obf files we're modifying
|
|
748
|
-
const modifiedObfFiles = new Set();
|
|
749
|
-
// Generate new .obf files for pages in the tree
|
|
750
|
-
const newObfFiles = new Map();
|
|
744
|
+
const originalZip = await this.options.zipAdapter(originalPath);
|
|
745
|
+
const outputZip = await this.options.zipAdapter();
|
|
746
|
+
const outputFiles = [];
|
|
751
747
|
for (const page of Object.values(tree.pages)) {
|
|
752
|
-
const
|
|
753
|
-
modifiedObfFiles.add(obfFilename);
|
|
748
|
+
const name = this.getPageFilename(page.id, tree.metadata);
|
|
754
749
|
// createObfBoardFromPage will automatically apply mutations if present
|
|
755
750
|
const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
|
|
756
|
-
const
|
|
757
|
-
|
|
751
|
+
const data = JSON.stringify(obfBoard, null, 2);
|
|
752
|
+
outputFiles.push({ name, data });
|
|
758
753
|
}
|
|
759
754
|
// Generate updated manifest if we have pages
|
|
760
755
|
if (Object.keys(tree.pages).length > 0) {
|
|
761
|
-
modifiedObfFiles.add('manifest.json');
|
|
762
756
|
const manifest = {
|
|
763
757
|
format: OBF_FORMAT_VERSION,
|
|
764
758
|
root: tree.metadata.defaultHomePageId,
|
|
@@ -771,25 +765,18 @@ class ObfProcessor extends BaseProcessor {
|
|
|
771
765
|
sounds: {},
|
|
772
766
|
},
|
|
773
767
|
};
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
const newContent = newObfFiles.get(entry.entryName);
|
|
783
|
-
if (newContent) {
|
|
784
|
-
outputZip.addFile(entry.entryName, Buffer.from(newContent, 'utf8'));
|
|
785
|
-
}
|
|
786
|
-
continue;
|
|
768
|
+
const data = Buffer.from(JSON.stringify(manifest), 'utf8');
|
|
769
|
+
outputFiles.push({ name: 'manifest.json', data });
|
|
770
|
+
}
|
|
771
|
+
// Add remaining .obf from original zip
|
|
772
|
+
for (const entry of originalZip.listFiles()) {
|
|
773
|
+
if (!outputFiles.find((file) => file.name === entry)) {
|
|
774
|
+
const data = await originalZip.readFile(entry);
|
|
775
|
+
outputFiles.push({ name: entry, data });
|
|
787
776
|
}
|
|
788
|
-
// Copy all other files as-is (preserves images, sounds, etc.)
|
|
789
|
-
outputZip.addFile(entry.entryName, entry.getData());
|
|
790
777
|
}
|
|
791
778
|
// Write the output ZIP
|
|
792
|
-
const outputBuffer = outputZip.
|
|
779
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
793
780
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
794
781
|
}
|
|
795
782
|
/**
|
|
@@ -222,6 +222,7 @@ export declare class AACPage {
|
|
|
222
222
|
descriptionHtml?: string;
|
|
223
223
|
images?: any[];
|
|
224
224
|
sounds?: any[];
|
|
225
|
+
wordListItems?: import('../types/aac').AACWordListItem[];
|
|
225
226
|
semantic_ids?: string[];
|
|
226
227
|
clone_ids?: string[];
|
|
227
228
|
scanningConfig?: import('../types/aac').ScanningConfig;
|
|
@@ -920,6 +920,61 @@ function getAllPluginIds() {
|
|
|
920
920
|
const plugins = new Set(Object.values(exports.GRID3_COMMANDS).map((cmd) => cmd.pluginId));
|
|
921
921
|
return Array.from(plugins).sort();
|
|
922
922
|
}
|
|
923
|
+
function textOfStructured(val) {
|
|
924
|
+
if (!val || typeof val !== 'object')
|
|
925
|
+
return undefined;
|
|
926
|
+
const parts = [];
|
|
927
|
+
const processS = (s) => {
|
|
928
|
+
if (!s)
|
|
929
|
+
return;
|
|
930
|
+
if (s.r !== undefined) {
|
|
931
|
+
const rElements = Array.isArray(s.r) ? s.r : [s.r];
|
|
932
|
+
for (const r of rElements) {
|
|
933
|
+
if (typeof r === 'number') {
|
|
934
|
+
if (r !== 0)
|
|
935
|
+
parts.push(String(r));
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (typeof r === 'object' && r !== null) {
|
|
939
|
+
if ('#text' in r)
|
|
940
|
+
parts.push(String(r['#text']));
|
|
941
|
+
else if ('#cdata' in r)
|
|
942
|
+
parts.push(String(r['#cdata']));
|
|
943
|
+
else
|
|
944
|
+
parts.push(String(r));
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
parts.push(String(r));
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
if (val.p) {
|
|
953
|
+
const sElements = Array.isArray(val.p.s) ? val.p.s : val.p.s ? [val.p.s] : [];
|
|
954
|
+
sElements.forEach(processS);
|
|
955
|
+
}
|
|
956
|
+
else if (val.s) {
|
|
957
|
+
const sElements = Array.isArray(val.s) ? val.s : [val.s];
|
|
958
|
+
sElements.forEach(processS);
|
|
959
|
+
}
|
|
960
|
+
else if (val.r !== undefined) {
|
|
961
|
+
processS(val);
|
|
962
|
+
}
|
|
963
|
+
return parts.length > 0 ? parts.join('').trim() : undefined;
|
|
964
|
+
}
|
|
965
|
+
function extractParamValue(param) {
|
|
966
|
+
if (typeof param === 'string')
|
|
967
|
+
return param;
|
|
968
|
+
if (param.p || param.s || (param.r !== undefined && typeof param.r !== 'string')) {
|
|
969
|
+
const structured = textOfStructured(param);
|
|
970
|
+
if (structured !== undefined)
|
|
971
|
+
return structured;
|
|
972
|
+
}
|
|
973
|
+
const simple = param['#text'] ?? param.text ?? param.value;
|
|
974
|
+
if (simple !== undefined)
|
|
975
|
+
return simple;
|
|
976
|
+
return textOfStructured(param);
|
|
977
|
+
}
|
|
923
978
|
function extractCommandParameters(command) {
|
|
924
979
|
const parameters = {};
|
|
925
980
|
const params = command.Parameter || command.parameter;
|
|
@@ -928,7 +983,7 @@ function extractCommandParameters(command) {
|
|
|
928
983
|
const paramArray = Array.isArray(params) ? params : [params];
|
|
929
984
|
for (const param of paramArray) {
|
|
930
985
|
const key = param['@_Key'] || param.Key || param.key;
|
|
931
|
-
let value = param
|
|
986
|
+
let value = extractParamValue(param);
|
|
932
987
|
if (key && value !== undefined) {
|
|
933
988
|
// Try to convert to number if it looks numeric
|
|
934
989
|
if (typeof value === 'string' && /^\d+$/.test(value)) {
|
|
@@ -1,27 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
3
|
exports.GridsetProcessor = void 0;
|
|
27
4
|
const baseProcessor_1 = require("../core/baseProcessor");
|
|
@@ -726,6 +703,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
726
703
|
}
|
|
727
704
|
}
|
|
728
705
|
}
|
|
706
|
+
if (pageWordListItems.length > 0) {
|
|
707
|
+
page.wordListItems = pageWordListItems.map((item) => ({
|
|
708
|
+
text: item.text,
|
|
709
|
+
image: item.image,
|
|
710
|
+
partOfSpeech: item.partOfSpeech,
|
|
711
|
+
}));
|
|
712
|
+
}
|
|
729
713
|
// Track WordList AutoContent cells and their positions for "more" button placement
|
|
730
714
|
const wordListAutoContentCells = [];
|
|
731
715
|
let wordListCellIndex = 0;
|
|
@@ -1058,6 +1042,15 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1058
1042
|
const param = getRawParam(key);
|
|
1059
1043
|
if (param === undefined)
|
|
1060
1044
|
return undefined;
|
|
1045
|
+
if (typeof param === 'string')
|
|
1046
|
+
return param;
|
|
1047
|
+
if (param.p ||
|
|
1048
|
+
param.s ||
|
|
1049
|
+
(param.r !== undefined && typeof param.r !== 'string')) {
|
|
1050
|
+
const structuredValue = this.textOf(param);
|
|
1051
|
+
if (structuredValue !== undefined)
|
|
1052
|
+
return structuredValue;
|
|
1053
|
+
}
|
|
1061
1054
|
const simpleValue = param['#text'] ?? param.text ?? param.value;
|
|
1062
1055
|
if (typeof simpleValue === 'string')
|
|
1063
1056
|
return simpleValue;
|
|
@@ -1066,8 +1059,6 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1066
1059
|
const structuredValue = this.textOf(param);
|
|
1067
1060
|
if (structuredValue !== undefined)
|
|
1068
1061
|
return structuredValue;
|
|
1069
|
-
if (typeof param === 'string')
|
|
1070
|
-
return param;
|
|
1071
1062
|
return undefined;
|
|
1072
1063
|
};
|
|
1073
1064
|
// Skip PredictThis in primary action loop as it was handled in pre-pass
|
|
@@ -2253,9 +2244,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
2253
2244
|
await writeBinaryToPath(outputPath, originalBuffer);
|
|
2254
2245
|
return;
|
|
2255
2246
|
}
|
|
2256
|
-
const
|
|
2257
|
-
const
|
|
2258
|
-
const outputZip = new AdmZip();
|
|
2247
|
+
const originalZip = await this.options.zipAdapter(originalPath);
|
|
2248
|
+
const outputZip = await this.options.zipAdapter();
|
|
2259
2249
|
// Check if any page has pending mutations
|
|
2260
2250
|
const hasPendingMutations = Object.values(tree.pages).some((page) => page.pendingMutations.length > 0);
|
|
2261
2251
|
if (hasPendingMutations) {
|
|
@@ -2272,15 +2262,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
2272
2262
|
suppressBooleanAttributes: false,
|
|
2273
2263
|
});
|
|
2274
2264
|
saveMutations_1.GridsetSaveHandler.saveWithMutations(tree, originalZip, outputZip, parser, gridBuilder, (page) => this.createBasicGridXml(page));
|
|
2275
|
-
// Copy
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
outputZip.addFile(entry.entryName, entry.getData());
|
|
2281
|
-
}
|
|
2265
|
+
// Copy files
|
|
2266
|
+
const outputFiles = [];
|
|
2267
|
+
for (const name of originalZip.listFiles()) {
|
|
2268
|
+
const data = await originalZip.readFile(name);
|
|
2269
|
+
outputFiles.push({ name, data });
|
|
2282
2270
|
}
|
|
2283
|
-
const outputBuffer = outputZip.
|
|
2271
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
2284
2272
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
2285
2273
|
return;
|
|
2286
2274
|
}
|
|
@@ -2311,15 +2299,15 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
2311
2299
|
const gridPath = `Grids/${page.name}/grid.xml`;
|
|
2312
2300
|
modifiedGridFiles.add(gridPath);
|
|
2313
2301
|
// Try to get the original grid.xml file
|
|
2314
|
-
const
|
|
2315
|
-
if (!
|
|
2302
|
+
const originalEntries = originalZip.listFiles();
|
|
2303
|
+
if (!originalEntries.includes(gridPath)) {
|
|
2316
2304
|
// If original doesn't exist, create a new basic grid
|
|
2317
2305
|
const basicGrid = this.createBasicGridXml(page);
|
|
2318
2306
|
newGridFiles.set(gridPath, basicGrid);
|
|
2319
2307
|
continue;
|
|
2320
2308
|
}
|
|
2321
2309
|
// Parse the original grid XML
|
|
2322
|
-
const originalContent =
|
|
2310
|
+
const originalContent = (await originalZip.readFile(gridPath)).toString();
|
|
2323
2311
|
const originalGrid = parser.parse(originalContent);
|
|
2324
2312
|
if (!originalGrid.Grid) {
|
|
2325
2313
|
// Invalid grid structure, create a basic one
|
|
@@ -2484,22 +2472,22 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
2484
2472
|
newGridFiles.set(gridPath, builtXml);
|
|
2485
2473
|
}
|
|
2486
2474
|
// Copy all files from original zip, replacing modified grid files
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
continue;
|
|
2475
|
+
const outputFiles = [];
|
|
2476
|
+
for (const entry of originalZip.listFiles()) {
|
|
2490
2477
|
// Skip grid.xml files that we're modifying
|
|
2491
|
-
if (modifiedGridFiles.has(entry
|
|
2492
|
-
const newContent = newGridFiles.get(entry
|
|
2478
|
+
if (modifiedGridFiles.has(entry)) {
|
|
2479
|
+
const newContent = newGridFiles.get(entry);
|
|
2493
2480
|
if (newContent) {
|
|
2494
|
-
|
|
2481
|
+
outputFiles.push({ name: entry, data: Buffer.from(newContent, 'utf8') });
|
|
2495
2482
|
}
|
|
2496
2483
|
continue;
|
|
2497
2484
|
}
|
|
2498
2485
|
// Copy all other files as-is
|
|
2499
|
-
|
|
2486
|
+
const data = await originalZip.readFile(entry);
|
|
2487
|
+
outputFiles.push({ name: entry, data });
|
|
2500
2488
|
}
|
|
2501
2489
|
// Write the output ZIP
|
|
2502
|
-
const outputBuffer = outputZip.
|
|
2490
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
2503
2491
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
2504
2492
|
}
|
|
2505
2493
|
/**
|
|
@@ -1,27 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
3
|
exports.ObfProcessor = void 0;
|
|
27
4
|
const baseProcessor_1 = require("../core/baseProcessor");
|
|
@@ -767,24 +744,18 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
767
744
|
await writeBinaryToPath(outputPath, originalBuffer);
|
|
768
745
|
return;
|
|
769
746
|
}
|
|
770
|
-
const
|
|
771
|
-
const
|
|
772
|
-
const
|
|
773
|
-
// Track which .obf files we're modifying
|
|
774
|
-
const modifiedObfFiles = new Set();
|
|
775
|
-
// Generate new .obf files for pages in the tree
|
|
776
|
-
const newObfFiles = new Map();
|
|
747
|
+
const originalZip = await this.options.zipAdapter(originalPath);
|
|
748
|
+
const outputZip = await this.options.zipAdapter();
|
|
749
|
+
const outputFiles = [];
|
|
777
750
|
for (const page of Object.values(tree.pages)) {
|
|
778
|
-
const
|
|
779
|
-
modifiedObfFiles.add(obfFilename);
|
|
751
|
+
const name = this.getPageFilename(page.id, tree.metadata);
|
|
780
752
|
// createObfBoardFromPage will automatically apply mutations if present
|
|
781
753
|
const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
|
|
782
|
-
const
|
|
783
|
-
|
|
754
|
+
const data = JSON.stringify(obfBoard, null, 2);
|
|
755
|
+
outputFiles.push({ name, data });
|
|
784
756
|
}
|
|
785
757
|
// Generate updated manifest if we have pages
|
|
786
758
|
if (Object.keys(tree.pages).length > 0) {
|
|
787
|
-
modifiedObfFiles.add('manifest.json');
|
|
788
759
|
const manifest = {
|
|
789
760
|
format: OBF_FORMAT_VERSION,
|
|
790
761
|
root: tree.metadata.defaultHomePageId,
|
|
@@ -797,25 +768,18 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
797
768
|
sounds: {},
|
|
798
769
|
},
|
|
799
770
|
};
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const newContent = newObfFiles.get(entry.entryName);
|
|
809
|
-
if (newContent) {
|
|
810
|
-
outputZip.addFile(entry.entryName, Buffer.from(newContent, 'utf8'));
|
|
811
|
-
}
|
|
812
|
-
continue;
|
|
771
|
+
const data = Buffer.from(JSON.stringify(manifest), 'utf8');
|
|
772
|
+
outputFiles.push({ name: 'manifest.json', data });
|
|
773
|
+
}
|
|
774
|
+
// Add remaining .obf from original zip
|
|
775
|
+
for (const entry of originalZip.listFiles()) {
|
|
776
|
+
if (!outputFiles.find((file) => file.name === entry)) {
|
|
777
|
+
const data = await originalZip.readFile(entry);
|
|
778
|
+
outputFiles.push({ name: entry, data });
|
|
813
779
|
}
|
|
814
|
-
// Copy all other files as-is (preserves images, sounds, etc.)
|
|
815
|
-
outputZip.addFile(entry.entryName, entry.getData());
|
|
816
780
|
}
|
|
817
781
|
// Write the output ZIP
|
|
818
|
-
const outputBuffer = outputZip.
|
|
782
|
+
const outputBuffer = await outputZip.writeFiles(outputFiles);
|
|
819
783
|
await writeBinaryToPath(outputPath, outputBuffer);
|
|
820
784
|
}
|
|
821
785
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willwade/aac-processors",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "A comprehensive TypeScript library for processing AAC (Augmentative and Alternative Communication) file formats with translation support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"browser": "dist/browser/index.browser.js",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
],
|
|
132
132
|
"author": {
|
|
133
133
|
"name": "Will Wade",
|
|
134
|
-
"email": "
|
|
134
|
+
"email": "will@aactools.co.uk",
|
|
135
135
|
"url": "https://github.com/willwade"
|
|
136
136
|
},
|
|
137
137
|
"license": "MIT",
|
|
@@ -140,12 +140,12 @@
|
|
|
140
140
|
},
|
|
141
141
|
"repository": {
|
|
142
142
|
"type": "git",
|
|
143
|
-
"url": "https://github.com/
|
|
143
|
+
"url": "https://github.com/AACTools/AACProcessors-nodejs.git"
|
|
144
144
|
},
|
|
145
145
|
"bugs": {
|
|
146
|
-
"url": "https://github.com/
|
|
146
|
+
"url": "https://github.com/AACTools/AACProcessors-nodejs/issues"
|
|
147
147
|
},
|
|
148
|
-
"homepage": "https://github.com/
|
|
148
|
+
"homepage": "https://github.com/AACTools/AACProcessors-nodejs#readme",
|
|
149
149
|
"engines": {
|
|
150
150
|
"node": ">=20.0.0",
|
|
151
151
|
"npm": ">=9.0.0"
|