diff --git a/.github/workflows/documentationjs.yml b/.github/workflows/documentationjs.yml
deleted file mode 100644
index e93dc38..0000000
--- a/.github/workflows/documentationjs.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Deploy documentation.js on GitHub pages
-
-on:
- workflow_dispatch:
- release:
- types: [published]
-
-jobs:
- deploy:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Build documentation
- uses: zakodium/documentationjs-action@v1
- - name: Deploy to GitHub pages
- uses: JamesIves/github-pages-deploy-action@releases/v4
- with:
- token: ${{ secrets.BOT_TOKEN }}
- branch: gh-pages
- folder: docs
- clean: true
diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml
new file mode 100644
index 0000000..6de8daf
--- /dev/null
+++ b/.github/workflows/typedoc.yml
@@ -0,0 +1,14 @@
+name: TypeDoc
+
+on:
+ workflow_dispatch:
+ release:
+ types: [published]
+
+jobs:
+ typedoc:
+ uses: zakodium/workflows/.github/workflows/typedoc.yml@typedoc-v1
+ with:
+ entry: 'src/index.ts'
+ secrets:
+ github-token: ${{ secrets.BOT_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 81c3507..9ed4bea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -115,6 +115,7 @@ dist
.yarn/install-state.gz
.pnp.*
+.claude
.DS_Store
lib
diff --git a/package.json b/package.json
index 0189583..e9eb2ec 100644
--- a/package.json
+++ b/package.json
@@ -35,25 +35,25 @@
"url": "https://github.com/cheminfo/arraybuffer-xml-parser/issues"
},
"homepage": "https://github.com/cheminfo/arraybuffer-xml-parser#readme",
+ "dependencies": {
+ "dynamic-typing": "^2.0.0"
+ },
"devDependencies": {
"@types/he": "^1.2.3",
- "@vitest/coverage-v8": "4.0.12",
- "@zakodium/tsconfig": "^1.0.2",
- "cheminfo-build": "^1.3.1",
+ "@types/node": "^25.5.0",
+ "@vitest/coverage-v8": "4.1.2",
+ "@zakodium/tsconfig": "^1.0.3",
+ "cheminfo-build": "^1.3.2",
"eslint": "^9.39.1",
- "eslint-config-cheminfo-typescript": "^21.0.1",
- "globals": "^16.5.0",
+ "eslint-config-cheminfo-typescript": "^21.1.0",
+ "globals": "^17.4.0",
"he": "^1.2.0",
- "ml-spectra-processing": "^14.18.1",
+ "ml-spectra-processing": "^14.22.0",
"pako": "^2.1.0",
- "prettier": "^3.6.2",
- "rimraf": "^6.1.2",
+ "prettier": "^3.8.1",
+ "rimraf": "^6.1.3",
"typescript": "^5.9.3",
"uint8-base64": "^1.0.0",
- "vitest": "^4.0.12"
- },
- "dependencies": {
- "@types/node": "^24.10.1",
- "dynamic-typing": "^1.0.1"
+ "vitest": "^4.1.2"
}
}
diff --git a/src/.npmignore b/src/.npmignore
index e75adf4..27e25b8 100644
--- a/src/.npmignore
+++ b/src/.npmignore
@@ -1,2 +1,3 @@
__tests__
+.DS_Store
.npmignore
\ No newline at end of file
diff --git a/src/XMLNode.ts b/src/XMLNode.ts
index 6fadce3..380ebe7 100644
--- a/src/XMLNode.ts
+++ b/src/XMLNode.ts
@@ -1,4 +1,4 @@
-import type { TagValueProcessor } from './traversable/defaultOptions.js';
+import type { TagValueProcessor } from './traversable/defaultOptions.ts';
export type XMLNodeValue = string | Uint8Array | number | boolean;
export type XMLAttributeValue = string | number | boolean;
@@ -44,9 +44,9 @@ export class XMLNode {
return this.cachedValue;
}
public addChild(child: XMLNode) {
- if (Array.isArray(this.children[child.tagName])) {
- //already presents
- this.children[child.tagName].push(child);
+ const existing = this.children[child.tagName];
+ if (Array.isArray(existing)) {
+ existing.push(child);
} else {
this.children[child.tagName] = [child];
}
diff --git a/src/__tests__/arrayModeSpec.test.ts b/src/__tests__/arrayModeSpec.test.ts
index 01ff628..405d553 100644
--- a/src/__tests__/arrayModeSpec.test.ts
+++ b/src/__tests__/arrayModeSpec.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
diff --git a/src/__tests__/arrayWithExtendedPrototypePropsSpec.test.js b/src/__tests__/arrayWithExtendedPrototypePropsSpec.test.ts
similarity index 84%
rename from src/__tests__/arrayWithExtendedPrototypePropsSpec.test.js
rename to src/__tests__/arrayWithExtendedPrototypePropsSpec.test.ts
index dfe96ba..5208c43 100644
--- a/src/__tests__/arrayWithExtendedPrototypePropsSpec.test.js
+++ b/src/__tests__/arrayWithExtendedPrototypePropsSpec.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
@@ -15,8 +15,7 @@ describe('XMLParser array with extended prototype props', () => {
a: { b: [0, 1] },
};
- // eslint-disable-next-line no-extend-native
- Array.prototype.someExtentionOfArrayPrototype =
+ (Array.prototype as any).someExtentionOfArrayPrototype =
'someExtentionOfArrayPrototype';
const result = parse(xmlData, {
diff --git a/src/__tests__/attributesSpec.test.ts b/src/__tests__/attributesSpec.test.ts
index b706ade..af7364c 100644
--- a/src/__tests__/attributesSpec.test.ts
+++ b/src/__tests__/attributesSpec.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
// import he from 'he';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
diff --git a/src/__tests__/base64.test.js b/src/__tests__/base64.test.ts
similarity index 91%
rename from src/__tests__/base64.test.js
rename to src/__tests__/base64.test.ts
index 5d14e20..676caa1 100644
--- a/src/__tests__/base64.test.js
+++ b/src/__tests__/base64.test.ts
@@ -1,7 +1,7 @@
import { decode as base64decode } from 'uint8-base64';
import { expect, test } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
// library to convert base64 <--> arrayBuffer: https://github.com/niklasvh/base64-arraybuffer/blob/master/src/index.ts
const encoder = new TextEncoder();
@@ -15,7 +15,7 @@ test('base64 parsing', () => {
AAAAAAAA8D8AAAAAAAAAQAAAAAAAAAhA
`);
- let result = parse(xmlData, {
+ const result = parse(xmlData, {
attributeNameProcessor: (name) => name,
tagValueProcessor: (value, node) => {
if (node.tagName !== 'binary') return decoder.decode(value);
@@ -23,7 +23,7 @@ test('base64 parsing', () => {
// isLittleEndian and the data were encoded in littleEndian
return new Float64Array(decoded.buffer);
},
- });
+ }) as Record;
expect(result.binaryDataArray.binary).toStrictEqual(
Float64Array.from([1, 2, 3]),
diff --git a/src/__tests__/cdataSpec.test.ts b/src/__tests__/cdataSpec.test.ts
index 4650ad2..2502f3d 100644
--- a/src/__tests__/cdataSpec.test.ts
+++ b/src/__tests__/cdataSpec.test.ts
@@ -3,7 +3,7 @@ import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
diff --git a/src/__tests__/cheminfo.test.ts b/src/__tests__/cheminfo.test.ts
index cb647a5..4bec61a 100644
--- a/src/__tests__/cheminfo.test.ts
+++ b/src/__tests__/cheminfo.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
describe('XMLParser', () => {
it('Try to parse a very simple example', () => {
diff --git a/src/__tests__/cyrillic.test.ts b/src/__tests__/cyrillic.test.ts
index 87d1848..6a8ab28 100644
--- a/src/__tests__/cyrillic.test.ts
+++ b/src/__tests__/cyrillic.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
describe('XMLParser', () => {
it('should parse XML with cyrillic characters to JSON string', () => {
diff --git a/src/__tests__/data.test.ts b/src/__tests__/data.test.ts
index 59c6225..937be2a 100644
--- a/src/__tests__/data.test.ts
+++ b/src/__tests__/data.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
diff --git a/src/__tests__/parseStream.test.ts b/src/__tests__/parseStream.test.ts
index 4555b8c..c0d2f17 100644
--- a/src/__tests__/parseStream.test.ts
+++ b/src/__tests__/parseStream.test.ts
@@ -3,7 +3,7 @@ import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
-import { parseStream } from '../parseStream.js';
+import { parseStream } from '../parseStream.ts';
describe('parseStream', () => {
it('simple case', async () => {
diff --git a/src/__tests__/stopNodes.test.ts b/src/__tests__/stopNodes.test.ts
index 9b908d3..148b4c3 100644
--- a/src/__tests__/stopNodes.test.ts
+++ b/src/__tests__/stopNodes.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
diff --git a/src/__tests__/tagProcessors.test.ts b/src/__tests__/tagProcessors.test.ts
index 4a8571b..d24b752 100644
--- a/src/__tests__/tagProcessors.test.ts
+++ b/src/__tests__/tagProcessors.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
describe('XMLParser', () => {
it('tag name processor', () => {
diff --git a/src/__tests__/valueProcessors.test.ts b/src/__tests__/valueProcessors.test.ts
index 17c4948..4c86063 100644
--- a/src/__tests__/valueProcessors.test.ts
+++ b/src/__tests__/valueProcessors.test.ts
@@ -3,7 +3,7 @@ import he from 'he'; // HTML entity encoder/decoder
import { describe, expect, it } from 'vitest';
/* eslint-disable camelcase */
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
@@ -89,8 +89,9 @@ describe('XMLParser', () => {
const resultMap: Record = {};
parse(xmlData, {
tagValueProcessor: (value, node) => {
- if (resultMap[node.tagName]) {
- resultMap[node.tagName].push(value);
+ const existing = resultMap[node.tagName];
+ if (existing) {
+ existing.push(value);
} else {
resultMap[node.tagName] = [value];
}
diff --git a/src/__tests__/xmlParser.mz.test.ts b/src/__tests__/xmlParser.mz.test.ts
index 56e3110..045d9bc 100644
--- a/src/__tests__/xmlParser.mz.test.ts
+++ b/src/__tests__/xmlParser.mz.test.ts
@@ -6,7 +6,7 @@ import { recursiveResolve } from 'ml-spectra-processing';
import { decode } from 'uint8-base64';
import { expect, test } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const decoder = new TextDecoder();
@@ -76,7 +76,9 @@ export async function decodeBase64(
switch (compression.toLowerCase()) {
case 'zlib': {
const ds = new DecompressionStream('deflate');
- const decompressedStream = new Blob([uint8Array])
+ const decompressedStream = new Blob([
+ uint8Array as Uint8Array,
+ ])
.stream()
.pipeThrough(ds);
const decompressedArrayBuffer = await new Response(
@@ -116,8 +118,8 @@ export async function decodeBase64(
i += step
) {
for (let j = 0; j < step / 2; j++) {
- const temp = uint8Array[i + j];
- uint8Array[i + j] = uint8Array[i + step - 1 - j];
+ const temp = uint8Array[i + j] as number;
+ uint8Array[i + j] = uint8Array[i + step - 1 - j] as number;
uint8Array[i + step - 1 - j] = temp;
}
}
diff --git a/src/__tests__/xmlParser.test.ts b/src/__tests__/xmlParser.test.ts
index b9645a4..ccec821 100644
--- a/src/__tests__/xmlParser.test.ts
+++ b/src/__tests__/xmlParser.test.ts
@@ -5,7 +5,7 @@ import { parseString } from 'dynamic-typing';
import { recursiveResolve } from 'ml-spectra-processing';
import { describe, expect, it } from 'vitest';
-import { parse } from '../parse.js';
+import { parse } from '../parse.ts';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
diff --git a/src/bufferUtils/__tests__/arrayIndexOf.test.ts b/src/bufferUtils/__tests__/arrayIndexOf.test.ts
index 6775be7..6baebd1 100644
--- a/src/bufferUtils/__tests__/arrayIndexOf.test.ts
+++ b/src/bufferUtils/__tests__/arrayIndexOf.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import { arrayIndexOf } from '../arrayIndexOf.js';
+import { arrayIndexOf } from '../arrayIndexOf.ts';
describe('arrayIndexOf', () => {
it('should find the index pointing to the begining of the found string in array', () => {
diff --git a/src/bufferUtils/__tests__/arrayTrim.test.ts b/src/bufferUtils/__tests__/arrayTrim.test.ts
index fd92a78..9b748d2 100644
--- a/src/bufferUtils/__tests__/arrayTrim.test.ts
+++ b/src/bufferUtils/__tests__/arrayTrim.test.ts
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';
-import { arrayTrim } from '../arrayTrim.js';
+import { arrayTrim } from '../arrayTrim.ts';
test('arrayTrim', () => {
const beginning = new Uint8Array([32, 32, 32, 32, 32, 32, 32, 33, 33, 97]);
diff --git a/src/bufferUtils/arrayTrim.ts b/src/bufferUtils/arrayTrim.ts
index c6daf67..1bce12c 100644
--- a/src/bufferUtils/arrayTrim.ts
+++ b/src/bufferUtils/arrayTrim.ts
@@ -2,8 +2,8 @@
export function arrayTrim(array: Uint8Array, arg?: unknown) {
let i = 0;
let j = array.length - 1;
- for (; i < array.length && array[i] <= 0x20; i++);
- for (; j >= i && array[j] <= 0x20; j--);
+ for (; i < array.length && (array[i] as number) <= 0x20; i++);
+ for (; j >= i && (array[j] as number) <= 0x20; j--);
if (i === 0 && j === array.length - 1) return array;
return array.subarray(i, j + 1);
}
diff --git a/src/index.ts b/src/index.ts
index 3b4c428..8f2a781 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,2 +1,2 @@
-export * from './parse.js';
-export * from './parseStream.js';
+export * from './parse.ts';
+export * from './parseStream.ts';
diff --git a/src/parse.ts b/src/parse.ts
index c3cc6d5..4b32f31 100644
--- a/src/parse.ts
+++ b/src/parse.ts
@@ -1,10 +1,10 @@
import type {
ParseOptions,
RealParseOptions,
-} from './traversable/defaultOptions.js';
-import { defaultOptions } from './traversable/defaultOptions.js';
-import { getTraversable } from './traversable/getTraversable.js';
-import { traversableToJSON } from './traversableToJSON.js';
+} from './traversable/defaultOptions.ts';
+import { defaultOptions } from './traversable/defaultOptions.ts';
+import { getTraversable } from './traversable/getTraversable.ts';
+import { traversableToJSON } from './traversableToJSON.ts';
/**
* Parse an ArrayBuffer or Uint8Array representing an XML and return an object
diff --git a/src/parseStream.ts b/src/parseStream.ts
index 6d1f364..26bfdfd 100644
--- a/src/parseStream.ts
+++ b/src/parseStream.ts
@@ -1,7 +1,7 @@
-import type { StreamParseOptions } from './traversable/defaultOptions.js';
-import { defaultStreamOptions } from './traversable/defaultOptions.js';
-import { getTraversableGenerator } from './traversable/getTraversableGenerator.js';
-import { traversableToJSON } from './traversableToJSON.js';
+import type { StreamParseOptions } from './traversable/defaultOptions.ts';
+import { defaultStreamOptions } from './traversable/defaultOptions.ts';
+import { getTraversableGenerator } from './traversable/getTraversableGenerator.ts';
+import { traversableToJSON } from './traversableToJSON.ts';
/**
* Parse a web stream representing an XML and emit objects
diff --git a/src/traversable/__tests__/closingIndexForOpeningTag.test.ts b/src/traversable/__tests__/closingIndexForOpeningTag.test.ts
index 6e42769..a63df35 100644
--- a/src/traversable/__tests__/closingIndexForOpeningTag.test.ts
+++ b/src/traversable/__tests__/closingIndexForOpeningTag.test.ts
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';
-import { closingIndexForOpeningTag } from '../closingIndexForOpeningTag.js';
+import { closingIndexForOpeningTag } from '../closingIndexForOpeningTag.ts';
test('sclosingIndexForOpeningTag', () => {
expect(
diff --git a/src/traversable/closingIndexForOpeningTag.ts b/src/traversable/closingIndexForOpeningTag.ts
index d346ce7..eeb2e7d 100644
--- a/src/traversable/closingIndexForOpeningTag.ts
+++ b/src/traversable/closingIndexForOpeningTag.ts
@@ -1,4 +1,4 @@
-import { decoder } from './utils/utf8Decoder.js';
+import { decoder } from './utils/utf8Decoder.ts';
/**
* Search for the corresponding closing tag '>'
diff --git a/src/traversable/defaultOptions.ts b/src/traversable/defaultOptions.ts
index cd3abfc..f1c802f 100644
--- a/src/traversable/defaultOptions.ts
+++ b/src/traversable/defaultOptions.ts
@@ -1,6 +1,6 @@
import { parseString } from 'dynamic-typing';
-import type { XMLAttributeValue, XMLNode } from '../XMLNode.js';
+import type { XMLAttributeValue, XMLNode } from '../XMLNode.ts';
const utf8Decoder = new TextDecoder();
diff --git a/src/traversable/findClosingIndex.ts b/src/traversable/findClosingIndex.ts
index 23c0220..4f22e00 100644
--- a/src/traversable/findClosingIndex.ts
+++ b/src/traversable/findClosingIndex.ts
@@ -1,4 +1,4 @@
-import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.js';
+import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.ts';
export function findClosingIndex(
xmlData: Uint8Array,
diff --git a/src/traversable/getTraversable.ts b/src/traversable/getTraversable.ts
index 78efc19..558f776 100644
--- a/src/traversable/getTraversable.ts
+++ b/src/traversable/getTraversable.ts
@@ -1,13 +1,13 @@
-import { XMLNode } from '../XMLNode.js';
-import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.js';
-import { arrayTrim } from '../bufferUtils/arrayTrim.js';
+import { XMLNode } from '../XMLNode.ts';
+import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.ts';
+import { arrayTrim } from '../bufferUtils/arrayTrim.ts';
-import { closingIndexForOpeningTag } from './closingIndexForOpeningTag.js';
-import type { RealParseOptions } from './defaultOptions.js';
-import { findClosingIndex } from './findClosingIndex.js';
-import { parseAttributesString } from './parseAttributesString.js';
-import { removeNameSpaceIfNeeded } from './utils/removeNameSpaceIfNeeded.js';
-import { decoder } from './utils/utf8Decoder.js';
+import { closingIndexForOpeningTag } from './closingIndexForOpeningTag.ts';
+import type { RealParseOptions } from './defaultOptions.ts';
+import { findClosingIndex } from './findClosingIndex.ts';
+import { parseAttributesString } from './parseAttributesString.ts';
+import { removeNameSpaceIfNeeded } from './utils/removeNameSpaceIfNeeded.ts';
+import { decoder } from './utils/utf8Decoder.ts';
export function getTraversable(xmlData: Uint8Array, options: RealParseOptions) {
const { tagValueProcessor } = options;
diff --git a/src/traversable/getTraversableGenerator.ts b/src/traversable/getTraversableGenerator.ts
index 53d59f3..99b1f4d 100644
--- a/src/traversable/getTraversableGenerator.ts
+++ b/src/traversable/getTraversableGenerator.ts
@@ -1,13 +1,13 @@
-import { XMLNode } from '../XMLNode.js';
-import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.js';
-import { arrayTrim } from '../bufferUtils/arrayTrim.js';
+import { XMLNode } from '../XMLNode.ts';
+import { arrayIndexOf } from '../bufferUtils/arrayIndexOf.ts';
+import { arrayTrim } from '../bufferUtils/arrayTrim.ts';
-import { closingIndexForOpeningTag } from './closingIndexForOpeningTag.js';
-import type { RealStreamParseOptions } from './defaultOptions.js';
-import { findClosingIndex } from './findClosingIndex.js';
-import { parseAttributesString } from './parseAttributesString.js';
-import { removeNameSpaceIfNeeded } from './utils/removeNameSpaceIfNeeded.js';
-import { decoder } from './utils/utf8Decoder.js';
+import { closingIndexForOpeningTag } from './closingIndexForOpeningTag.ts';
+import type { RealStreamParseOptions } from './defaultOptions.ts';
+import { findClosingIndex } from './findClosingIndex.ts';
+import { parseAttributesString } from './parseAttributesString.ts';
+import { removeNameSpaceIfNeeded } from './utils/removeNameSpaceIfNeeded.ts';
+import { decoder } from './utils/utf8Decoder.ts';
export async function* getTraversableGenerator(
readableStream: ReadableStream,
@@ -27,7 +27,7 @@ export async function* getTraversableGenerator(
let endStream = chunk.done;
let xmlData = new Uint8Array(chunk.value);
- const { maxEntrySize = 1e7, maxBufferSize = 2e8 } = options;
+ const { maxEntrySize, maxBufferSize } = options;
for (let i = 0; i < xmlData.length; i++) {
if (xmlData.length - i < maxEntrySize && !endStream) {
diff --git a/src/traversable/parseAttributesString.ts b/src/traversable/parseAttributesString.ts
index 9f3d938..7e8e806 100644
--- a/src/traversable/parseAttributesString.ts
+++ b/src/traversable/parseAttributesString.ts
@@ -1,6 +1,6 @@
-import { getAllMatches, isEmptySimpleObject } from '../util.js';
+import { getAllMatches, isEmptySimpleObject } from '../util.ts';
-import type { RealParseOptions } from './defaultOptions.js';
+import type { RealParseOptions } from './defaultOptions.ts';
const newLocal = String.raw`([^\s=]+)\s*(=\s*(['"])(.*?)\3)?`;
const attrsRegx = new RegExp(newLocal, 'g');
@@ -20,7 +20,7 @@ export function parseAttributesString(
// argument 1 is the key, argument 4 is the value
const attributes: Record = {};
for (const match of matches) {
- const attributeName = resolveNameSpace(match[1], options);
+ const attributeName = resolveNameSpace(match[1] as string, options);
if (attributeName.length > 0) {
if (match[4] !== undefined) {
if (options.trimValues) {
@@ -48,7 +48,7 @@ function resolveNameSpace(tagName: string, options: RealParseOptions) {
if (tags[0] === 'xmlns') {
return '';
}
- if (tags.length === 2) {
+ if (tags.length === 2 && tags[1] !== undefined) {
tagName = prefix + tags[1];
}
}
diff --git a/src/traversable/utils/removeNameSpaceIfNeeded.ts b/src/traversable/utils/removeNameSpaceIfNeeded.ts
index 3b0ef65..fc6351e 100644
--- a/src/traversable/utils/removeNameSpaceIfNeeded.ts
+++ b/src/traversable/utils/removeNameSpaceIfNeeded.ts
@@ -1,4 +1,4 @@
-import type { ParseOptions } from '../defaultOptions.js';
+import type { ParseOptions } from '../defaultOptions.ts';
export function removeNameSpaceIfNeeded(
tagName: string,
diff --git a/src/traversableToJSON.ts b/src/traversableToJSON.ts
index c975506..67f15ff 100644
--- a/src/traversableToJSON.ts
+++ b/src/traversableToJSON.ts
@@ -1,11 +1,11 @@
-import type { XMLAttributeValue, XMLNode, XMLNodeValue } from './XMLNode.js';
-import type { RealParseOptions } from './traversable/defaultOptions.js';
+import type { XMLAttributeValue, XMLNode, XMLNodeValue } from './XMLNode.ts';
+import type { RealParseOptions } from './traversable/defaultOptions.ts';
import {
isEmptyObject,
isEmptySimpleObject,
isTagNameInArrayMode,
merge,
-} from './util.js';
+} from './util.ts';
/**
*
@@ -49,7 +49,10 @@ export function traversableToJSON(
const renamedAttributes: Record = {};
for (const attributeName in node.attributes) {
const newAttributeName = attributeNameProcessor(attributeName);
- renamedAttributes[newAttributeName] = node.attributes[attributeName];
+ const value = node.attributes[attributeName];
+ if (value !== undefined) {
+ renamedAttributes[newAttributeName] = value;
+ }
}
attributes = renamedAttributes;
}
@@ -64,16 +67,19 @@ export function traversableToJSON(
for (const tagName in node.children) {
const nodes = node.children[tagName];
+ if (!nodes) continue;
const newTagName = tagNameProcessor
? tagNameProcessor(tagName, nodes)
: tagName;
- if (nodes?.length > 1) {
+ if (nodes.length > 1) {
result[tagName] = [];
for (const child of nodes) {
result[newTagName].push(traversableToJSON(child, options, tagName));
}
} else {
- const subResult = traversableToJSON(nodes[0], options, tagName);
+ const firstNode = nodes[0];
+ if (!firstNode) continue;
+ const subResult = traversableToJSON(firstNode, options, tagName);
const asArray =
(arrayMode === true && typeof subResult === 'object') ||
isTagNameInArrayMode(
diff --git a/src/util.ts b/src/util.ts
index 6e6afce..7bb55ae 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -1,4 +1,4 @@
-import type { XMLAttributeValue, XMLNode } from './XMLNode.js';
+import type { XMLAttributeValue, XMLNode } from './XMLNode.ts';
const nameStartChar = String.raw`:A-Za-z_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD`;
const nameChar = String.raw`${nameStartChar}\-.\d\u00B7\u0300-\u036F\u203F-\u2040`;
@@ -54,10 +54,12 @@ export function merge(
) {
if (!source) return;
for (const key in source) {
+ const value = source[key];
+ if (value === undefined) continue;
if (arrayMode === 'strict') {
- target[key] = [source[key]];
+ target[key] = [value];
} else {
- target[key] = source[key];
+ target[key] = value;
}
}
}
diff --git a/tsconfig.json b/tsconfig.json
index a68fc7e..f7ba89c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,6 @@
{
"extends": "@zakodium/tsconfig",
"compilerOptions": {
- "noUncheckedIndexedAccess": false,
"outDir": "lib",
"types": ["node"]
},
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..d9727d8
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ snapshotFormat: {
+ maxOutputLength: 1e8,
+ },
+ },
+});