@willwade/aac-processors 0.1.5 → 0.1.7

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 (55) hide show
  1. package/README.md +14 -0
  2. package/dist/browser/index.browser.js +15 -1
  3. package/dist/browser/processors/gridset/password.js +11 -0
  4. package/dist/browser/processors/gridsetProcessor.js +42 -46
  5. package/dist/browser/processors/obfProcessor.js +47 -63
  6. package/dist/browser/processors/snapProcessor.js +1031 -0
  7. package/dist/browser/processors/touchchatProcessor.js +1004 -0
  8. package/dist/browser/utils/io.js +36 -2
  9. package/dist/browser/utils/sqlite.js +109 -0
  10. package/dist/browser/utils/zip.js +54 -0
  11. package/dist/browser/validation/gridsetValidator.js +7 -27
  12. package/dist/browser/validation/obfValidator.js +9 -4
  13. package/dist/browser/validation/snapValidator.js +197 -0
  14. package/dist/browser/validation/touchChatValidator.js +201 -0
  15. package/dist/index.browser.d.ts +7 -0
  16. package/dist/index.browser.js +19 -2
  17. package/dist/processors/gridset/helpers.js +3 -4
  18. package/dist/processors/gridset/index.d.ts +1 -1
  19. package/dist/processors/gridset/index.js +3 -2
  20. package/dist/processors/gridset/password.d.ts +3 -2
  21. package/dist/processors/gridset/password.js +12 -0
  22. package/dist/processors/gridset/wordlistHelpers.js +107 -51
  23. package/dist/processors/gridsetProcessor.js +40 -44
  24. package/dist/processors/obfProcessor.js +46 -62
  25. package/dist/processors/snapProcessor.js +60 -54
  26. package/dist/processors/touchchatProcessor.js +38 -36
  27. package/dist/utils/io.d.ts +4 -0
  28. package/dist/utils/io.js +40 -2
  29. package/dist/utils/sqlite.d.ts +21 -0
  30. package/dist/utils/sqlite.js +137 -0
  31. package/dist/utils/zip.d.ts +7 -0
  32. package/dist/utils/zip.js +80 -0
  33. package/dist/validation/applePanelsValidator.js +11 -28
  34. package/dist/validation/astericsValidator.js +11 -30
  35. package/dist/validation/dotValidator.js +11 -30
  36. package/dist/validation/excelValidator.js +5 -6
  37. package/dist/validation/gridsetValidator.js +29 -26
  38. package/dist/validation/index.d.ts +2 -1
  39. package/dist/validation/index.js +9 -32
  40. package/dist/validation/obfValidator.js +8 -3
  41. package/dist/validation/obfsetValidator.js +11 -30
  42. package/dist/validation/opmlValidator.js +11 -30
  43. package/dist/validation/snapValidator.js +6 -9
  44. package/dist/validation/touchChatValidator.js +6 -7
  45. package/docs/BROWSER_USAGE.md +2 -10
  46. package/examples/README.md +3 -75
  47. package/examples/vitedemo/README.md +13 -7
  48. package/examples/vitedemo/index.html +51 -2
  49. package/examples/vitedemo/package-lock.json +9 -0
  50. package/examples/vitedemo/package.json +1 -0
  51. package/examples/vitedemo/src/main.ts +132 -2
  52. package/examples/vitedemo/src/vite-env.d.ts +1 -0
  53. package/examples/vitedemo/vite.config.ts +26 -7
  54. package/package.json +3 -1
  55. package/examples/browser-test-server.js +0 -81
@@ -1,21 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.TouchChatProcessor = void 0;
7
4
  const baseProcessor_1 = require("../core/baseProcessor");
8
5
  const treeStructure_1 = require("../core/treeStructure");
9
6
  const idGenerator_1 = require("../utilities/analytics/utils/idGenerator");
10
7
  const stringCasing_1 = require("../core/stringCasing");
11
- const adm_zip_1 = __importDefault(require("adm-zip"));
12
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
13
- const path_1 = __importDefault(require("path"));
14
- const fs_1 = __importDefault(require("fs"));
15
- const os_1 = __importDefault(require("os"));
16
8
  const touchChatValidator_1 = require("../validation/touchChatValidator");
17
9
  const io_1 = require("../utils/io");
18
10
  const translationProcessor_1 = require("../utilities/translation/translationProcessor");
11
+ const sqlite_1 = require("../utils/sqlite");
12
+ const zip_1 = require("../utils/zip");
19
13
  const toNumberOrUndefined = (value) => typeof value === 'number' ? value : undefined;
20
14
  const toStringOrUndefined = (value) => typeof value === 'string' && value.length > 0 ? value : undefined;
21
15
  const toBooleanOrUndefined = (value) => typeof value === 'number' ? value !== 0 : undefined;
@@ -66,25 +60,22 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
66
60
  async loadIntoTree(filePathOrBuffer) {
67
61
  await Promise.resolve();
68
62
  // Unzip .ce file, extract the .c4v SQLite DB, and parse pages/buttons
69
- let tmpDir = null;
70
63
  let db = null;
64
+ let cleanup;
71
65
  try {
72
66
  // Store source file path or buffer
73
67
  this.sourceFile = filePathOrBuffer;
74
68
  // Step 1: Unzip
75
- tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'touchchat-'));
76
69
  const zipInput = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
77
- const zipBuffer = Buffer.isBuffer(zipInput) ? zipInput : Buffer.from(zipInput);
78
- const zip = new adm_zip_1.default(zipBuffer);
79
- zip.extractAllTo(tmpDir, true);
80
- // Step 2: Find and open SQLite DB
81
- const files = fs_1.default.readdirSync(tmpDir);
82
- const vocabFile = files.find((f) => f.endsWith('.c4v'));
83
- if (!vocabFile) {
70
+ const { zip } = await (0, zip_1.openZipFromInput)(zipInput);
71
+ const vocabEntry = zip.listFiles().find((name) => name.endsWith('.c4v'));
72
+ if (!vocabEntry) {
84
73
  throw new Error('No .c4v vocab DB found in TouchChat export');
85
74
  }
86
- const dbPath = path_1.default.join(tmpDir, vocabFile);
87
- db = new better_sqlite3_1.default(dbPath, { readonly: true });
75
+ const dbBuffer = await zip.readFile(vocabEntry);
76
+ const dbResult = await (0, sqlite_1.openSqliteDatabase)(dbBuffer, { readonly: true });
77
+ db = dbResult.db;
78
+ cleanup = dbResult.cleanup;
88
79
  // Step 3: Create tree and load pages
89
80
  const tree = new treeStructure_1.AACTree();
90
81
  // Set root ID to the first page ID (will be updated if we find a better root)
@@ -476,20 +467,18 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
476
467
  }
477
468
  finally {
478
469
  // Clean up
479
- if (db) {
480
- db.close();
470
+ if (cleanup) {
471
+ cleanup();
481
472
  }
482
- if (tmpDir && fs_1.default.existsSync(tmpDir)) {
483
- try {
484
- fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
485
- }
486
- catch (e) {
487
- console.warn('Failed to clean up temp directory:', e);
488
- }
473
+ else if (db) {
474
+ db.close();
489
475
  }
490
476
  }
491
477
  }
492
478
  async processTexts(filePathOrBuffer, translations, outputPath) {
479
+ if (!(0, io_1.isNodeRuntime)()) {
480
+ throw new Error('processTexts is only supported in Node.js environments for TouchChat files.');
481
+ }
493
482
  // Load the tree, apply translations, and save to new file
494
483
  const tree = await this.loadIntoTree(filePathOrBuffer);
495
484
  // Apply translations to all text content
@@ -519,15 +508,23 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
519
508
  });
520
509
  // Save the translated tree and return its content
521
510
  await this.saveFromTree(tree, outputPath);
522
- return fs_1.default.readFileSync(outputPath);
511
+ const fs = (0, io_1.getFs)();
512
+ return fs.readFileSync(outputPath);
523
513
  }
524
514
  async saveFromTree(tree, outputPath) {
525
515
  await Promise.resolve();
516
+ if (!(0, io_1.isNodeRuntime)()) {
517
+ throw new Error('saveFromTree is only supported in Node.js environments for TouchChat files.');
518
+ }
519
+ const fs = (0, io_1.getFs)();
520
+ const path = (0, io_1.getPath)();
521
+ const os = (0, io_1.getOs)();
526
522
  // Create a TouchChat database that matches the expected schema for loading
527
- const tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'touchchat-export-'));
528
- const dbPath = path_1.default.join(tmpDir, 'vocab.c4v');
523
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'touchchat-export-'));
524
+ const dbPath = path.join(tmpDir, 'vocab.c4v');
529
525
  try {
530
- const db = new better_sqlite3_1.default(dbPath);
526
+ const Database = (0, sqlite_1.requireBetterSqlite3)();
527
+ const db = new Database(dbPath);
531
528
  // Create schema that matches what loadIntoTree expects
532
529
  db.exec(`
533
530
  CREATE TABLE IF NOT EXISTS resources (
@@ -817,14 +814,15 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
817
814
  }
818
815
  db.close();
819
816
  // Create zip file with the database
820
- const zip = new adm_zip_1.default();
817
+ const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
818
+ const zip = new AdmZip();
821
819
  zip.addLocalFile(dbPath, '', 'vocab.c4v');
822
820
  zip.writeZip(outputPath);
823
821
  }
824
822
  finally {
825
823
  // Clean up
826
- if (fs_1.default.existsSync(tmpDir)) {
827
- fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
824
+ if (fs.existsSync(tmpDir)) {
825
+ fs.rmSync(tmpDir, { recursive: true, force: true });
828
826
  }
829
827
  }
830
828
  }
@@ -961,6 +959,9 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
961
959
  * @returns Buffer of the translated TouchChat file
962
960
  */
963
961
  async processLLMTranslations(filePathOrBuffer, llmTranslations, outputPath, options) {
962
+ if (!(0, io_1.isNodeRuntime)()) {
963
+ throw new Error('processLLMTranslations is only supported in Node.js environments for TouchChat files.');
964
+ }
964
965
  const tree = await this.loadIntoTree(filePathOrBuffer);
965
966
  // Validate translations using shared utility
966
967
  const buttonIds = Object.values(tree.pages).flatMap((page) => page.buttons.map((b) => b.id));
@@ -999,7 +1000,8 @@ class TouchChatProcessor extends baseProcessor_1.BaseProcessor {
999
1000
  });
1000
1001
  // Save and return
1001
1002
  await this.saveFromTree(tree, outputPath);
1002
- return fs_1.default.readFileSync(outputPath);
1003
+ const fs = (0, io_1.getFs)();
1004
+ return fs.readFileSync(outputPath);
1003
1005
  }
1004
1006
  }
1005
1007
  exports.TouchChatProcessor = TouchChatProcessor;
@@ -4,7 +4,11 @@ type NodeRequire = (id: string) => any;
4
4
  export declare function getNodeRequire(): NodeRequire;
5
5
  export declare function getFs(): typeof import('fs');
6
6
  export declare function getPath(): typeof import('path');
7
+ export declare function getOs(): typeof import('os');
8
+ export declare function isNodeRuntime(): boolean;
7
9
  export declare function getBasename(filePath: string): string;
10
+ export declare function toUint8Array(input: Uint8Array | ArrayBuffer | Buffer): Uint8Array;
11
+ export declare function toArrayBuffer(input: Uint8Array | ArrayBuffer | Buffer): ArrayBuffer;
8
12
  export declare function decodeText(input: Uint8Array): string;
9
13
  export declare function encodeBase64(input: Uint8Array): string;
10
14
  export declare function encodeText(text: string): BinaryOutput;
package/dist/utils/io.js CHANGED
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getNodeRequire = getNodeRequire;
4
4
  exports.getFs = getFs;
5
5
  exports.getPath = getPath;
6
+ exports.getOs = getOs;
7
+ exports.isNodeRuntime = isNodeRuntime;
6
8
  exports.getBasename = getBasename;
9
+ exports.toUint8Array = toUint8Array;
10
+ exports.toArrayBuffer = toArrayBuffer;
7
11
  exports.decodeText = decodeText;
8
12
  exports.encodeBase64 = encodeBase64;
9
13
  exports.encodeText = encodeText;
@@ -13,6 +17,7 @@ exports.writeBinaryToPath = writeBinaryToPath;
13
17
  exports.writeTextToPath = writeTextToPath;
14
18
  let cachedFs = null;
15
19
  let cachedPath = null;
20
+ let cachedOs = null;
16
21
  let cachedRequire = undefined;
17
22
  function getNodeRequire() {
18
23
  if (cachedRequire === undefined) {
@@ -64,9 +69,42 @@ function getPath() {
64
69
  }
65
70
  return cachedPath;
66
71
  }
72
+ function getOs() {
73
+ if (!cachedOs) {
74
+ try {
75
+ const nodeRequire = getNodeRequire();
76
+ const osModule = 'os';
77
+ cachedOs = nodeRequire(osModule);
78
+ }
79
+ catch {
80
+ throw new Error('OS utilities are not available in this environment.');
81
+ }
82
+ }
83
+ if (!cachedOs) {
84
+ throw new Error('OS utilities are not available in this environment.');
85
+ }
86
+ return cachedOs;
87
+ }
88
+ function isNodeRuntime() {
89
+ return typeof process !== 'undefined' && !!process.versions?.node;
90
+ }
67
91
  function getBasename(filePath) {
68
- const parts = filePath.split(/[/\\]/);
69
- return parts[parts.length - 1] || filePath;
92
+ const trimmed = filePath.replace(/[/\\]+$/, '') || filePath;
93
+ const parts = trimmed.split(/[/\\]/);
94
+ return parts[parts.length - 1] || trimmed;
95
+ }
96
+ function toUint8Array(input) {
97
+ if (input instanceof Uint8Array) {
98
+ return input;
99
+ }
100
+ return new Uint8Array(input);
101
+ }
102
+ function toArrayBuffer(input) {
103
+ if (input instanceof ArrayBuffer) {
104
+ return input;
105
+ }
106
+ const view = input instanceof Uint8Array ? input : new Uint8Array(input);
107
+ return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
70
108
  }
71
109
  function decodeText(input) {
72
110
  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
@@ -0,0 +1,21 @@
1
+ import type { SqlJsConfig } from 'sql.js';
2
+ export interface SqliteStatementAdapter {
3
+ all(...params: unknown[]): any[];
4
+ get(...params: unknown[]): any;
5
+ run(...params: unknown[]): any;
6
+ }
7
+ export interface SqliteDatabaseAdapter {
8
+ prepare(sql: string): SqliteStatementAdapter;
9
+ exec(sql: string): void;
10
+ close(): void;
11
+ }
12
+ export interface SqliteOpenOptions {
13
+ readonly?: boolean;
14
+ }
15
+ export interface SqliteOpenResult {
16
+ db: SqliteDatabaseAdapter;
17
+ cleanup?: () => void;
18
+ }
19
+ export declare function configureSqlJs(config: SqlJsConfig): void;
20
+ export declare function requireBetterSqlite3(): typeof import('better-sqlite3');
21
+ export declare function openSqliteDatabase(input: string | Uint8Array | ArrayBuffer | Buffer, options?: SqliteOpenOptions): Promise<SqliteOpenResult>;
@@ -0,0 +1,137 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.configureSqlJs = configureSqlJs;
27
+ exports.requireBetterSqlite3 = requireBetterSqlite3;
28
+ exports.openSqliteDatabase = openSqliteDatabase;
29
+ const io_1 = require("./io");
30
+ let sqlJsConfig = null;
31
+ let sqlJsPromise = null;
32
+ function configureSqlJs(config) {
33
+ sqlJsConfig = { ...(sqlJsConfig ?? {}), ...config };
34
+ }
35
+ async function getSqlJs() {
36
+ if (!sqlJsPromise) {
37
+ sqlJsPromise = Promise.resolve().then(() => __importStar(require('sql.js'))).then((module) => {
38
+ const initSqlJs = module.default || module;
39
+ return initSqlJs(sqlJsConfig ?? {});
40
+ });
41
+ }
42
+ return sqlJsPromise;
43
+ }
44
+ function createSqlJsAdapter(db) {
45
+ return {
46
+ prepare(sql) {
47
+ return {
48
+ all(...params) {
49
+ const stmt = db.prepare(sql);
50
+ if (params.length > 0) {
51
+ stmt.bind(params);
52
+ }
53
+ const rows = [];
54
+ while (stmt.step()) {
55
+ rows.push(stmt.getAsObject());
56
+ }
57
+ stmt.free();
58
+ return rows;
59
+ },
60
+ get(...params) {
61
+ const stmt = db.prepare(sql);
62
+ if (params.length > 0) {
63
+ stmt.bind(params);
64
+ }
65
+ const row = stmt.step() ? stmt.getAsObject() : undefined;
66
+ stmt.free();
67
+ return row;
68
+ },
69
+ run(...params) {
70
+ const stmt = db.prepare(sql);
71
+ if (params.length > 0) {
72
+ stmt.bind(params);
73
+ }
74
+ stmt.step();
75
+ stmt.free();
76
+ return undefined;
77
+ },
78
+ };
79
+ },
80
+ exec(sql) {
81
+ db.exec(sql);
82
+ },
83
+ close() {
84
+ db.close();
85
+ },
86
+ };
87
+ }
88
+ function getBetterSqlite3() {
89
+ try {
90
+ const nodeRequire = (0, io_1.getNodeRequire)();
91
+ return nodeRequire('better-sqlite3');
92
+ }
93
+ catch {
94
+ throw new Error('better-sqlite3 is not available in this environment.');
95
+ }
96
+ }
97
+ function requireBetterSqlite3() {
98
+ return getBetterSqlite3();
99
+ }
100
+ async function openSqliteDatabase(input, options = {}) {
101
+ if (typeof input === 'string') {
102
+ if (!(0, io_1.isNodeRuntime)()) {
103
+ throw new Error('SQLite file paths are not supported in browser environments.');
104
+ }
105
+ const Database = getBetterSqlite3();
106
+ const db = new Database(input, { readonly: options.readonly ?? true });
107
+ return { db };
108
+ }
109
+ const data = (0, io_1.readBinaryFromInput)(input);
110
+ if (!(0, io_1.isNodeRuntime)()) {
111
+ const SQL = await getSqlJs();
112
+ const db = new SQL.Database(data);
113
+ return { db: createSqlJsAdapter(db) };
114
+ }
115
+ const fs = (0, io_1.getFs)();
116
+ const path = (0, io_1.getPath)();
117
+ const os = (0, io_1.getOs)();
118
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aac-sqlite-'));
119
+ const dbPath = path.join(tempDir, 'input.sqlite');
120
+ fs.writeFileSync(dbPath, data);
121
+ const Database = getBetterSqlite3();
122
+ const db = new Database(dbPath, { readonly: options.readonly ?? true });
123
+ const cleanup = () => {
124
+ try {
125
+ db.close();
126
+ }
127
+ finally {
128
+ try {
129
+ fs.rmSync(tempDir, { recursive: true, force: true });
130
+ }
131
+ catch (error) {
132
+ console.warn('Failed to clean up temporary SQLite files:', error);
133
+ }
134
+ }
135
+ };
136
+ return { db, cleanup };
137
+ }
@@ -0,0 +1,7 @@
1
+ export interface ZipAdapter {
2
+ listFiles(): string[];
3
+ readFile(name: string): Promise<Uint8Array>;
4
+ }
5
+ export declare function openZipFromInput(input: string | Uint8Array | ArrayBuffer | Buffer): Promise<{
6
+ zip: ZipAdapter;
7
+ }>;
@@ -0,0 +1,80 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.openZipFromInput = openZipFromInput;
27
+ const io_1 = require("./io");
28
+ async function openZipFromInput(input) {
29
+ if (typeof input === 'string') {
30
+ if (!(0, io_1.isNodeRuntime)()) {
31
+ throw new Error('Zip file paths are not supported in browser environments.');
32
+ }
33
+ const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
34
+ const admZip = new AdmZip(input);
35
+ return {
36
+ zip: {
37
+ listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
38
+ readFile: (name) => {
39
+ const entry = admZip.getEntry(name);
40
+ if (!entry) {
41
+ throw new Error(`Zip entry not found: ${name}`);
42
+ }
43
+ return Promise.resolve(entry.getData());
44
+ },
45
+ },
46
+ };
47
+ }
48
+ const data = (0, io_1.readBinaryFromInput)(input);
49
+ if ((0, io_1.isNodeRuntime)()) {
50
+ const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
51
+ const admZip = new AdmZip(Buffer.from(data));
52
+ return {
53
+ zip: {
54
+ listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
55
+ readFile: (name) => {
56
+ const entry = admZip.getEntry(name);
57
+ if (!entry) {
58
+ throw new Error(`Zip entry not found: ${name}`);
59
+ }
60
+ return Promise.resolve(entry.getData());
61
+ },
62
+ },
63
+ };
64
+ }
65
+ const module = await Promise.resolve().then(() => __importStar(require('jszip')));
66
+ const init = module.default || module;
67
+ const zip = await init.loadAsync(data);
68
+ return {
69
+ zip: {
70
+ listFiles: () => Object.keys(zip.files),
71
+ readFile: async (name) => {
72
+ const file = zip.file(name);
73
+ if (!file) {
74
+ throw new Error(`Zip entry not found: ${name}`);
75
+ }
76
+ return file.async('uint8array');
77
+ },
78
+ },
79
+ };
80
+ }
@@ -1,45 +1,23 @@
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
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.ApplePanelsValidator = void 0;
30
7
  /* eslint-disable @typescript-eslint/require-await */
31
- const fs = __importStar(require("fs"));
32
- const path = __importStar(require("path"));
33
8
  const plist_1 = __importDefault(require("plist"));
34
9
  const baseValidator_1 = require("./baseValidator");
10
+ const io_1 = require("../utils/io");
35
11
  /**
36
12
  * Validator for Apple Panels (.plist or .ascconfig directory)
37
13
  */
38
14
  class ApplePanelsValidator extends baseValidator_1.BaseValidator {
39
15
  static async validateFile(filePath) {
40
16
  const validator = new ApplePanelsValidator();
17
+ const fs = (0, io_1.getFs)();
18
+ const path = (0, io_1.getPath)();
41
19
  let content;
42
- const filename = path.basename(filePath);
20
+ const filename = (0, io_1.getBasename)(filePath);
43
21
  let size = 0;
44
22
  const stats = fs.existsSync(filePath) ? fs.statSync(filePath) : null;
45
23
  if (stats?.isDirectory() && filename.toLowerCase().endsWith('.ascconfig')) {
@@ -62,7 +40,12 @@ class ApplePanelsValidator extends baseValidator_1.BaseValidator {
62
40
  return true;
63
41
  }
64
42
  try {
65
- const str = Buffer.isBuffer(content) ? content.toString('utf-8') : String(content);
43
+ if (typeof content !== 'string' &&
44
+ !(content instanceof ArrayBuffer) &&
45
+ !(content instanceof Uint8Array)) {
46
+ return false;
47
+ }
48
+ const str = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
66
49
  const parsed = plist_1.default.parse(str);
67
50
  return Boolean(parsed.panels || parsed.Panels);
68
51
  }
@@ -80,7 +63,7 @@ class ApplePanelsValidator extends baseValidator_1.BaseValidator {
80
63
  let parsed = null;
81
64
  await this.add_check('plist_parse', 'valid plist/XML', async () => {
82
65
  try {
83
- const str = Buffer.isBuffer(content) ? content.toString('utf-8') : String(content);
66
+ const str = (0, io_1.decodeText)(content);
84
67
  parsed = plist_1.default.parse(str);
85
68
  }
86
69
  catch (e) {
@@ -1,33 +1,9 @@
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.AstericsGridValidator = void 0;
27
4
  /* eslint-disable @typescript-eslint/require-await */
28
- const fs = __importStar(require("fs"));
29
- const path = __importStar(require("path"));
30
5
  const baseValidator_1 = require("./baseValidator");
6
+ const io_1 = require("../utils/io");
31
7
  /**
32
8
  * Validator for Asterics Grid (.grd) JSON files
33
9
  */
@@ -37,9 +13,9 @@ class AstericsGridValidator extends baseValidator_1.BaseValidator {
37
13
  */
38
14
  static async validateFile(filePath) {
39
15
  const validator = new AstericsGridValidator();
40
- const content = fs.readFileSync(filePath);
41
- const stats = fs.statSync(filePath);
42
- return validator.validate(content, path.basename(filePath), stats.size);
16
+ const content = (0, io_1.readBinaryFromInput)(filePath);
17
+ const stats = (0, io_1.getFs)().statSync(filePath);
18
+ return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
43
19
  }
44
20
  /**
45
21
  * Identify whether the content appears to be an Asterics .grd file
@@ -50,7 +26,12 @@ class AstericsGridValidator extends baseValidator_1.BaseValidator {
50
26
  return true;
51
27
  }
52
28
  try {
53
- const str = Buffer.isBuffer(content) ? content.toString('utf-8') : String(content);
29
+ if (typeof content !== 'string' &&
30
+ !(content instanceof ArrayBuffer) &&
31
+ !(content instanceof Uint8Array)) {
32
+ return false;
33
+ }
34
+ const str = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
54
35
  const json = JSON.parse(str);
55
36
  return Array.isArray(json?.grids);
56
37
  }
@@ -68,7 +49,7 @@ class AstericsGridValidator extends baseValidator_1.BaseValidator {
68
49
  let json = null;
69
50
  await this.add_check('json_parse', 'valid JSON', async () => {
70
51
  try {
71
- let str = Buffer.isBuffer(content) ? content.toString('utf-8') : String(content);
52
+ let str = (0, io_1.decodeText)(content);
72
53
  if (str.charCodeAt(0) === 0xfeff) {
73
54
  str = str.slice(1);
74
55
  }