@willwade/aac-processors 0.0.9 β†’ 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +85 -11
  2. package/dist/cli/index.js +87 -0
  3. package/dist/core/analyze.js +1 -0
  4. package/dist/core/baseProcessor.d.ts +3 -0
  5. package/dist/core/fileProcessor.js +1 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +3 -0
  8. package/dist/optional/symbolTools.js +4 -2
  9. package/dist/processors/gridset/helpers.d.ts +1 -1
  10. package/dist/processors/gridset/helpers.js +5 -3
  11. package/dist/processors/gridset/password.d.ts +11 -0
  12. package/dist/processors/gridset/password.js +37 -0
  13. package/dist/processors/gridset/resolver.d.ts +1 -1
  14. package/dist/processors/gridset/resolver.js +8 -4
  15. package/dist/processors/gridset/wordlistHelpers.d.ts +2 -2
  16. package/dist/processors/gridset/wordlistHelpers.js +7 -4
  17. package/dist/processors/gridsetProcessor.d.ts +15 -1
  18. package/dist/processors/gridsetProcessor.js +64 -22
  19. package/dist/processors/index.d.ts +1 -0
  20. package/dist/processors/index.js +5 -2
  21. package/dist/processors/obfProcessor.d.ts +7 -0
  22. package/dist/processors/obfProcessor.js +9 -0
  23. package/dist/processors/snapProcessor.d.ts +7 -0
  24. package/dist/processors/snapProcessor.js +9 -0
  25. package/dist/processors/touchchatProcessor.d.ts +7 -0
  26. package/dist/processors/touchchatProcessor.js +9 -0
  27. package/dist/utilities/screenshotConverter.d.ts +69 -0
  28. package/dist/utilities/screenshotConverter.js +453 -0
  29. package/dist/validation/baseValidator.d.ts +80 -0
  30. package/dist/validation/baseValidator.js +160 -0
  31. package/dist/validation/gridsetValidator.d.ts +36 -0
  32. package/dist/validation/gridsetValidator.js +288 -0
  33. package/dist/validation/index.d.ts +13 -0
  34. package/dist/validation/index.js +69 -0
  35. package/dist/validation/obfValidator.d.ts +44 -0
  36. package/dist/validation/obfValidator.js +530 -0
  37. package/dist/validation/snapValidator.d.ts +33 -0
  38. package/dist/validation/snapValidator.js +237 -0
  39. package/dist/validation/touchChatValidator.d.ts +33 -0
  40. package/dist/validation/touchChatValidator.js +229 -0
  41. package/dist/validation/validationTypes.d.ts +64 -0
  42. package/dist/validation/validationTypes.js +15 -0
  43. package/examples/README.md +7 -0
  44. package/examples/demo.js +143 -0
  45. package/examples/obf/aboutme.json +376 -0
  46. package/examples/obf/array.json +6 -0
  47. package/examples/obf/hash.json +4 -0
  48. package/examples/obf/links.obz +0 -0
  49. package/examples/obf/simple.obf +53 -0
  50. package/examples/package-lock.json +1326 -0
  51. package/examples/package.json +10 -0
  52. package/examples/styling-example.ts +316 -0
  53. package/examples/translate.js +39 -0
  54. package/examples/translate_demo.js +254 -0
  55. package/examples/typescript-demo.ts +251 -0
  56. package/package.json +3 -1
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ /**
4
+ * TypeScript Demo - AACProcessors 2.0
5
+ *
6
+ * This example demonstrates the new TypeScript API and features
7
+ * including translation workflows and cross-format conversion.
8
+ */
9
+
10
+ import {
11
+ getProcessor,
12
+ DotProcessor,
13
+ ObfProcessor,
14
+ AACTree,
15
+ AACPage,
16
+ AACButton
17
+ } from '../src/index';
18
+ import fs from 'fs';
19
+ import path from 'path';
20
+
21
+ async function main() {
22
+ console.log('πŸš€ AACProcessors 2.0 TypeScript Demo\n');
23
+
24
+ // Example 1: Auto-detect processor by file extension
25
+ console.log('πŸ“ Example 1: Auto-detection');
26
+ try {
27
+ const dotFile = path.join(__dirname, 'example.dot');
28
+ if (fs.existsSync(dotFile)) {
29
+ const processor = getProcessor(dotFile);
30
+ console.log(`βœ… Detected processor: ${processor.constructor.name}`);
31
+
32
+ const tree = processor.loadIntoTree(dotFile);
33
+ console.log(`πŸ“Š Loaded ${Object.keys(tree.pages).length} pages`);
34
+
35
+ const texts = processor.extractTexts(dotFile);
36
+ console.log(`πŸ“ Found ${texts.length} text elements`);
37
+ } else {
38
+ console.log('⚠️ example.dot not found, skipping auto-detection demo');
39
+ }
40
+ } catch (error) {
41
+ console.error('❌ Auto-detection error:', error);
42
+ }
43
+
44
+ console.log('\n' + '='.repeat(50) + '\n');
45
+
46
+ // Example 2: Create a communication board programmatically
47
+ console.log('πŸ—οΈ Example 2: Programmatic Board Creation');
48
+
49
+ const tree = new AACTree();
50
+
51
+ // Create home page
52
+ const homePage = new AACPage({
53
+ id: 'home',
54
+ name: 'Home Page',
55
+ buttons: []
56
+ });
57
+
58
+ // Add buttons
59
+ const greetingButton = new AACButton({
60
+ id: 'btn_hello',
61
+ label: 'Hello',
62
+ message: 'Hello, how are you today?',
63
+ type: 'SPEAK'
64
+ });
65
+
66
+ const foodButton = new AACButton({
67
+ id: 'btn_food',
68
+ label: 'Food',
69
+ message: 'I want something to eat',
70
+ type: 'NAVIGATE',
71
+ targetPageId: 'food_page'
72
+ });
73
+
74
+ const drinkButton = new AACButton({
75
+ id: 'btn_drink',
76
+ label: 'Drink',
77
+ message: 'I want something to drink',
78
+ type: 'SPEAK'
79
+ });
80
+
81
+ homePage.addButton(greetingButton);
82
+ homePage.addButton(foodButton);
83
+ homePage.addButton(drinkButton);
84
+ tree.addPage(homePage);
85
+
86
+ // Create food page
87
+ const foodPage = new AACPage({
88
+ id: 'food_page',
89
+ name: 'Food Options',
90
+ buttons: []
91
+ });
92
+
93
+ const appleButton = new AACButton({
94
+ id: 'btn_apple',
95
+ label: 'Apple',
96
+ message: 'I want an apple',
97
+ type: 'SPEAK'
98
+ });
99
+
100
+ const backButton = new AACButton({
101
+ id: 'btn_back',
102
+ label: 'Back',
103
+ message: 'Go back to home',
104
+ type: 'NAVIGATE',
105
+ targetPageId: 'home'
106
+ });
107
+
108
+ foodPage.addButton(appleButton);
109
+ foodPage.addButton(backButton);
110
+ tree.addPage(foodPage);
111
+
112
+ tree.rootId = 'home';
113
+
114
+ console.log(`βœ… Created communication board with ${Object.keys(tree.pages).length} pages`);
115
+
116
+ console.log('\n' + '='.repeat(50) + '\n');
117
+
118
+ // Example 3: Save to multiple formats
119
+ console.log('πŸ’Ύ Example 3: Cross-Format Conversion');
120
+
121
+ const tempDir = path.join(__dirname, 'temp');
122
+ if (!fs.existsSync(tempDir)) {
123
+ fs.mkdirSync(tempDir);
124
+ }
125
+
126
+ try {
127
+ // Save as DOT
128
+ const dotProcessor = new DotProcessor();
129
+ const dotPath = path.join(tempDir, 'demo-board.dot');
130
+ dotProcessor.saveFromTree(tree, dotPath);
131
+ console.log(`βœ… Saved as DOT: ${dotPath}`);
132
+
133
+ // Save as OBF
134
+ const obfProcessor = new ObfProcessor();
135
+ const obfPath = path.join(tempDir, 'demo-board.obf');
136
+ obfProcessor.saveFromTree(tree, obfPath);
137
+ console.log(`βœ… Saved as OBF: ${obfPath}`);
138
+
139
+ // Verify round-trip integrity
140
+ const reloadedDotTree = dotProcessor.loadIntoTree(dotPath);
141
+ const reloadedObfTree = obfProcessor.loadIntoTree(obfPath);
142
+
143
+ console.log(`πŸ”„ DOT round-trip: ${Object.keys(reloadedDotTree.pages).length} pages`);
144
+ console.log(`πŸ”„ OBF round-trip: ${Object.keys(reloadedObfTree.pages).length} pages`);
145
+
146
+ } catch (error) {
147
+ console.error('❌ Conversion error:', error);
148
+ }
149
+
150
+ console.log('\n' + '='.repeat(50) + '\n');
151
+
152
+ // Example 4: Translation workflow
153
+ console.log('🌍 Example 4: Translation Workflow');
154
+
155
+ try {
156
+ const dotPath = path.join(tempDir, 'demo-board.dot');
157
+ if (fs.existsSync(dotPath)) {
158
+ const processor = new DotProcessor();
159
+
160
+ // Extract all text
161
+ const originalTexts = processor.extractTexts(dotPath);
162
+ console.log(`πŸ“ Found ${originalTexts.length} translatable texts:`, originalTexts);
163
+
164
+ // Create Spanish translations
165
+ const translations = new Map([
166
+ ['Hello', 'Hola'],
167
+ ['Food', 'Comida'],
168
+ ['Drink', 'Bebida'],
169
+ ['Apple', 'Manzana'],
170
+ ['Back', 'AtrΓ‘s'],
171
+ ['Home Page', 'PΓ‘gina Principal'],
172
+ ['Food Options', 'Opciones de Comida'],
173
+ ['Hello, how are you today?', 'Hola, ΒΏcΓ³mo estΓ‘s hoy?'],
174
+ ['I want something to eat', 'Quiero algo de comer'],
175
+ ['I want something to drink', 'Quiero algo de beber'],
176
+ ['I want an apple', 'Quiero una manzana'],
177
+ ['Go back to home', 'Volver a casa']
178
+ ]);
179
+
180
+ // Apply translations
181
+ const spanishPath = path.join(tempDir, 'demo-board-spanish.dot');
182
+ const translatedBuffer = processor.processTexts(dotPath, translations, spanishPath);
183
+
184
+ console.log(`βœ… Applied ${translations.size} translations`);
185
+ console.log(`πŸ’Ύ Saved Spanish version: ${spanishPath}`);
186
+
187
+ // Verify translations
188
+ const spanishTexts = processor.extractTexts(spanishPath);
189
+ console.log(`πŸ” Spanish texts:`, spanishTexts.slice(0, 5), '...');
190
+
191
+ } else {
192
+ console.log('⚠️ DOT file not found for translation demo');
193
+ }
194
+ } catch (error) {
195
+ console.error('❌ Translation error:', error);
196
+ }
197
+
198
+ console.log('\n' + '='.repeat(50) + '\n');
199
+
200
+ // Example 5: Error handling
201
+ console.log('πŸ›‘οΈ Example 5: Error Handling');
202
+
203
+ try {
204
+ const processor = new DotProcessor();
205
+
206
+ // Try to load a non-existent file
207
+ try {
208
+ processor.loadIntoTree('non-existent-file.dot');
209
+ } catch (error) {
210
+ console.log(`βœ… Caught expected error: ${error instanceof Error ? error.message : error}`);
211
+ }
212
+
213
+ // Try to load invalid content
214
+ try {
215
+ const invalidContent = Buffer.from('This is not a valid DOT file');
216
+ const tree = processor.loadIntoTree(invalidContent);
217
+ console.log(`βœ… Gracefully handled invalid content: ${Object.keys(tree.pages).length} pages`);
218
+ } catch (error) {
219
+ console.log(`βœ… Handled invalid content error: ${error instanceof Error ? error.message : error}`);
220
+ }
221
+
222
+ } catch (error) {
223
+ console.error('❌ Error handling demo failed:', error);
224
+ }
225
+
226
+ console.log('\nπŸŽ‰ Demo completed successfully!');
227
+ console.log('\nπŸ“š For more examples, see:');
228
+ console.log(' - README.md for API documentation');
229
+ console.log(' - test/ directory for comprehensive usage examples');
230
+ console.log(' - examples/ directory for more demos');
231
+
232
+ // Cleanup
233
+ try {
234
+ if (fs.existsSync(tempDir)) {
235
+ fs.rmSync(tempDir, { recursive: true, force: true });
236
+ console.log('\n🧹 Cleaned up temporary files');
237
+ }
238
+ } catch (error) {
239
+ console.warn('⚠️ Failed to clean up temporary files:', error);
240
+ }
241
+ }
242
+
243
+ // Run the demo
244
+ if (require.main === module) {
245
+ main().catch(error => {
246
+ console.error('❌ Demo failed:', error);
247
+ process.exit(1);
248
+ });
249
+ }
250
+
251
+ export { main as runDemo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willwade/aac-processors",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
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
  "types": "dist/index.d.ts",
@@ -93,6 +93,7 @@
93
93
  "typescript": "~5.5.0"
94
94
  },
95
95
  "dependencies": {
96
+ "@types/xml2js": "^0.4.14",
96
97
  "adm-zip": "^0.5.16",
97
98
  "axios": "^1.11.0",
98
99
  "better-sqlite3": "^11.9.1",
@@ -100,6 +101,7 @@
100
101
  "exceljs": "^4.4.0",
101
102
  "fast-xml-parser": "^5.2.0",
102
103
  "plist": "^3.1.0",
104
+ "xml2js": "^0.6.2",
103
105
  "yauzl": "^3.2.0"
104
106
  },
105
107
  "bin": {