@willwade/aac-processors 0.1.6 → 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.
- package/dist/browser/utils/io.js +16 -2
- package/dist/browser/validation/gridsetValidator.js +7 -27
- package/dist/browser/validation/obfValidator.js +9 -4
- package/dist/browser/validation/snapValidator.js +6 -9
- package/dist/browser/validation/touchChatValidator.js +6 -7
- package/dist/utils/io.d.ts +2 -0
- package/dist/utils/io.js +18 -2
- package/dist/validation/applePanelsValidator.js +11 -28
- package/dist/validation/astericsValidator.js +11 -30
- package/dist/validation/dotValidator.js +11 -30
- package/dist/validation/excelValidator.js +5 -6
- package/dist/validation/gridsetValidator.js +29 -26
- package/dist/validation/index.d.ts +2 -1
- package/dist/validation/index.js +9 -32
- package/dist/validation/obfValidator.js +8 -3
- package/dist/validation/obfsetValidator.js +11 -30
- package/dist/validation/opmlValidator.js +11 -30
- package/dist/validation/snapValidator.js +6 -9
- package/dist/validation/touchChatValidator.js +6 -7
- package/examples/vitedemo/index.html +49 -0
- package/examples/vitedemo/src/main.ts +84 -0
- package/examples/vitedemo/vite.config.ts +26 -7
- package/package.json +1 -1
package/dist/browser/utils/io.js
CHANGED
|
@@ -72,8 +72,22 @@ export function isNodeRuntime() {
|
|
|
72
72
|
return typeof process !== 'undefined' && !!process.versions?.node;
|
|
73
73
|
}
|
|
74
74
|
export function getBasename(filePath) {
|
|
75
|
-
const
|
|
76
|
-
|
|
75
|
+
const trimmed = filePath.replace(/[/\\]+$/, '') || filePath;
|
|
76
|
+
const parts = trimmed.split(/[/\\]/);
|
|
77
|
+
return parts[parts.length - 1] || trimmed;
|
|
78
|
+
}
|
|
79
|
+
export function toUint8Array(input) {
|
|
80
|
+
if (input instanceof Uint8Array) {
|
|
81
|
+
return input;
|
|
82
|
+
}
|
|
83
|
+
return new Uint8Array(input);
|
|
84
|
+
}
|
|
85
|
+
export function toArrayBuffer(input) {
|
|
86
|
+
if (input instanceof ArrayBuffer) {
|
|
87
|
+
return input;
|
|
88
|
+
}
|
|
89
|
+
const view = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
90
|
+
return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
|
77
91
|
}
|
|
78
92
|
export function decodeText(input) {
|
|
79
93
|
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
|
|
@@ -2,24 +2,9 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
4
|
import JSZip from 'jszip';
|
|
5
|
+
import * as xml2js from 'xml2js';
|
|
5
6
|
import { BaseValidator } from './baseValidator';
|
|
6
|
-
import {
|
|
7
|
-
let cachedXml2js = null;
|
|
8
|
-
function getXml2js() {
|
|
9
|
-
if (cachedXml2js)
|
|
10
|
-
return cachedXml2js;
|
|
11
|
-
try {
|
|
12
|
-
const nodeRequire = getNodeRequire();
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
14
|
-
const module = nodeRequire('xml2js');
|
|
15
|
-
const resolved = module.default || module;
|
|
16
|
-
cachedXml2js = resolved;
|
|
17
|
-
return resolved;
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
throw new Error('Validator requires Xml2js in this environment.');
|
|
21
|
-
}
|
|
22
|
-
}
|
|
7
|
+
import { decodeText, getBasename, getFs, toUint8Array } from '../utils/io';
|
|
23
8
|
/**
|
|
24
9
|
* Validator for Grid3/Smartbox Gridset files (.gridset, .gridsetx)
|
|
25
10
|
*/
|
|
@@ -33,10 +18,9 @@ export class GridsetValidator extends BaseValidator {
|
|
|
33
18
|
static async validateFile(filePath) {
|
|
34
19
|
const validator = new GridsetValidator();
|
|
35
20
|
const fs = getFs();
|
|
36
|
-
const path = getPath();
|
|
37
21
|
const content = fs.readFileSync(filePath);
|
|
38
22
|
const stats = fs.statSync(filePath);
|
|
39
|
-
return validator.validate(content,
|
|
23
|
+
return validator.validate(content, getBasename(filePath), stats.size);
|
|
40
24
|
}
|
|
41
25
|
/**
|
|
42
26
|
* Check if content is Gridset format
|
|
@@ -48,8 +32,7 @@ export class GridsetValidator extends BaseValidator {
|
|
|
48
32
|
}
|
|
49
33
|
// Try to parse as XML and check for gridset structure
|
|
50
34
|
try {
|
|
51
|
-
const contentStr =
|
|
52
|
-
const xml2js = getXml2js();
|
|
35
|
+
const contentStr = typeof content === 'string' ? content : decodeText(toUint8Array(content));
|
|
53
36
|
const parser = new xml2js.Parser();
|
|
54
37
|
const result = await parser.parseStringPromise(contentStr);
|
|
55
38
|
return result && (result.gridset || result.Gridset);
|
|
@@ -102,9 +85,8 @@ export class GridsetValidator extends BaseValidator {
|
|
|
102
85
|
let xmlObj = null;
|
|
103
86
|
await this.add_check('xml_parse', 'valid XML', async () => {
|
|
104
87
|
try {
|
|
105
|
-
const xml2js = getXml2js();
|
|
106
88
|
const parser = new xml2js.Parser();
|
|
107
|
-
const contentStr = content
|
|
89
|
+
const contentStr = decodeText(content);
|
|
108
90
|
xmlObj = await parser.parseStringPromise(contentStr);
|
|
109
91
|
}
|
|
110
92
|
catch (e) {
|
|
@@ -129,7 +111,7 @@ export class GridsetValidator extends BaseValidator {
|
|
|
129
111
|
async validateZipArchive(content, filename, _filesize) {
|
|
130
112
|
let zip;
|
|
131
113
|
try {
|
|
132
|
-
zip = await JSZip.loadAsync(
|
|
114
|
+
zip = await JSZip.loadAsync(toUint8Array(content));
|
|
133
115
|
}
|
|
134
116
|
catch (e) {
|
|
135
117
|
this.err(`Failed to open ZIP archive: ${e.message}`, true);
|
|
@@ -145,7 +127,6 @@ export class GridsetValidator extends BaseValidator {
|
|
|
145
127
|
else {
|
|
146
128
|
try {
|
|
147
129
|
const gridsetXml = await gridsetEntry.async('string');
|
|
148
|
-
const xml2js = getXml2js();
|
|
149
130
|
const parser = new xml2js.Parser();
|
|
150
131
|
const xmlObj = await parser.parseStringPromise(gridsetXml);
|
|
151
132
|
const gridset = xmlObj.gridset || xmlObj.Gridset;
|
|
@@ -153,7 +134,7 @@ export class GridsetValidator extends BaseValidator {
|
|
|
153
134
|
this.err('Invalid gridset.xml structure', true);
|
|
154
135
|
}
|
|
155
136
|
else {
|
|
156
|
-
await this.validateGridsetStructure(gridset, filename,
|
|
137
|
+
await this.validateGridsetStructure(gridset, filename, new Uint8Array());
|
|
157
138
|
}
|
|
158
139
|
}
|
|
159
140
|
catch (e) {
|
|
@@ -170,7 +151,6 @@ export class GridsetValidator extends BaseValidator {
|
|
|
170
151
|
else {
|
|
171
152
|
try {
|
|
172
153
|
const settingsXml = await settingsEntry.async('string');
|
|
173
|
-
const xml2js = getXml2js();
|
|
174
154
|
const parser = new xml2js.Parser();
|
|
175
155
|
const xmlObj = await parser.parseStringPromise(settingsXml);
|
|
176
156
|
const settings = xmlObj.GridSetSettings || xmlObj.gridSetSettings || xmlObj.GridsetSettings;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
|
6
6
|
import JSZip from 'jszip';
|
|
7
7
|
import { BaseValidator } from './baseValidator';
|
|
8
|
-
import {
|
|
8
|
+
import { decodeText, getBasename, getFs, readBinaryFromInput, toUint8Array } from '../utils/io';
|
|
9
9
|
const OBF_FORMAT = 'open-board-0.1';
|
|
10
10
|
const OBF_FORMAT_CURRENT_VERSION = 0.1;
|
|
11
11
|
/**
|
|
@@ -22,7 +22,7 @@ export class ObfValidator extends BaseValidator {
|
|
|
22
22
|
const validator = new ObfValidator();
|
|
23
23
|
const content = readBinaryFromInput(filePath);
|
|
24
24
|
const stats = getFs().statSync(filePath);
|
|
25
|
-
return validator.validate(content,
|
|
25
|
+
return validator.validate(content, getBasename(filePath), stats.size);
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Check if content is OBF format
|
|
@@ -34,7 +34,12 @@ export class ObfValidator extends BaseValidator {
|
|
|
34
34
|
}
|
|
35
35
|
// Try to parse as JSON and check format
|
|
36
36
|
try {
|
|
37
|
-
|
|
37
|
+
if (typeof content !== 'string' &&
|
|
38
|
+
!(content instanceof ArrayBuffer) &&
|
|
39
|
+
!(content instanceof Uint8Array)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const contentStr = typeof content === 'string' ? content : decodeText(toUint8Array(content));
|
|
38
43
|
const json = JSON.parse(contentStr);
|
|
39
44
|
return json && json.format && json.format.startsWith('open-board-');
|
|
40
45
|
}
|
|
@@ -68,7 +73,7 @@ export class ObfValidator extends BaseValidator {
|
|
|
68
73
|
let json = null;
|
|
69
74
|
await this.add_check('valid_json', 'JSON file', async () => {
|
|
70
75
|
try {
|
|
71
|
-
json = JSON.parse(content
|
|
76
|
+
json = JSON.parse(decodeText(content));
|
|
72
77
|
}
|
|
73
78
|
catch {
|
|
74
79
|
this.err("Couldn't parse as JSON", true);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/require-await */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import * as path from 'path';
|
|
5
3
|
import * as xml2js from 'xml2js';
|
|
6
4
|
import JSZip from 'jszip';
|
|
7
5
|
import { BaseValidator } from './baseValidator';
|
|
6
|
+
import { getBasename, getFs, readBinaryFromInput, toUint8Array } from '../utils/io';
|
|
8
7
|
/**
|
|
9
8
|
* Validator for Snap files (.spb, .sps)
|
|
10
9
|
* Snap files are zipped packages containing XML configuration
|
|
@@ -18,9 +17,9 @@ export class SnapValidator extends BaseValidator {
|
|
|
18
17
|
*/
|
|
19
18
|
static async validateFile(filePath) {
|
|
20
19
|
const validator = new SnapValidator();
|
|
21
|
-
const content =
|
|
22
|
-
const stats =
|
|
23
|
-
return validator.validate(content,
|
|
20
|
+
const content = readBinaryFromInput(filePath);
|
|
21
|
+
const stats = getFs().statSync(filePath);
|
|
22
|
+
return validator.validate(content, getBasename(filePath), stats.size);
|
|
24
23
|
}
|
|
25
24
|
/**
|
|
26
25
|
* Check if content is Snap format
|
|
@@ -33,8 +32,7 @@ export class SnapValidator extends BaseValidator {
|
|
|
33
32
|
}
|
|
34
33
|
// Try to parse as ZIP and check for Snap structure
|
|
35
34
|
try {
|
|
36
|
-
const
|
|
37
|
-
const zip = await JSZip.loadAsync(buffer);
|
|
35
|
+
const zip = await JSZip.loadAsync(toUint8Array(content));
|
|
38
36
|
const entries = Object.values(zip.files).filter((entry) => !entry.dir);
|
|
39
37
|
return entries.some((entry) => entry.name.includes('settings') || entry.name.includes('.xml'));
|
|
40
38
|
}
|
|
@@ -56,8 +54,7 @@ export class SnapValidator extends BaseValidator {
|
|
|
56
54
|
let validZip = false;
|
|
57
55
|
await this.add_check('zip', 'valid zip package', async () => {
|
|
58
56
|
try {
|
|
59
|
-
|
|
60
|
-
zip = await JSZip.loadAsync(buffer);
|
|
57
|
+
zip = await JSZip.loadAsync(toUint8Array(content));
|
|
61
58
|
const entries = Object.values(zip.files);
|
|
62
59
|
validZip = entries.length > 0;
|
|
63
60
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/require-await */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
|
-
import * as fs from 'fs';
|
|
5
|
-
import * as path from 'path';
|
|
6
4
|
import * as xml2js from 'xml2js';
|
|
7
5
|
import { BaseValidator } from './baseValidator';
|
|
6
|
+
import { decodeText, getBasename, getFs, readBinaryFromInput, toUint8Array } from '../utils/io';
|
|
8
7
|
/**
|
|
9
8
|
* Validator for TouchChat files (.ce)
|
|
10
9
|
* TouchChat files are XML-based
|
|
@@ -18,9 +17,9 @@ export class TouchChatValidator extends BaseValidator {
|
|
|
18
17
|
*/
|
|
19
18
|
static async validateFile(filePath) {
|
|
20
19
|
const validator = new TouchChatValidator();
|
|
21
|
-
const content =
|
|
22
|
-
const stats =
|
|
23
|
-
return validator.validate(content,
|
|
20
|
+
const content = readBinaryFromInput(filePath);
|
|
21
|
+
const stats = getFs().statSync(filePath);
|
|
22
|
+
return validator.validate(content, getBasename(filePath), stats.size);
|
|
24
23
|
}
|
|
25
24
|
/**
|
|
26
25
|
* Check if content is TouchChat format
|
|
@@ -32,7 +31,7 @@ export class TouchChatValidator extends BaseValidator {
|
|
|
32
31
|
}
|
|
33
32
|
// Try to parse as XML and check for TouchChat structure
|
|
34
33
|
try {
|
|
35
|
-
const contentStr =
|
|
34
|
+
const contentStr = typeof content === 'string' ? content : decodeText(toUint8Array(content));
|
|
36
35
|
const parser = new xml2js.Parser();
|
|
37
36
|
const result = await parser.parseStringPromise(contentStr);
|
|
38
37
|
// TouchChat files typically have specific structure
|
|
@@ -56,7 +55,7 @@ export class TouchChatValidator extends BaseValidator {
|
|
|
56
55
|
await this.add_check('xml_parse', 'valid XML', async () => {
|
|
57
56
|
try {
|
|
58
57
|
const parser = new xml2js.Parser();
|
|
59
|
-
const contentStr = content
|
|
58
|
+
const contentStr = decodeText(content);
|
|
60
59
|
xmlObj = await parser.parseStringPromise(contentStr);
|
|
61
60
|
}
|
|
62
61
|
catch (e) {
|
package/dist/utils/io.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare function getPath(): typeof import('path');
|
|
|
7
7
|
export declare function getOs(): typeof import('os');
|
|
8
8
|
export declare function isNodeRuntime(): boolean;
|
|
9
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;
|
|
10
12
|
export declare function decodeText(input: Uint8Array): string;
|
|
11
13
|
export declare function encodeBase64(input: Uint8Array): string;
|
|
12
14
|
export declare function encodeText(text: string): BinaryOutput;
|
package/dist/utils/io.js
CHANGED
|
@@ -6,6 +6,8 @@ exports.getPath = getPath;
|
|
|
6
6
|
exports.getOs = getOs;
|
|
7
7
|
exports.isNodeRuntime = isNodeRuntime;
|
|
8
8
|
exports.getBasename = getBasename;
|
|
9
|
+
exports.toUint8Array = toUint8Array;
|
|
10
|
+
exports.toArrayBuffer = toArrayBuffer;
|
|
9
11
|
exports.decodeText = decodeText;
|
|
10
12
|
exports.encodeBase64 = encodeBase64;
|
|
11
13
|
exports.encodeText = encodeText;
|
|
@@ -87,8 +89,22 @@ function isNodeRuntime() {
|
|
|
87
89
|
return typeof process !== 'undefined' && !!process.versions?.node;
|
|
88
90
|
}
|
|
89
91
|
function getBasename(filePath) {
|
|
90
|
-
const
|
|
91
|
-
|
|
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);
|
|
92
108
|
}
|
|
93
109
|
function decodeText(input) {
|
|
94
110
|
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(input)) {
|
|
@@ -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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
41
|
-
const stats =
|
|
42
|
-
return validator.validate(content,
|
|
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
|
-
|
|
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 =
|
|
52
|
+
let str = (0, io_1.decodeText)(content);
|
|
72
53
|
if (str.charCodeAt(0) === 0xfeff) {
|
|
73
54
|
str = str.slice(1);
|
|
74
55
|
}
|
|
@@ -1,49 +1,30 @@
|
|
|
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.DotValidator = 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 Graphviz DOT files
|
|
33
9
|
*/
|
|
34
10
|
class DotValidator extends baseValidator_1.BaseValidator {
|
|
35
11
|
static async validateFile(filePath) {
|
|
36
12
|
const validator = new DotValidator();
|
|
37
|
-
const content =
|
|
38
|
-
const stats =
|
|
39
|
-
return validator.validate(content,
|
|
13
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
14
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
15
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
40
16
|
}
|
|
41
17
|
static async identifyFormat(content, filename) {
|
|
42
18
|
const name = filename.toLowerCase();
|
|
43
19
|
if (name.endsWith('.dot'))
|
|
44
20
|
return true;
|
|
45
21
|
try {
|
|
46
|
-
|
|
22
|
+
if (typeof content !== 'string' &&
|
|
23
|
+
!(content instanceof ArrayBuffer) &&
|
|
24
|
+
!(content instanceof Uint8Array)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const str = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
47
28
|
return str.includes('digraph') || str.includes('->');
|
|
48
29
|
}
|
|
49
30
|
catch {
|
|
@@ -59,7 +40,7 @@ class DotValidator extends baseValidator_1.BaseValidator {
|
|
|
59
40
|
});
|
|
60
41
|
let text = '';
|
|
61
42
|
await this.add_check('text', 'text content', async () => {
|
|
62
|
-
text =
|
|
43
|
+
text = (0, io_1.decodeText)(content);
|
|
63
44
|
if (!text.trim()) {
|
|
64
45
|
this.err('DOT file is empty', true);
|
|
65
46
|
}
|
|
@@ -25,19 +25,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.ExcelValidator = void 0;
|
|
27
27
|
/* eslint-disable @typescript-eslint/require-await */
|
|
28
|
-
const fs = __importStar(require("fs"));
|
|
29
|
-
const path = __importStar(require("path"));
|
|
30
28
|
const ExcelJS = __importStar(require("exceljs"));
|
|
31
29
|
const baseValidator_1 = require("./baseValidator");
|
|
30
|
+
const io_1 = require("../utils/io");
|
|
32
31
|
/**
|
|
33
32
|
* Validator for Excel imports (.xlsx/.xls)
|
|
34
33
|
*/
|
|
35
34
|
class ExcelValidator extends baseValidator_1.BaseValidator {
|
|
36
35
|
static async validateFile(filePath) {
|
|
37
36
|
const validator = new ExcelValidator();
|
|
38
|
-
const content =
|
|
39
|
-
const stats =
|
|
40
|
-
return validator.validate(content,
|
|
37
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
38
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
39
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
41
40
|
}
|
|
42
41
|
static async identifyFormat(_content, filename) {
|
|
43
42
|
const name = filename.toLowerCase();
|
|
@@ -58,7 +57,7 @@ class ExcelValidator extends baseValidator_1.BaseValidator {
|
|
|
58
57
|
});
|
|
59
58
|
return this.buildResult(filename, filesize, 'excel');
|
|
60
59
|
}
|
|
61
|
-
const buffer = Buffer.isBuffer(content) ? content :
|
|
60
|
+
const buffer = typeof Buffer !== 'undefined' && Buffer.isBuffer(content) ? content : (0, io_1.toArrayBuffer)(content);
|
|
62
61
|
const workbook = new ExcelJS.Workbook();
|
|
63
62
|
await this.add_check('open', 'open workbook', async () => {
|
|
64
63
|
try {
|
|
@@ -1,4 +1,27 @@
|
|
|
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
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
@@ -8,24 +31,9 @@ exports.GridsetValidator = void 0;
|
|
|
8
31
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
9
32
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
10
33
|
const jszip_1 = __importDefault(require("jszip"));
|
|
34
|
+
const xml2js = __importStar(require("xml2js"));
|
|
11
35
|
const baseValidator_1 = require("./baseValidator");
|
|
12
36
|
const io_1 = require("../utils/io");
|
|
13
|
-
let cachedXml2js = null;
|
|
14
|
-
function getXml2js() {
|
|
15
|
-
if (cachedXml2js)
|
|
16
|
-
return cachedXml2js;
|
|
17
|
-
try {
|
|
18
|
-
const nodeRequire = (0, io_1.getNodeRequire)();
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
20
|
-
const module = nodeRequire('xml2js');
|
|
21
|
-
const resolved = module.default || module;
|
|
22
|
-
cachedXml2js = resolved;
|
|
23
|
-
return resolved;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
throw new Error('Validator requires Xml2js in this environment.');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
37
|
/**
|
|
30
38
|
* Validator for Grid3/Smartbox Gridset files (.gridset, .gridsetx)
|
|
31
39
|
*/
|
|
@@ -39,10 +47,9 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
39
47
|
static async validateFile(filePath) {
|
|
40
48
|
const validator = new GridsetValidator();
|
|
41
49
|
const fs = (0, io_1.getFs)();
|
|
42
|
-
const path = (0, io_1.getPath)();
|
|
43
50
|
const content = fs.readFileSync(filePath);
|
|
44
51
|
const stats = fs.statSync(filePath);
|
|
45
|
-
return validator.validate(content,
|
|
52
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
55
|
* Check if content is Gridset format
|
|
@@ -54,8 +61,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
54
61
|
}
|
|
55
62
|
// Try to parse as XML and check for gridset structure
|
|
56
63
|
try {
|
|
57
|
-
const contentStr =
|
|
58
|
-
const xml2js = getXml2js();
|
|
64
|
+
const contentStr = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
59
65
|
const parser = new xml2js.Parser();
|
|
60
66
|
const result = await parser.parseStringPromise(contentStr);
|
|
61
67
|
return result && (result.gridset || result.Gridset);
|
|
@@ -108,9 +114,8 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
108
114
|
let xmlObj = null;
|
|
109
115
|
await this.add_check('xml_parse', 'valid XML', async () => {
|
|
110
116
|
try {
|
|
111
|
-
const xml2js = getXml2js();
|
|
112
117
|
const parser = new xml2js.Parser();
|
|
113
|
-
const contentStr =
|
|
118
|
+
const contentStr = (0, io_1.decodeText)(content);
|
|
114
119
|
xmlObj = await parser.parseStringPromise(contentStr);
|
|
115
120
|
}
|
|
116
121
|
catch (e) {
|
|
@@ -135,7 +140,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
135
140
|
async validateZipArchive(content, filename, _filesize) {
|
|
136
141
|
let zip;
|
|
137
142
|
try {
|
|
138
|
-
zip = await jszip_1.default.loadAsync(
|
|
143
|
+
zip = await jszip_1.default.loadAsync((0, io_1.toUint8Array)(content));
|
|
139
144
|
}
|
|
140
145
|
catch (e) {
|
|
141
146
|
this.err(`Failed to open ZIP archive: ${e.message}`, true);
|
|
@@ -151,7 +156,6 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
151
156
|
else {
|
|
152
157
|
try {
|
|
153
158
|
const gridsetXml = await gridsetEntry.async('string');
|
|
154
|
-
const xml2js = getXml2js();
|
|
155
159
|
const parser = new xml2js.Parser();
|
|
156
160
|
const xmlObj = await parser.parseStringPromise(gridsetXml);
|
|
157
161
|
const gridset = xmlObj.gridset || xmlObj.Gridset;
|
|
@@ -159,7 +163,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
159
163
|
this.err('Invalid gridset.xml structure', true);
|
|
160
164
|
}
|
|
161
165
|
else {
|
|
162
|
-
await this.validateGridsetStructure(gridset, filename,
|
|
166
|
+
await this.validateGridsetStructure(gridset, filename, new Uint8Array());
|
|
163
167
|
}
|
|
164
168
|
}
|
|
165
169
|
catch (e) {
|
|
@@ -176,7 +180,6 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
176
180
|
else {
|
|
177
181
|
try {
|
|
178
182
|
const settingsXml = await settingsEntry.async('string');
|
|
179
|
-
const xml2js = getXml2js();
|
|
180
183
|
const parser = new xml2js.Parser();
|
|
181
184
|
const xmlObj = await parser.parseStringPromise(settingsXml);
|
|
182
185
|
const settings = xmlObj.GridSetSettings || xmlObj.gridSetSettings || xmlObj.GridsetSettings;
|
|
@@ -16,6 +16,7 @@ export { ApplePanelsValidator } from './applePanelsValidator';
|
|
|
16
16
|
export { ObfsetValidator } from './obfsetValidator';
|
|
17
17
|
import { BaseValidator } from './baseValidator';
|
|
18
18
|
import { ValidationResult } from './validationTypes';
|
|
19
|
+
import { type ProcessorInput } from '../utils/io';
|
|
19
20
|
export declare function getValidatorForFormat(format: string): BaseValidator | null;
|
|
20
21
|
export declare function getValidatorForFile(filename: string): BaseValidator | null;
|
|
21
22
|
/**
|
|
@@ -23,4 +24,4 @@ export declare function getValidatorForFile(filename: string): BaseValidator | n
|
|
|
23
24
|
* When a file path is provided, any validator-specific validateFile() helper
|
|
24
25
|
* will be used if available to access nested resources.
|
|
25
26
|
*/
|
|
26
|
-
export declare function validateFileOrBuffer(filePathOrBuffer:
|
|
27
|
+
export declare function validateFileOrBuffer(filePathOrBuffer: ProcessorInput, filenameHint?: string): Promise<ValidationResult>;
|
package/dist/validation/index.js
CHANGED
|
@@ -3,29 +3,6 @@
|
|
|
3
3
|
* Validation system for AAC processors
|
|
4
4
|
* Provides consistent validation across all supported formats
|
|
5
5
|
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
|
-
if (mod && mod.__esModule) return mod;
|
|
24
|
-
var result = {};
|
|
25
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
26
|
-
__setModuleDefault(result, mod);
|
|
27
|
-
return result;
|
|
28
|
-
};
|
|
29
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
7
|
exports.ObfsetValidator = exports.ApplePanelsValidator = exports.DotValidator = exports.OpmlValidator = exports.ExcelValidator = exports.AstericsGridValidator = exports.TouchChatValidator = exports.SnapValidator = exports.GridsetValidator = exports.ObfValidator = exports.BaseValidator = exports.buildValidationResultFromMessage = exports.ValidationFailureError = exports.ValidationError = void 0;
|
|
31
8
|
exports.getValidatorForFormat = getValidatorForFormat;
|
|
@@ -72,8 +49,7 @@ const opmlValidator_2 = require("./opmlValidator");
|
|
|
72
49
|
const dotValidator_2 = require("./dotValidator");
|
|
73
50
|
const applePanelsValidator_2 = require("./applePanelsValidator");
|
|
74
51
|
const obfsetValidator_2 = require("./obfsetValidator");
|
|
75
|
-
const
|
|
76
|
-
const path = __importStar(require("path"));
|
|
52
|
+
const io_1 = require("../utils/io");
|
|
77
53
|
function getValidatorForFormat(format) {
|
|
78
54
|
switch (format.toLowerCase()) {
|
|
79
55
|
case 'obf':
|
|
@@ -151,22 +127,23 @@ function getValidatorForFile(filename) {
|
|
|
151
127
|
*/
|
|
152
128
|
async function validateFileOrBuffer(filePathOrBuffer, filenameHint) {
|
|
153
129
|
const isPath = typeof filePathOrBuffer === 'string';
|
|
154
|
-
const name = filenameHint || (isPath ?
|
|
130
|
+
const name = filenameHint || (isPath ? (0, io_1.getBasename)(filePathOrBuffer) : 'upload');
|
|
155
131
|
const validator = getValidatorForFile(name) || getValidatorForFormat(name);
|
|
156
132
|
if (!validator) {
|
|
157
133
|
throw new Error(`No validator registered for ${name}`);
|
|
158
134
|
}
|
|
159
135
|
if (isPath) {
|
|
136
|
+
if (!(0, io_1.isNodeRuntime)()) {
|
|
137
|
+
throw new Error('File path validation is only supported in Node.js environments.');
|
|
138
|
+
}
|
|
160
139
|
const ctor = validator.constructor;
|
|
161
140
|
if (typeof ctor.validateFile === 'function') {
|
|
162
141
|
return ctor.validateFile(filePathOrBuffer);
|
|
163
142
|
}
|
|
164
|
-
const buf =
|
|
165
|
-
const stats =
|
|
166
|
-
return validator.validate(buf,
|
|
143
|
+
const buf = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
|
|
144
|
+
const stats = (0, io_1.getFs)().statSync(filePathOrBuffer);
|
|
145
|
+
return validator.validate(buf, (0, io_1.getBasename)(filePathOrBuffer), stats.size);
|
|
167
146
|
}
|
|
168
|
-
const buffer =
|
|
169
|
-
? filePathOrBuffer
|
|
170
|
-
: Buffer.from(filePathOrBuffer);
|
|
147
|
+
const buffer = (0, io_1.toUint8Array)(filePathOrBuffer);
|
|
171
148
|
return validator.validate(buffer, name, buffer.byteLength);
|
|
172
149
|
}
|
|
@@ -28,7 +28,7 @@ class ObfValidator extends baseValidator_1.BaseValidator {
|
|
|
28
28
|
const validator = new ObfValidator();
|
|
29
29
|
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
30
30
|
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
31
|
-
return validator.validate(content, (0, io_1.
|
|
31
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Check if content is OBF format
|
|
@@ -40,7 +40,12 @@ class ObfValidator extends baseValidator_1.BaseValidator {
|
|
|
40
40
|
}
|
|
41
41
|
// Try to parse as JSON and check format
|
|
42
42
|
try {
|
|
43
|
-
|
|
43
|
+
if (typeof content !== 'string' &&
|
|
44
|
+
!(content instanceof ArrayBuffer) &&
|
|
45
|
+
!(content instanceof Uint8Array)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const contentStr = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
44
49
|
const json = JSON.parse(contentStr);
|
|
45
50
|
return json && json.format && json.format.startsWith('open-board-');
|
|
46
51
|
}
|
|
@@ -74,7 +79,7 @@ class ObfValidator extends baseValidator_1.BaseValidator {
|
|
|
74
79
|
let json = null;
|
|
75
80
|
await this.add_check('valid_json', 'JSON file', async () => {
|
|
76
81
|
try {
|
|
77
|
-
json = JSON.parse(
|
|
82
|
+
json = JSON.parse((0, io_1.decodeText)(content));
|
|
78
83
|
}
|
|
79
84
|
catch {
|
|
80
85
|
this.err("Couldn't parse as JSON", true);
|
|
@@ -1,49 +1,30 @@
|
|
|
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.ObfsetValidator = 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 OBF set bundles (.obfset) - JSON arrays of boards
|
|
33
9
|
*/
|
|
34
10
|
class ObfsetValidator extends baseValidator_1.BaseValidator {
|
|
35
11
|
static async validateFile(filePath) {
|
|
36
12
|
const validator = new ObfsetValidator();
|
|
37
|
-
const content =
|
|
38
|
-
const stats =
|
|
39
|
-
return validator.validate(content,
|
|
13
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
14
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
15
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
40
16
|
}
|
|
41
17
|
static async identifyFormat(content, filename) {
|
|
42
18
|
const name = filename.toLowerCase();
|
|
43
19
|
if (name.endsWith('.obfset'))
|
|
44
20
|
return true;
|
|
45
21
|
try {
|
|
46
|
-
|
|
22
|
+
if (typeof content !== 'string' &&
|
|
23
|
+
!(content instanceof ArrayBuffer) &&
|
|
24
|
+
!(content instanceof Uint8Array)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const str = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
47
28
|
const parsed = JSON.parse(str);
|
|
48
29
|
return Array.isArray(parsed);
|
|
49
30
|
}
|
|
@@ -61,7 +42,7 @@ class ObfsetValidator extends baseValidator_1.BaseValidator {
|
|
|
61
42
|
let boards = null;
|
|
62
43
|
await this.add_check('json_parse', 'valid JSON array', async () => {
|
|
63
44
|
try {
|
|
64
|
-
const str =
|
|
45
|
+
const str = (0, io_1.decodeText)(content);
|
|
65
46
|
const parsed = JSON.parse(str);
|
|
66
47
|
if (!Array.isArray(parsed)) {
|
|
67
48
|
this.err('root must be a JSON array of boards', true);
|
|
@@ -1,43 +1,19 @@
|
|
|
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.OpmlValidator = 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 fast_xml_parser_1 = require("fast-xml-parser");
|
|
31
6
|
const baseValidator_1 = require("./baseValidator");
|
|
7
|
+
const io_1 = require("../utils/io");
|
|
32
8
|
/**
|
|
33
9
|
* Validator for OPML files
|
|
34
10
|
*/
|
|
35
11
|
class OpmlValidator extends baseValidator_1.BaseValidator {
|
|
36
12
|
static async validateFile(filePath) {
|
|
37
13
|
const validator = new OpmlValidator();
|
|
38
|
-
const content =
|
|
39
|
-
const stats =
|
|
40
|
-
return validator.validate(content,
|
|
14
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
15
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
16
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
41
17
|
}
|
|
42
18
|
static async identifyFormat(content, filename) {
|
|
43
19
|
const name = filename.toLowerCase();
|
|
@@ -45,7 +21,12 @@ class OpmlValidator extends baseValidator_1.BaseValidator {
|
|
|
45
21
|
return true;
|
|
46
22
|
}
|
|
47
23
|
try {
|
|
48
|
-
|
|
24
|
+
if (typeof content !== 'string' &&
|
|
25
|
+
!(content instanceof ArrayBuffer) &&
|
|
26
|
+
!(content instanceof Uint8Array)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const str = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
49
30
|
const validation = fast_xml_parser_1.XMLValidator.validate(str);
|
|
50
31
|
if (validation !== true) {
|
|
51
32
|
return false;
|
|
@@ -68,7 +49,7 @@ class OpmlValidator extends baseValidator_1.BaseValidator {
|
|
|
68
49
|
});
|
|
69
50
|
let text = '';
|
|
70
51
|
await this.add_check('content', 'non-empty content', async () => {
|
|
71
|
-
text =
|
|
52
|
+
text = (0, io_1.decodeText)(content);
|
|
72
53
|
if (!text.trim()) {
|
|
73
54
|
this.err('OPML file is empty', true);
|
|
74
55
|
}
|
|
@@ -29,11 +29,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.SnapValidator = void 0;
|
|
30
30
|
/* eslint-disable @typescript-eslint/require-await */
|
|
31
31
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
32
|
-
const fs = __importStar(require("fs"));
|
|
33
|
-
const path = __importStar(require("path"));
|
|
34
32
|
const xml2js = __importStar(require("xml2js"));
|
|
35
33
|
const jszip_1 = __importDefault(require("jszip"));
|
|
36
34
|
const baseValidator_1 = require("./baseValidator");
|
|
35
|
+
const io_1 = require("../utils/io");
|
|
37
36
|
/**
|
|
38
37
|
* Validator for Snap files (.spb, .sps)
|
|
39
38
|
* Snap files are zipped packages containing XML configuration
|
|
@@ -47,9 +46,9 @@ class SnapValidator extends baseValidator_1.BaseValidator {
|
|
|
47
46
|
*/
|
|
48
47
|
static async validateFile(filePath) {
|
|
49
48
|
const validator = new SnapValidator();
|
|
50
|
-
const content =
|
|
51
|
-
const stats =
|
|
52
|
-
return validator.validate(content,
|
|
49
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
50
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
51
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
54
|
* Check if content is Snap format
|
|
@@ -62,8 +61,7 @@ class SnapValidator extends baseValidator_1.BaseValidator {
|
|
|
62
61
|
}
|
|
63
62
|
// Try to parse as ZIP and check for Snap structure
|
|
64
63
|
try {
|
|
65
|
-
const
|
|
66
|
-
const zip = await jszip_1.default.loadAsync(buffer);
|
|
64
|
+
const zip = await jszip_1.default.loadAsync((0, io_1.toUint8Array)(content));
|
|
67
65
|
const entries = Object.values(zip.files).filter((entry) => !entry.dir);
|
|
68
66
|
return entries.some((entry) => entry.name.includes('settings') || entry.name.includes('.xml'));
|
|
69
67
|
}
|
|
@@ -85,8 +83,7 @@ class SnapValidator extends baseValidator_1.BaseValidator {
|
|
|
85
83
|
let validZip = false;
|
|
86
84
|
await this.add_check('zip', 'valid zip package', async () => {
|
|
87
85
|
try {
|
|
88
|
-
|
|
89
|
-
zip = await jszip_1.default.loadAsync(buffer);
|
|
86
|
+
zip = await jszip_1.default.loadAsync((0, io_1.toUint8Array)(content));
|
|
90
87
|
const entries = Object.values(zip.files);
|
|
91
88
|
validZip = entries.length > 0;
|
|
92
89
|
}
|
|
@@ -27,10 +27,9 @@ exports.TouchChatValidator = void 0;
|
|
|
27
27
|
/* eslint-disable @typescript-eslint/require-await */
|
|
28
28
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
29
29
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
30
|
-
const fs = __importStar(require("fs"));
|
|
31
|
-
const path = __importStar(require("path"));
|
|
32
30
|
const xml2js = __importStar(require("xml2js"));
|
|
33
31
|
const baseValidator_1 = require("./baseValidator");
|
|
32
|
+
const io_1 = require("../utils/io");
|
|
34
33
|
/**
|
|
35
34
|
* Validator for TouchChat files (.ce)
|
|
36
35
|
* TouchChat files are XML-based
|
|
@@ -44,9 +43,9 @@ class TouchChatValidator extends baseValidator_1.BaseValidator {
|
|
|
44
43
|
*/
|
|
45
44
|
static async validateFile(filePath) {
|
|
46
45
|
const validator = new TouchChatValidator();
|
|
47
|
-
const content =
|
|
48
|
-
const stats =
|
|
49
|
-
return validator.validate(content,
|
|
46
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
47
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
48
|
+
return validator.validate(content, (0, io_1.getBasename)(filePath), stats.size);
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
52
51
|
* Check if content is TouchChat format
|
|
@@ -58,7 +57,7 @@ class TouchChatValidator extends baseValidator_1.BaseValidator {
|
|
|
58
57
|
}
|
|
59
58
|
// Try to parse as XML and check for TouchChat structure
|
|
60
59
|
try {
|
|
61
|
-
const contentStr =
|
|
60
|
+
const contentStr = typeof content === 'string' ? content : (0, io_1.decodeText)((0, io_1.toUint8Array)(content));
|
|
62
61
|
const parser = new xml2js.Parser();
|
|
63
62
|
const result = await parser.parseStringPromise(contentStr);
|
|
64
63
|
// TouchChat files typically have specific structure
|
|
@@ -82,7 +81,7 @@ class TouchChatValidator extends baseValidator_1.BaseValidator {
|
|
|
82
81
|
await this.add_check('xml_parse', 'valid XML', async () => {
|
|
83
82
|
try {
|
|
84
83
|
const parser = new xml2js.Parser();
|
|
85
|
-
const contentStr =
|
|
84
|
+
const contentStr = (0, io_1.decodeText)(content);
|
|
86
85
|
xmlObj = await parser.parseStringPromise(contentStr);
|
|
87
86
|
}
|
|
88
87
|
catch (e) {
|
|
@@ -191,6 +191,48 @@
|
|
|
191
191
|
font-size: 13px;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
.validation-panel {
|
|
195
|
+
margin-top: 15px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.validation-summary {
|
|
199
|
+
background: #f8f9fa;
|
|
200
|
+
border-radius: 8px;
|
|
201
|
+
padding: 10px 12px;
|
|
202
|
+
font-size: 13px;
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
margin-bottom: 10px;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.validation-summary.success {
|
|
208
|
+
border-left: 4px solid #2ecc71;
|
|
209
|
+
color: #2d7a4f;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.validation-summary.error {
|
|
213
|
+
border-left: 4px solid #e74c3c;
|
|
214
|
+
color: #b03a2e;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.validation-list {
|
|
218
|
+
max-height: 180px;
|
|
219
|
+
overflow-y: auto;
|
|
220
|
+
font-size: 12px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.validation-item {
|
|
224
|
+
padding: 6px 0;
|
|
225
|
+
border-bottom: 1px solid #ececec;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.validation-item.warn {
|
|
229
|
+
color: #c18401;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.validation-item.error {
|
|
233
|
+
color: #b03a2e;
|
|
234
|
+
}
|
|
235
|
+
|
|
194
236
|
.processor-name {
|
|
195
237
|
font-weight: 600;
|
|
196
238
|
color: #333;
|
|
@@ -437,6 +479,7 @@
|
|
|
437
479
|
</div>
|
|
438
480
|
|
|
439
481
|
<button class="btn" id="processBtn" disabled>🚀 Process File</button>
|
|
482
|
+
<button class="btn btn-secondary" id="validateBtn" disabled>✅ Validate File</button>
|
|
440
483
|
<button class="btn btn-secondary" id="runTestsBtn">🧪 Run Compatibility Tests</button>
|
|
441
484
|
<button class="btn btn-secondary" id="clearBtn">🗑️ Clear Results</button>
|
|
442
485
|
|
|
@@ -467,6 +510,12 @@
|
|
|
467
510
|
<div class="panel-title">Test Results</div>
|
|
468
511
|
<div id="testList"></div>
|
|
469
512
|
</div>
|
|
513
|
+
|
|
514
|
+
<div class="validation-panel" id="validationPanel" style="display: none;">
|
|
515
|
+
<div class="panel-title">Validation</div>
|
|
516
|
+
<div class="validation-summary" id="validationSummary"></div>
|
|
517
|
+
<div class="validation-list" id="validationList"></div>
|
|
518
|
+
</div>
|
|
470
519
|
</div>
|
|
471
520
|
|
|
472
521
|
<!-- Right Panel: Results -->
|
|
@@ -81,6 +81,7 @@ import {
|
|
|
81
81
|
AACPage,
|
|
82
82
|
AACButton
|
|
83
83
|
} from 'aac-processors';
|
|
84
|
+
import { validateFileOrBuffer, type ValidationResult } from 'aac-processors/validation';
|
|
84
85
|
|
|
85
86
|
import sqlWasmUrl from 'sql.js/dist/sql-wasm.wasm?url';
|
|
86
87
|
|
|
@@ -92,6 +93,7 @@ configureSqlJs({
|
|
|
92
93
|
const dropArea = document.getElementById('dropArea') as HTMLElement;
|
|
93
94
|
const fileInput = document.getElementById('fileInput') as HTMLInputElement;
|
|
94
95
|
const processBtn = document.getElementById('processBtn') as HTMLButtonElement;
|
|
96
|
+
const validateBtn = document.getElementById('validateBtn') as HTMLButtonElement;
|
|
95
97
|
const runTestsBtn = document.getElementById('runTestsBtn') as HTMLButtonElement;
|
|
96
98
|
const clearBtn = document.getElementById('clearBtn') as HTMLButtonElement;
|
|
97
99
|
const fileInfo = document.getElementById('fileInfo') as HTMLElement;
|
|
@@ -102,6 +104,9 @@ const results = document.getElementById('results') as HTMLElement;
|
|
|
102
104
|
const logPanel = document.getElementById('logPanel') as HTMLElement;
|
|
103
105
|
const testResults = document.getElementById('testResults') as HTMLElement;
|
|
104
106
|
const testList = document.getElementById('testList') as HTMLElement;
|
|
107
|
+
const validationPanel = document.getElementById('validationPanel') as HTMLElement;
|
|
108
|
+
const validationSummary = document.getElementById('validationSummary') as HTMLElement;
|
|
109
|
+
const validationList = document.getElementById('validationList') as HTMLElement;
|
|
105
110
|
const tabButtons = document.querySelectorAll('.tab-btn') as NodeListOf<HTMLButtonElement>;
|
|
106
111
|
const inspectTab = document.getElementById('inspectTab') as HTMLElement;
|
|
107
112
|
const pagesetTab = document.getElementById('pagesetTab') as HTMLElement;
|
|
@@ -218,6 +223,7 @@ function handleFile(file: File) {
|
|
|
218
223
|
fileDetails.textContent = extension;
|
|
219
224
|
fileInfo.style.display = 'block';
|
|
220
225
|
processBtn.disabled = true;
|
|
226
|
+
validateBtn.disabled = true;
|
|
221
227
|
return;
|
|
222
228
|
}
|
|
223
229
|
|
|
@@ -228,12 +234,14 @@ function handleFile(file: File) {
|
|
|
228
234
|
fileDetails.textContent = `${file.name} • ${formatFileSize(file.size)}`;
|
|
229
235
|
fileInfo.style.display = 'block';
|
|
230
236
|
processBtn.disabled = false;
|
|
237
|
+
validateBtn.disabled = false;
|
|
231
238
|
currentSourceLabel = file.name;
|
|
232
239
|
|
|
233
240
|
log(`Using processor: ${currentProcessor.constructor.name}`, 'success');
|
|
234
241
|
} catch (error) {
|
|
235
242
|
log(`Error getting processor: ${(error as Error).message}`, 'error');
|
|
236
243
|
processBtn.disabled = true;
|
|
244
|
+
validateBtn.disabled = true;
|
|
237
245
|
}
|
|
238
246
|
}
|
|
239
247
|
|
|
@@ -314,6 +322,79 @@ processBtn.addEventListener('click', async () => {
|
|
|
314
322
|
}
|
|
315
323
|
});
|
|
316
324
|
|
|
325
|
+
function collectValidationMessages(
|
|
326
|
+
result: ValidationResult,
|
|
327
|
+
prefix = ''
|
|
328
|
+
): Array<{ type: 'error' | 'warn'; message: string }> {
|
|
329
|
+
const messages: Array<{ type: 'error' | 'warn'; message: string }> = [];
|
|
330
|
+
const label = prefix ? `${prefix}: ` : '';
|
|
331
|
+
result.results.forEach((check) => {
|
|
332
|
+
if (!check.valid && check.error) {
|
|
333
|
+
messages.push({ type: 'error', message: `${label}${check.description}: ${check.error}` });
|
|
334
|
+
}
|
|
335
|
+
if (check.warnings?.length) {
|
|
336
|
+
check.warnings.forEach((warning) => {
|
|
337
|
+
messages.push({ type: 'warn', message: `${label}${check.description}: ${warning}` });
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
result.sub_results?.forEach((sub) => {
|
|
342
|
+
const nextPrefix = `${label}${sub.filename || sub.format}`;
|
|
343
|
+
messages.push(...collectValidationMessages(sub, nextPrefix));
|
|
344
|
+
});
|
|
345
|
+
return messages;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function renderValidationResult(result: ValidationResult) {
|
|
349
|
+
validationPanel.style.display = 'block';
|
|
350
|
+
validationSummary.classList.remove('success', 'error');
|
|
351
|
+
validationSummary.classList.add(result.valid ? 'success' : 'error');
|
|
352
|
+
validationSummary.textContent = `${result.valid ? '✅ Valid' : '❌ Invalid'} • ${result.format.toUpperCase()} • ${result.errors} errors, ${result.warnings} warnings`;
|
|
353
|
+
|
|
354
|
+
validationList.innerHTML = '';
|
|
355
|
+
const messages = collectValidationMessages(result).slice(0, 30);
|
|
356
|
+
if (messages.length === 0) {
|
|
357
|
+
const empty = document.createElement('div');
|
|
358
|
+
empty.className = 'validation-item';
|
|
359
|
+
empty.textContent = 'No issues reported.';
|
|
360
|
+
validationList.appendChild(empty);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
messages.forEach((entry) => {
|
|
365
|
+
const item = document.createElement('div');
|
|
366
|
+
item.className = `validation-item ${entry.type}`;
|
|
367
|
+
item.textContent = entry.message;
|
|
368
|
+
validationList.appendChild(item);
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
validateBtn.addEventListener('click', async () => {
|
|
373
|
+
if (!currentFile) return;
|
|
374
|
+
log('Validating file...', 'info');
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
validateBtn.disabled = true;
|
|
378
|
+
const arrayBuffer = await currentFile.arrayBuffer();
|
|
379
|
+
const result = await validateFileOrBuffer(new Uint8Array(arrayBuffer), currentFile.name);
|
|
380
|
+
renderValidationResult(result);
|
|
381
|
+
log(
|
|
382
|
+
`${result.valid ? '✅' : '❌'} Validation complete: ${result.errors} errors, ${result.warnings} warnings`,
|
|
383
|
+
result.valid ? 'success' : 'warn'
|
|
384
|
+
);
|
|
385
|
+
} catch (error) {
|
|
386
|
+
const errorMsg = (error as Error).message;
|
|
387
|
+
validationPanel.style.display = 'block';
|
|
388
|
+
validationSummary.classList.remove('success');
|
|
389
|
+
validationSummary.classList.add('error');
|
|
390
|
+
validationSummary.textContent = `❌ Validation failed: ${errorMsg}`;
|
|
391
|
+
validationList.innerHTML = '';
|
|
392
|
+
log(`❌ Validation failed: ${errorMsg}`, 'error');
|
|
393
|
+
} finally {
|
|
394
|
+
validateBtn.disabled = !currentFile;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
317
398
|
// Display results
|
|
318
399
|
function displayResults(tree: AACTree) {
|
|
319
400
|
results.innerHTML = '';
|
|
@@ -423,6 +504,9 @@ clearBtn.addEventListener('click', () => {
|
|
|
423
504
|
stats.style.display = 'none';
|
|
424
505
|
results.innerHTML = '<p style="color: #999; text-align: center; padding: 40px;">Load a file to see its contents here</p>';
|
|
425
506
|
testResults.style.display = 'none';
|
|
507
|
+
validationPanel.style.display = 'none';
|
|
508
|
+
validationSummary.textContent = '';
|
|
509
|
+
validationList.innerHTML = '';
|
|
426
510
|
logPanel.innerHTML = '<div class="log-entry log-info">Cleared. Ready to process files...</div>';
|
|
427
511
|
pagesetOutput.textContent = 'Generate or convert a pageset to preview the output JSON.';
|
|
428
512
|
updateConvertButtons();
|
|
@@ -3,13 +3,32 @@ import path from 'path';
|
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
resolve: {
|
|
6
|
-
alias:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
alias: [
|
|
7
|
+
{
|
|
8
|
+
find: /^aac-processors\/validation$/,
|
|
9
|
+
replacement: path.resolve(__dirname, '../../src/validation.ts'),
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
find: /^aac-processors$/,
|
|
13
|
+
replacement: path.resolve(__dirname, '../../src/index.browser.ts'),
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
find: /^stream$/,
|
|
17
|
+
replacement: path.resolve(__dirname, 'node_modules/stream-browserify'),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
find: /^events$/,
|
|
21
|
+
replacement: path.resolve(__dirname, 'node_modules/events'),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
find: /^timers$/,
|
|
25
|
+
replacement: path.resolve(__dirname, 'node_modules/timers-browserify'),
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
find: /^util$/,
|
|
29
|
+
replacement: path.resolve(__dirname, 'node_modules/util'),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
13
32
|
},
|
|
14
33
|
optimizeDeps: {
|
|
15
34
|
exclude: ['aac-processors'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willwade/aac-processors",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|