Skip to content

Commit faccca1

Browse files
committed
sync with v5.3.9
1 parent ab00cdc commit faccca1

5 files changed

Lines changed: 891 additions & 384 deletions

File tree

src/fxp.d.ts

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,60 @@
1-
type X2jOptions = {
1+
export type ProcessEntitiesOptions = {
2+
/**
3+
* Whether to enable entity processing
4+
*
5+
* Defaults to `true`
6+
*/
7+
enabled?: boolean;
8+
9+
/**
10+
* Maximum size in characters for a single entity definition
11+
*
12+
* Defaults to `10000`
13+
*/
14+
maxEntitySize?: number;
15+
16+
/**
17+
* Maximum depth for nested entity references (reserved for future use)
18+
*
19+
* Defaults to `10`
20+
*/
21+
maxExpansionDepth?: number;
22+
23+
/**
24+
* Maximum total number of entity expansions allowed
25+
*
26+
* Defaults to `1000`
27+
*/
28+
maxTotalExpansions?: number;
29+
30+
/**
31+
* Maximum total expanded content length in characters
32+
*
33+
* Defaults to `100000`
34+
*/
35+
maxExpandedLength?: number;
36+
37+
/**
38+
* Array of tag names where entity replacement is allowed.
39+
* If null, entities are replaced in all tags.
40+
*
41+
* Defaults to `null`
42+
*/
43+
allowedTags?: string[] | null;
44+
45+
/**
46+
* Custom filter function to determine if entities should be replaced in a tag
47+
*
48+
* @param tagName - The name of the current tag
49+
* @param jPath - The jPath of the current tag
50+
* @returns `true` to allow entity replacement, `false` to skip
51+
*
52+
* Defaults to `null`
53+
*/
54+
tagFilter?: ((tagName: string, jPath: string) => boolean) | null;
55+
};
56+
57+
export type X2jOptions = {
258
/**
359
* Preserve the order of tags in resulting JS object
460
*
@@ -10,7 +66,7 @@ type X2jOptions = {
1066
* Give a prefix to the attribute name in the resulting JS object
1167
*
1268
* Defaults to '@_'
13-
*/
69+
*/
1470
attributeNamePrefix?: string;
1571

1672
/**
@@ -64,7 +120,7 @@ type X2jOptions = {
64120
parseTagValue?: boolean;
65121

66122
/**
67-
* Whether to parse tag value with `strnum` package
123+
* Whether to parse attribute value with `strnum` package
68124
*
69125
* Defaults to `false`
70126
*/
@@ -161,9 +217,15 @@ type X2jOptions = {
161217
/**
162218
* Whether to process default and DOCTYPE entities
163219
*
220+
* When `true` - enables entity processing with default limits
221+
*
222+
* When `false` - disables all entity processing
223+
*
224+
* When `ProcessEntitiesOptions` - enables entity processing with custom configuration
225+
*
164226
* Defaults to `true`
165227
*/
166-
processEntities?: boolean;
228+
processEntities?: boolean | ProcessEntitiesOptions;
167229

168230
/**
169231
* Whether to process HTML entities
@@ -209,24 +271,46 @@ type X2jOptions = {
209271
*
210272
* Defaults to `(tagName, jPath, attrs) => tagName`
211273
*/
212-
updateTag?: (tagName: string, jPath: string, attrs: {[k: string]: string}) => string | boolean;
274+
updateTag?: (tagName: string, jPath: string, attrs: { [k: string]: string }) => string | boolean;
275+
276+
/**
277+
* If true, adds a Symbol to all object nodes, accessible by {@link XMLParser.getMetaDataSymbol} with
278+
* metadata about each the node in the XML file.
279+
*/
280+
captureMetaData?: boolean;
281+
282+
/**
283+
* Maximum number of nested tags
284+
*
285+
* Defaults to `100`
286+
*/
287+
maxNestedTags?: number;
288+
289+
/**
290+
* Whether to strictly validate tag names
291+
*
292+
* Defaults to `true`
293+
*/
294+
strictReservedNames?: boolean;
213295
};
214296

215-
type strnumOptions = {
297+
298+
299+
export type strnumOptions = {
216300
hex: boolean;
217301
leadingZeros: boolean,
218302
skipLike?: RegExp,
219303
eNotation?: boolean
220304
}
221305

222-
type validationOptions = {
306+
export type validationOptions = {
223307
/**
224308
* Whether to allow attributes without value
225309
*
226310
* Defaults to `false`
227311
*/
228312
allowBooleanAttributes?: boolean;
229-
313+
230314
/**
231315
* List of tags without closing tags
232316
*
@@ -235,12 +319,12 @@ type validationOptions = {
235319
unpairedTags?: string[];
236320
};
237321

238-
type XmlBuilderOptions = {
322+
export type XmlBuilderOptions = {
239323
/**
240324
* Give a prefix to the attribute name in the resulting JS object
241325
*
242326
* Defaults to '@_'
243-
*/
327+
*/
244328
attributeNamePrefix?: string;
245329

246330
/**
@@ -387,20 +471,20 @@ type XmlBuilderOptions = {
387471
oneListGroup?: boolean;
388472
};
389473

390-
type ESchema = string | object | Array<string|object>;
474+
type ESchema = string | object | Array<string | object>;
391475

392-
type ValidationError = {
393-
err: {
476+
export type ValidationError = {
477+
err: {
394478
code: string;
395479
msg: string,
396480
line: number,
397-
col: number
481+
col: number
398482
};
399483
};
400484

401485
export class XMLParser {
402486
constructor(options?: X2jOptions);
403-
parse(xmlData: string | Buffer ,validationOptions?: validationOptions | boolean): any;
487+
parse(xmlData: string | Uint8Array, validationOptions?: validationOptions | boolean): any;
404488
/**
405489
* Add Entity which is not by default supported by this library
406490
* @param entityIdentifier {string} Eg: 'ent' for &ent;
@@ -409,10 +493,10 @@ export class XMLParser {
409493
addEntity(entityIdentifier: string, entityValue: string): void;
410494
}
411495

412-
export class XMLValidator{
413-
static validate( xmlData: string, options?: validationOptions): true | ValidationError;
496+
export class XMLValidator {
497+
static validate(xmlData: string, options?: validationOptions): true | ValidationError;
414498
}
415499
export class XMLBuilder {
416500
constructor(options?: XmlBuilderOptions);
417-
build(jObj: any): any;
501+
build(jObj: any): string;
418502
}

src/xmlbuilder/orderedJs2Xml.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,21 @@ function arrToStr(arr, options, jPath, indentation) {
1818
let xmlStr = "";
1919
let isPreviousElementTag = false;
2020

21+
22+
if (!Array.isArray(arr)) {
23+
// Non-array values (e.g. string tag values) should be treated as text content
24+
if (arr !== undefined && arr !== null) {
25+
let text = arr.toString();
26+
text = replaceEntitiesValue(text, options);
27+
return text;
28+
}
29+
return "";
30+
}
31+
2132
for (let i = 0; i < arr.length; i++) {
2233
const tagObj = arr[i];
2334
const tagName = propName(tagObj);
24-
if(tagName === undefined) continue;
35+
if (tagName === undefined) continue;
2536

2637
let newJPath = "";
2738
if (jPath.length === 0) newJPath = tagName
@@ -92,7 +103,7 @@ function propName(obj) {
92103
const keys = Object.keys(obj);
93104
for (let i = 0; i < keys.length; i++) {
94105
const key = keys[i];
95-
if(!obj.hasOwnProperty(key)) continue;
106+
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
96107
if (key !== ":@") return key;
97108
}
98109
}
@@ -101,7 +112,7 @@ function attr_to_str(attrMap, options) {
101112
let attrStr = "";
102113
if (attrMap && !options.ignoreAttributes) {
103114
for (let attr in attrMap) {
104-
if(!attrMap.hasOwnProperty(attr)) continue;
115+
if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
105116
let attrVal = options.attributeValueProcessor(attr, attrMap[attr]);
106117
attrVal = replaceEntitiesValue(attrVal, options);
107118
if (attrVal === true && options.suppressBooleanAttributes) {

0 commit comments

Comments
 (0)