@safeaccess/inline 0.1.1 → 0.1.3
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/.gitattributes +1 -1
- package/CHANGELOG.md +23 -5
- package/LICENSE +1 -1
- package/README.md +79 -21
- package/dist/accessors/abstract-accessor.d.ts +24 -10
- package/dist/accessors/abstract-accessor.js +21 -8
- package/dist/accessors/abstract-integration-accessor.d.ts +22 -0
- package/dist/accessors/abstract-integration-accessor.js +23 -0
- package/dist/accessors/formats/any-accessor.d.ts +10 -8
- package/dist/accessors/formats/any-accessor.js +9 -8
- package/dist/accessors/formats/array-accessor.d.ts +2 -0
- package/dist/accessors/formats/array-accessor.js +2 -0
- package/dist/accessors/formats/env-accessor.d.ts +2 -0
- package/dist/accessors/formats/env-accessor.js +2 -0
- package/dist/accessors/formats/ini-accessor.d.ts +2 -0
- package/dist/accessors/formats/ini-accessor.js +2 -0
- package/dist/accessors/formats/json-accessor.d.ts +2 -0
- package/dist/accessors/formats/json-accessor.js +2 -0
- package/dist/accessors/formats/ndjson-accessor.d.ts +2 -0
- package/dist/accessors/formats/ndjson-accessor.js +2 -0
- package/dist/accessors/formats/object-accessor.d.ts +2 -0
- package/dist/accessors/formats/object-accessor.js +2 -0
- package/dist/accessors/formats/xml-accessor.d.ts +2 -0
- package/dist/accessors/formats/xml-accessor.js +2 -0
- package/dist/accessors/formats/yaml-accessor.d.ts +3 -1
- package/dist/accessors/formats/yaml-accessor.js +4 -2
- package/dist/cache/simple-path-cache.d.ts +51 -0
- package/dist/cache/simple-path-cache.js +72 -0
- package/dist/contracts/accessors-interface.d.ts +2 -0
- package/dist/contracts/factory-accessors-interface.d.ts +2 -0
- package/dist/contracts/filter-evaluator-interface.d.ts +28 -0
- package/dist/contracts/filter-evaluator-interface.js +1 -0
- package/dist/contracts/parse-integration-interface.d.ts +2 -0
- package/dist/contracts/parser-interface.d.ts +92 -0
- package/dist/contracts/parser-interface.js +1 -0
- package/dist/contracts/path-cache-interface.d.ts +7 -6
- package/dist/contracts/readable-accessors-interface.d.ts +11 -6
- package/dist/contracts/security-guard-interface.d.ts +2 -0
- package/dist/contracts/security-parser-interface.d.ts +2 -0
- package/dist/contracts/validatable-parser-interface.d.ts +59 -0
- package/dist/contracts/validatable-parser-interface.js +1 -0
- package/dist/contracts/writable-accessors-interface.d.ts +5 -0
- package/dist/core/accessor-factory.d.ts +124 -0
- package/dist/core/accessor-factory.js +157 -0
- package/dist/core/dot-notation-parser.d.ts +34 -5
- package/dist/core/dot-notation-parser.js +51 -10
- package/dist/core/inline-builder-accessor.d.ts +82 -0
- package/dist/core/inline-builder-accessor.js +107 -0
- package/dist/exceptions/accessor-exception.d.ts +9 -0
- package/dist/exceptions/accessor-exception.js +9 -0
- package/dist/exceptions/invalid-format-exception.d.ts +5 -0
- package/dist/exceptions/invalid-format-exception.js +5 -0
- package/dist/exceptions/parser-exception.d.ts +4 -0
- package/dist/exceptions/parser-exception.js +4 -0
- package/dist/exceptions/path-not-found-exception.d.ts +4 -0
- package/dist/exceptions/path-not-found-exception.js +4 -0
- package/dist/exceptions/readonly-violation-exception.d.ts +4 -0
- package/dist/exceptions/readonly-violation-exception.js +4 -0
- package/dist/exceptions/security-exception.d.ts +6 -0
- package/dist/exceptions/security-exception.js +6 -0
- package/dist/exceptions/unsupported-type-exception.d.ts +4 -0
- package/dist/exceptions/unsupported-type-exception.js +4 -0
- package/dist/exceptions/yaml-parse-exception.d.ts +4 -0
- package/dist/exceptions/yaml-parse-exception.js +4 -0
- package/dist/index.js +2 -1
- package/dist/inline.d.ts +26 -56
- package/dist/inline.js +43 -111
- package/dist/parser/xml-parser.js +23 -10
- package/dist/parser/yaml-parser.d.ts +54 -7
- package/dist/parser/yaml-parser.js +268 -51
- package/dist/path-query/segment-filter-parser.d.ts +142 -0
- package/dist/path-query/segment-filter-parser.js +384 -0
- package/dist/path-query/segment-parser.d.ts +98 -0
- package/dist/path-query/segment-parser.js +283 -0
- package/dist/path-query/segment-path-resolver.d.ts +149 -0
- package/dist/path-query/segment-path-resolver.js +351 -0
- package/dist/path-query/segment-type.d.ts +85 -0
- package/dist/path-query/segment-type.js +35 -0
- package/dist/security/forbidden-keys.d.ts +2 -2
- package/dist/security/forbidden-keys.js +5 -5
- package/dist/security/security-guard.d.ts +4 -1
- package/dist/security/security-guard.js +7 -2
- package/dist/security/security-parser.d.ts +10 -1
- package/dist/security/security-parser.js +10 -1
- package/dist/type-format.d.ts +2 -0
- package/dist/type-format.js +2 -0
- package/package.json +11 -3
- package/src/accessors/abstract-accessor.ts +25 -19
- package/src/accessors/abstract-integration-accessor.ts +27 -0
- package/src/accessors/formats/any-accessor.ts +11 -11
- package/src/accessors/formats/array-accessor.ts +2 -0
- package/src/accessors/formats/env-accessor.ts +2 -0
- package/src/accessors/formats/ini-accessor.ts +2 -0
- package/src/accessors/formats/json-accessor.ts +2 -0
- package/src/accessors/formats/ndjson-accessor.ts +2 -0
- package/src/accessors/formats/object-accessor.ts +2 -0
- package/src/accessors/formats/xml-accessor.ts +2 -0
- package/src/accessors/formats/yaml-accessor.ts +4 -2
- package/src/cache/simple-path-cache.ts +77 -0
- package/src/contracts/accessors-interface.ts +2 -0
- package/src/contracts/factory-accessors-interface.ts +2 -0
- package/src/contracts/filter-evaluator-interface.ts +30 -0
- package/src/contracts/parse-integration-interface.ts +2 -0
- package/src/contracts/parser-interface.ts +114 -0
- package/src/contracts/path-cache-interface.ts +8 -6
- package/src/contracts/readable-accessors-interface.ts +11 -6
- package/src/contracts/security-guard-interface.ts +2 -0
- package/src/contracts/security-parser-interface.ts +2 -0
- package/src/contracts/validatable-parser-interface.ts +64 -0
- package/src/contracts/writable-accessors-interface.ts +5 -0
- package/src/core/accessor-factory.ts +173 -0
- package/src/core/dot-notation-parser.ts +74 -11
- package/src/core/inline-builder-accessor.ts +163 -0
- package/src/exceptions/accessor-exception.ts +9 -0
- package/src/exceptions/invalid-format-exception.ts +5 -0
- package/src/exceptions/parser-exception.ts +4 -0
- package/src/exceptions/path-not-found-exception.ts +4 -0
- package/src/exceptions/readonly-violation-exception.ts +4 -0
- package/src/exceptions/security-exception.ts +6 -0
- package/src/exceptions/unsupported-type-exception.ts +4 -0
- package/src/exceptions/yaml-parse-exception.ts +4 -0
- package/src/index.ts +3 -1
- package/src/inline.ts +46 -120
- package/src/parser/xml-parser.ts +31 -10
- package/src/parser/yaml-parser.ts +310 -45
- package/src/path-query/segment-filter-parser.ts +444 -0
- package/src/path-query/segment-parser.ts +321 -0
- package/src/path-query/segment-path-resolver.ts +521 -0
- package/src/path-query/segment-type.ts +82 -0
- package/src/security/forbidden-keys.ts +5 -5
- package/src/security/security-guard.ts +10 -2
- package/src/security/security-parser.ts +18 -3
- package/src/type-format.ts +2 -0
- package/stryker.config.json +8 -10
- package/tests/accessors/abstract-accessor.test.ts +217 -0
- package/tests/accessors/abstract-integration-accessor.test.ts +37 -0
- package/tests/accessors/formats/any-accessor.test.ts +57 -0
- package/tests/accessors/formats/array-accessor.test.ts +42 -0
- package/tests/accessors/formats/env-accessor.test.ts +103 -0
- package/tests/accessors/formats/ini-accessor.test.ts +186 -0
- package/tests/accessors/{json-accessor.test.ts → formats/json-accessor.test.ts} +6 -6
- package/tests/accessors/formats/ndjson-accessor.test.ts +49 -0
- package/tests/accessors/formats/object-accessor.test.ts +172 -0
- package/tests/accessors/formats/xml-accessor.test.ts +162 -0
- package/tests/accessors/formats/yaml-accessor.test.ts +36 -0
- package/tests/cache/simple-path-cache.test.ts +168 -0
- package/tests/core/accessor-factory.test.ts +157 -0
- package/tests/core/dot-notation-parser-edge-cases.test.ts +415 -0
- package/tests/core/dot-notation-parser.test.ts +0 -288
- package/tests/core/inline-builder-accessor.test.ts +114 -0
- package/tests/exceptions/accessor-exception.test.ts +28 -0
- package/tests/exceptions/invalid-format-exception.test.ts +31 -0
- package/tests/exceptions/path-not-found-exception.test.ts +33 -0
- package/tests/exceptions/readonly-violation-exception.test.ts +35 -0
- package/tests/exceptions/security-exception.test.ts +33 -0
- package/tests/exceptions/unsupported-type-exception.test.ts +33 -0
- package/tests/exceptions/yaml-parse-exception.test.ts +38 -0
- package/tests/mocks/fake-path-cache.ts +4 -3
- package/tests/parity-from.test.ts +118 -0
- package/tests/parity.test.ts +227 -10
- package/tests/parser/xml-parser-mutations.test.ts +579 -0
- package/tests/parser/xml-parser-scanner.test.ts +379 -0
- package/tests/parser/xml-parser.test.ts +17 -330
- package/tests/parser/yaml-parser-mutations.test.ts +750 -0
- package/tests/parser/yaml-parser.test.ts +844 -18
- package/tests/path-query/segment-filter-parser-mutations.test.ts +735 -0
- package/tests/path-query/segment-filter-parser.test.ts +1091 -0
- package/tests/path-query/segment-parser-mutations.test.ts +539 -0
- package/tests/path-query/segment-parser.test.ts +606 -0
- package/tests/path-query/segment-path-resolver-mutations.test.ts +626 -0
- package/tests/path-query/segment-path-resolver.test.ts +1009 -0
- package/tests/security/security-guard-advanced.test.ts +413 -0
- package/tests/security/security-guard-forbidden-keys.test.ts +87 -0
- package/tests/security/security-guard.test.ts +8 -479
- package/tests/security/security-parser.test.ts +18 -14
- package/vitest.config.ts +3 -3
- package/benchmarks/get.bench.ts +0 -26
- package/benchmarks/parse.bench.ts +0 -41
- package/tests/accessors/accessors.test.ts +0 -1017
|
@@ -2,6 +2,10 @@ import { AccessorException } from './accessor-exception.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Thrown when a write operation is attempted on a readonly accessor.
|
|
4
4
|
*
|
|
5
|
+
* @api
|
|
6
|
+
*
|
|
7
|
+
* @see AccessorException Parent exception class.
|
|
8
|
+
*
|
|
5
9
|
* @example
|
|
6
10
|
* const accessor = Inline.fromJson('{}').readonly(true);
|
|
7
11
|
* accessor.set('key', 'value'); // throws ReadonlyViolationException
|
|
@@ -6,6 +6,12 @@ import { AccessorException } from './accessor-exception.js';
|
|
|
6
6
|
* methods, stream wrapper / protocol URI schemes, Node.js globals),
|
|
7
7
|
* payload size violations, key-count limits, and depth limit violations.
|
|
8
8
|
*
|
|
9
|
+
* @api
|
|
10
|
+
*
|
|
11
|
+
* @see AccessorException Parent exception class.
|
|
12
|
+
* @see SecurityGuard Validates keys against the forbidden list.
|
|
13
|
+
* @see SecurityParser Enforces payload, depth, and key-count limits.
|
|
14
|
+
*
|
|
9
15
|
* @example
|
|
10
16
|
* throw new SecurityException("Forbidden key '__proto__' detected.");
|
|
11
17
|
*/
|
|
@@ -6,6 +6,12 @@ import { AccessorException } from './accessor-exception.js';
|
|
|
6
6
|
* methods, stream wrapper / protocol URI schemes, Node.js globals),
|
|
7
7
|
* payload size violations, key-count limits, and depth limit violations.
|
|
8
8
|
*
|
|
9
|
+
* @api
|
|
10
|
+
*
|
|
11
|
+
* @see AccessorException Parent exception class.
|
|
12
|
+
* @see SecurityGuard Validates keys against the forbidden list.
|
|
13
|
+
* @see SecurityParser Enforces payload, depth, and key-count limits.
|
|
14
|
+
*
|
|
9
15
|
* @example
|
|
10
16
|
* throw new SecurityException("Forbidden key '__proto__' detected.");
|
|
11
17
|
*/
|
|
@@ -2,6 +2,10 @@ import { AccessorException } from './accessor-exception.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Thrown when the requested format or TypeFormat value is not supported.
|
|
4
4
|
*
|
|
5
|
+
* @api
|
|
6
|
+
*
|
|
7
|
+
* @see AccessorException Parent exception class.
|
|
8
|
+
*
|
|
5
9
|
* @example
|
|
6
10
|
* throw new UnsupportedTypeException('TypeFormat.Csv is not supported.');
|
|
7
11
|
*/
|
|
@@ -2,6 +2,10 @@ import { AccessorException } from './accessor-exception.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Thrown when the requested format or TypeFormat value is not supported.
|
|
4
4
|
*
|
|
5
|
+
* @api
|
|
6
|
+
*
|
|
7
|
+
* @see AccessorException Parent exception class.
|
|
8
|
+
*
|
|
5
9
|
* @example
|
|
6
10
|
* throw new UnsupportedTypeException('TypeFormat.Csv is not supported.');
|
|
7
11
|
*/
|
|
@@ -5,6 +5,10 @@ import { InvalidFormatException } from './invalid-format-exception.js';
|
|
|
5
5
|
* Unsafe constructs include: tags (!! and !), anchors (&), aliases (*),
|
|
6
6
|
* and merge keys (<<).
|
|
7
7
|
*
|
|
8
|
+
* @api
|
|
9
|
+
*
|
|
10
|
+
* @see InvalidFormatException Parent exception class.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
13
|
* throw new YamlParseException('YAML anchors are not supported (line 3).');
|
|
10
14
|
*/
|
|
@@ -5,6 +5,10 @@ import { InvalidFormatException } from './invalid-format-exception.js';
|
|
|
5
5
|
* Unsafe constructs include: tags (!! and !), anchors (&), aliases (*),
|
|
6
6
|
* and merge keys (<<).
|
|
7
7
|
*
|
|
8
|
+
* @api
|
|
9
|
+
*
|
|
10
|
+
* @see InvalidFormatException Parent exception class.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
13
|
* throw new YamlParseException('YAML anchors are not supported (line 3).');
|
|
10
14
|
*/
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,8 @@ export { EnvAccessor } from './accessors/formats/env-accessor.js';
|
|
|
15
15
|
export { NdjsonAccessor } from './accessors/formats/ndjson-accessor.js';
|
|
16
16
|
export { AnyAccessor } from './accessors/formats/any-accessor.js';
|
|
17
17
|
// Core
|
|
18
|
-
// NOTE: DotNotationParser is intentionally not exported
|
|
18
|
+
// NOTE: DotNotationParser is intentionally not exported - it is an internal component.
|
|
19
|
+
// Cache - SimplePathCache is @internal; consumers must use PathCacheInterface
|
|
19
20
|
// Security
|
|
20
21
|
export { SecurityGuard } from './security/security-guard.js';
|
|
21
22
|
export { SecurityParser } from './security/security-parser.js';
|
package/dist/inline.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { TypeFormat } from './type-format.js';
|
|
2
|
-
import { DotNotationParser } from './core/dot-notation-parser.js';
|
|
3
2
|
import type { SecurityGuardInterface } from './contracts/security-guard-interface.js';
|
|
4
3
|
import type { SecurityParserInterface } from './contracts/security-parser-interface.js';
|
|
5
4
|
import type { AccessorsInterface } from './contracts/accessors-interface.js';
|
|
6
5
|
import type { ParseIntegrationInterface } from './contracts/parse-integration-interface.js';
|
|
7
6
|
import type { PathCacheInterface } from './contracts/path-cache-interface.js';
|
|
7
|
+
import type { ValidatableParserInterface } from './contracts/validatable-parser-interface.js';
|
|
8
8
|
import { ArrayAccessor } from './accessors/formats/array-accessor.js';
|
|
9
9
|
import { ObjectAccessor } from './accessors/formats/object-accessor.js';
|
|
10
10
|
import { JsonAccessor } from './accessors/formats/json-accessor.js';
|
|
@@ -14,6 +14,7 @@ import { IniAccessor } from './accessors/formats/ini-accessor.js';
|
|
|
14
14
|
import { EnvAccessor } from './accessors/formats/env-accessor.js';
|
|
15
15
|
import { NdjsonAccessor } from './accessors/formats/ndjson-accessor.js';
|
|
16
16
|
import { AnyAccessor } from './accessors/formats/any-accessor.js';
|
|
17
|
+
import { InlineBuilderAccessor } from './core/inline-builder-accessor.js';
|
|
17
18
|
/**
|
|
18
19
|
* Facade for creating typed data accessors fluently.
|
|
19
20
|
*
|
|
@@ -21,6 +22,8 @@ import { AnyAccessor } from './accessors/formats/any-accessor.js';
|
|
|
21
22
|
* Use the builder methods (`withSecurityGuard`, `withSecurityParser`) to
|
|
22
23
|
* customize the security configuration before creating an accessor.
|
|
23
24
|
*
|
|
25
|
+
* @api
|
|
26
|
+
*
|
|
24
27
|
* @example
|
|
25
28
|
* const accessor = Inline.fromJson('{"name":"Alice"}');
|
|
26
29
|
* accessor.get('name'); // 'Alice'
|
|
@@ -29,60 +32,8 @@ import { AnyAccessor } from './accessors/formats/any-accessor.js';
|
|
|
29
32
|
* const accessor = Inline.from(TypeFormat.Yaml, 'name: Alice');
|
|
30
33
|
* accessor.get('name'); // 'Alice'
|
|
31
34
|
*/
|
|
32
|
-
export declare class Inline {
|
|
33
|
-
private readonly guard;
|
|
34
|
-
private readonly secParser;
|
|
35
|
-
private readonly pathCache;
|
|
36
|
-
private readonly integration;
|
|
37
|
-
private readonly strictMode;
|
|
38
|
-
private constructor();
|
|
35
|
+
export declare class Inline extends InlineBuilderAccessor {
|
|
39
36
|
private static defaultInstance;
|
|
40
|
-
private makeParser;
|
|
41
|
-
/**
|
|
42
|
-
* Apply configured strict mode to a new accessor before hydration.
|
|
43
|
-
*
|
|
44
|
-
* @param accessor - Unhydrated accessor instance.
|
|
45
|
-
* @returns Same accessor with strict mode applied if configured.
|
|
46
|
-
*/
|
|
47
|
-
private prepare;
|
|
48
|
-
/**
|
|
49
|
-
* Return a new Inline instance with a custom SecurityGuard, preserving other settings.
|
|
50
|
-
*
|
|
51
|
-
* @param guard - Custom security guard implementation.
|
|
52
|
-
* @returns New Inline builder instance.
|
|
53
|
-
*/
|
|
54
|
-
withSecurityGuard(guard: SecurityGuardInterface): Inline;
|
|
55
|
-
/**
|
|
56
|
-
* Return a new Inline instance with a custom SecurityParser, preserving other settings.
|
|
57
|
-
*
|
|
58
|
-
* @param parser - Custom security parser implementation.
|
|
59
|
-
* @returns New Inline builder instance.
|
|
60
|
-
*/
|
|
61
|
-
withSecurityParser(parser: SecurityParserInterface): Inline;
|
|
62
|
-
/**
|
|
63
|
-
* Return a new Inline instance with a custom path cache, preserving other settings.
|
|
64
|
-
*
|
|
65
|
-
* @param cache - Custom path cache implementation.
|
|
66
|
-
* @returns New Inline builder instance.
|
|
67
|
-
*/
|
|
68
|
-
withPathCache(cache: PathCacheInterface): Inline;
|
|
69
|
-
/**
|
|
70
|
-
* Return a new Inline instance with a custom parser integration, preserving other settings.
|
|
71
|
-
*
|
|
72
|
-
* @param integration - Custom format integration implementation.
|
|
73
|
-
* @returns New Inline builder instance.
|
|
74
|
-
*/
|
|
75
|
-
withParserIntegration(integration: ParseIntegrationInterface): Inline;
|
|
76
|
-
/**
|
|
77
|
-
* Return a new Inline instance with the given strict mode, preserving other settings.
|
|
78
|
-
*
|
|
79
|
-
* @param strict - Whether to enable strict security validation.
|
|
80
|
-
* @returns New Inline builder instance.
|
|
81
|
-
*
|
|
82
|
-
* @security Passing `false` disables all SecurityGuard and SecurityParser
|
|
83
|
-
* validation. Only use with fully trusted, application-controlled input.
|
|
84
|
-
*/
|
|
85
|
-
withStrictMode(strict: boolean): Inline;
|
|
86
37
|
/**
|
|
87
38
|
* Return a new Inline instance with a custom SecurityGuard.
|
|
88
39
|
*
|
|
@@ -174,6 +125,9 @@ export declare class Inline {
|
|
|
174
125
|
/**
|
|
175
126
|
* Create an XmlAccessor from an XML string.
|
|
176
127
|
*
|
|
128
|
+
* Note: The PHP equivalent also accepts `\SimpleXMLElement`; JS only
|
|
129
|
+
* accepts raw XML strings (no pre-parsed equivalent exists in JS).
|
|
130
|
+
*
|
|
177
131
|
* @param data - Raw XML string.
|
|
178
132
|
* @returns Populated XmlAccessor instance.
|
|
179
133
|
* @throws {InvalidFormatException} When the XML is malformed.
|
|
@@ -249,14 +203,19 @@ export declare class Inline {
|
|
|
249
203
|
/**
|
|
250
204
|
* Create a typed accessor by its constructor.
|
|
251
205
|
*
|
|
206
|
+
* Note: The PHP equivalent accepts a class-string (FQCN) instead of a
|
|
207
|
+
* constructor reference, e.g. `Inline::make(JsonAccessor::class, $data)`.
|
|
208
|
+
*
|
|
252
209
|
* @param AccessorConstructor - The accessor class to instantiate.
|
|
253
210
|
* @param data - Raw data to hydrate the accessor with.
|
|
254
211
|
* @returns Populated accessor instance.
|
|
212
|
+
* @throws {InvalidFormatException} When the data does not match the accessor's expected format.
|
|
213
|
+
* @throws {SecurityException} When security constraints are violated.
|
|
255
214
|
*
|
|
256
215
|
* @example
|
|
257
216
|
* Inline.make(JsonAccessor, '{"key":"value"}').get('key'); // 'value'
|
|
258
217
|
*/
|
|
259
|
-
make<T extends AccessorsInterface>(AccessorConstructor: new (parser:
|
|
218
|
+
make<T extends AccessorsInterface>(AccessorConstructor: new (parser: ValidatableParserInterface) => T, data: unknown): T;
|
|
260
219
|
/**
|
|
261
220
|
* Create an accessor for the given TypeFormat and raw data.
|
|
262
221
|
*
|
|
@@ -266,6 +225,9 @@ export declare class Inline {
|
|
|
266
225
|
* @throws {InvalidFormatException} When the data is malformed for the target format.
|
|
267
226
|
* @throws {SecurityException} When security constraints are violated.
|
|
268
227
|
* @throws {UnsupportedTypeException} When the TypeFormat is not supported.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* Inline.from(TypeFormat.Json, '{"key":"value"}').get('key'); // 'value'
|
|
269
231
|
*/
|
|
270
232
|
from(typeFormat: TypeFormat, data: unknown): AccessorsInterface;
|
|
271
233
|
/**
|
|
@@ -305,6 +267,9 @@ export declare class Inline {
|
|
|
305
267
|
/**
|
|
306
268
|
* Create an XmlAccessor from an XML string.
|
|
307
269
|
*
|
|
270
|
+
* Note: The PHP equivalent also accepts `\SimpleXMLElement`; JS only
|
|
271
|
+
* accepts raw XML strings (no pre-parsed equivalent exists in JS).
|
|
272
|
+
*
|
|
308
273
|
* @param data - Raw XML string.
|
|
309
274
|
* @returns Populated XmlAccessor instance.
|
|
310
275
|
* @throws {InvalidFormatException} When the XML is malformed.
|
|
@@ -391,12 +356,17 @@ export declare class Inline {
|
|
|
391
356
|
/**
|
|
392
357
|
* Create a typed accessor by its constructor.
|
|
393
358
|
*
|
|
359
|
+
* Note: The PHP equivalent accepts a class-string (FQCN) instead of a
|
|
360
|
+
* constructor reference, e.g. `Inline::make(JsonAccessor::class, $data)`.
|
|
361
|
+
*
|
|
394
362
|
* @param AccessorConstructor - The accessor class to instantiate.
|
|
395
363
|
* @param data - Raw data to hydrate the accessor with.
|
|
396
364
|
* @returns Populated accessor instance.
|
|
365
|
+
* @throws {InvalidFormatException} When the data does not match the accessor's expected format.
|
|
366
|
+
* @throws {SecurityException} When security constraints are violated.
|
|
397
367
|
*
|
|
398
368
|
* @example
|
|
399
369
|
* Inline.make(JsonAccessor, '{"key":"value"}').get('key'); // 'value'
|
|
400
370
|
*/
|
|
401
|
-
static make<T extends AccessorsInterface>(AccessorConstructor: new (parser:
|
|
371
|
+
static make<T extends AccessorsInterface>(AccessorConstructor: new (parser: ValidatableParserInterface) => T, data: unknown): T;
|
|
402
372
|
}
|
package/dist/inline.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import { TypeFormat } from './type-format.js';
|
|
2
|
-
import { DotNotationParser } from './core/dot-notation-parser.js';
|
|
3
|
-
import { SecurityGuard } from './security/security-guard.js';
|
|
4
|
-
import { SecurityParser } from './security/security-parser.js';
|
|
5
2
|
import { AbstractAccessor } from './accessors/abstract-accessor.js';
|
|
6
|
-
import { ArrayAccessor } from './accessors/formats/array-accessor.js';
|
|
7
|
-
import { ObjectAccessor } from './accessors/formats/object-accessor.js';
|
|
8
|
-
import { JsonAccessor } from './accessors/formats/json-accessor.js';
|
|
9
|
-
import { XmlAccessor } from './accessors/formats/xml-accessor.js';
|
|
10
|
-
import { YamlAccessor } from './accessors/formats/yaml-accessor.js';
|
|
11
|
-
import { IniAccessor } from './accessors/formats/ini-accessor.js';
|
|
12
|
-
import { EnvAccessor } from './accessors/formats/env-accessor.js';
|
|
13
|
-
import { NdjsonAccessor } from './accessors/formats/ndjson-accessor.js';
|
|
14
|
-
import { AnyAccessor } from './accessors/formats/any-accessor.js';
|
|
15
3
|
import { UnsupportedTypeException } from './exceptions/unsupported-type-exception.js';
|
|
16
|
-
import {
|
|
4
|
+
import { InlineBuilderAccessor } from './core/inline-builder-accessor.js';
|
|
17
5
|
/**
|
|
18
6
|
* Facade for creating typed data accessors fluently.
|
|
19
7
|
*
|
|
@@ -21,6 +9,8 @@ import { InvalidFormatException } from './exceptions/invalid-format-exception.js
|
|
|
21
9
|
* Use the builder methods (`withSecurityGuard`, `withSecurityParser`) to
|
|
22
10
|
* customize the security configuration before creating an accessor.
|
|
23
11
|
*
|
|
12
|
+
* @api
|
|
13
|
+
*
|
|
24
14
|
* @example
|
|
25
15
|
* const accessor = Inline.fromJson('{"name":"Alice"}');
|
|
26
16
|
* accessor.get('name'); // 'Alice'
|
|
@@ -29,85 +19,11 @@ import { InvalidFormatException } from './exceptions/invalid-format-exception.js
|
|
|
29
19
|
* const accessor = Inline.from(TypeFormat.Yaml, 'name: Alice');
|
|
30
20
|
* accessor.get('name'); // 'Alice'
|
|
31
21
|
*/
|
|
32
|
-
export class Inline {
|
|
33
|
-
guard;
|
|
34
|
-
secParser;
|
|
35
|
-
pathCache;
|
|
36
|
-
integration;
|
|
37
|
-
strictMode;
|
|
38
|
-
constructor(guard, secParser, pathCache = null, integration = null, strictMode = null) {
|
|
39
|
-
this.guard = guard;
|
|
40
|
-
this.secParser = secParser;
|
|
41
|
-
this.pathCache = pathCache;
|
|
42
|
-
this.integration = integration;
|
|
43
|
-
this.strictMode = strictMode;
|
|
44
|
-
}
|
|
22
|
+
export class Inline extends InlineBuilderAccessor {
|
|
45
23
|
static defaultInstance() {
|
|
46
|
-
return new Inline(
|
|
47
|
-
}
|
|
48
|
-
makeParser() {
|
|
49
|
-
return new DotNotationParser(this.guard, this.secParser, this.pathCache ?? undefined);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Apply configured strict mode to a new accessor before hydration.
|
|
53
|
-
*
|
|
54
|
-
* @param accessor - Unhydrated accessor instance.
|
|
55
|
-
* @returns Same accessor with strict mode applied if configured.
|
|
56
|
-
*/
|
|
57
|
-
prepare(accessor) {
|
|
58
|
-
if (this.strictMode !== null) {
|
|
59
|
-
return accessor.strict(this.strictMode);
|
|
60
|
-
}
|
|
61
|
-
return accessor;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Return a new Inline instance with a custom SecurityGuard, preserving other settings.
|
|
65
|
-
*
|
|
66
|
-
* @param guard - Custom security guard implementation.
|
|
67
|
-
* @returns New Inline builder instance.
|
|
68
|
-
*/
|
|
69
|
-
withSecurityGuard(guard) {
|
|
70
|
-
return new Inline(guard, this.secParser, this.pathCache, this.integration, this.strictMode);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Return a new Inline instance with a custom SecurityParser, preserving other settings.
|
|
74
|
-
*
|
|
75
|
-
* @param parser - Custom security parser implementation.
|
|
76
|
-
* @returns New Inline builder instance.
|
|
77
|
-
*/
|
|
78
|
-
withSecurityParser(parser) {
|
|
79
|
-
return new Inline(this.guard, parser, this.pathCache, this.integration, this.strictMode);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Return a new Inline instance with a custom path cache, preserving other settings.
|
|
83
|
-
*
|
|
84
|
-
* @param cache - Custom path cache implementation.
|
|
85
|
-
* @returns New Inline builder instance.
|
|
86
|
-
*/
|
|
87
|
-
withPathCache(cache) {
|
|
88
|
-
return new Inline(this.guard, this.secParser, cache, this.integration, this.strictMode);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Return a new Inline instance with a custom parser integration, preserving other settings.
|
|
92
|
-
*
|
|
93
|
-
* @param integration - Custom format integration implementation.
|
|
94
|
-
* @returns New Inline builder instance.
|
|
95
|
-
*/
|
|
96
|
-
withParserIntegration(integration) {
|
|
97
|
-
return new Inline(this.guard, this.secParser, this.pathCache, integration, this.strictMode);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Return a new Inline instance with the given strict mode, preserving other settings.
|
|
101
|
-
*
|
|
102
|
-
* @param strict - Whether to enable strict security validation.
|
|
103
|
-
* @returns New Inline builder instance.
|
|
104
|
-
*
|
|
105
|
-
* @security Passing `false` disables all SecurityGuard and SecurityParser
|
|
106
|
-
* validation. Only use with fully trusted, application-controlled input.
|
|
107
|
-
*/
|
|
108
|
-
withStrictMode(strict) {
|
|
109
|
-
return new Inline(this.guard, this.secParser, this.pathCache, this.integration, strict);
|
|
24
|
+
return new Inline();
|
|
110
25
|
}
|
|
26
|
+
// ── Instance factory methods ──────────────────────────────────────
|
|
111
27
|
/**
|
|
112
28
|
* Return a new Inline instance with a custom SecurityGuard.
|
|
113
29
|
*
|
|
@@ -118,7 +34,7 @@ export class Inline {
|
|
|
118
34
|
* Inline.withSecurityGuard(new SecurityGuard(10, ['extraKey'])).fromJson('{}');
|
|
119
35
|
*/
|
|
120
36
|
static withSecurityGuard(guard) {
|
|
121
|
-
return new Inline(guard
|
|
37
|
+
return new Inline(guard);
|
|
122
38
|
}
|
|
123
39
|
/**
|
|
124
40
|
* Return a new Inline instance with a custom SecurityParser.
|
|
@@ -130,7 +46,7 @@ export class Inline {
|
|
|
130
46
|
* Inline.withSecurityParser(new SecurityParser({ maxDepth: 10 })).fromJson('{}');
|
|
131
47
|
*/
|
|
132
48
|
static withSecurityParser(parser) {
|
|
133
|
-
return new Inline(
|
|
49
|
+
return new Inline(undefined, parser);
|
|
134
50
|
}
|
|
135
51
|
/**
|
|
136
52
|
* Return a new Inline instance with a custom path cache.
|
|
@@ -143,7 +59,7 @@ export class Inline {
|
|
|
143
59
|
* Inline.withPathCache(cache).fromJson('{"key":"value"}');
|
|
144
60
|
*/
|
|
145
61
|
static withPathCache(cache) {
|
|
146
|
-
return new Inline(
|
|
62
|
+
return new Inline(undefined, undefined, cache);
|
|
147
63
|
}
|
|
148
64
|
/**
|
|
149
65
|
* Return a new Inline instance with a custom parser integration for `fromAny()`.
|
|
@@ -155,7 +71,7 @@ export class Inline {
|
|
|
155
71
|
* Inline.withParserIntegration(new MyCsvIntegration()).fromAny(csvString);
|
|
156
72
|
*/
|
|
157
73
|
static withParserIntegration(integration) {
|
|
158
|
-
return new Inline(
|
|
74
|
+
return new Inline(undefined, undefined, null, integration);
|
|
159
75
|
}
|
|
160
76
|
/**
|
|
161
77
|
* Return a new Inline instance with the given strict mode.
|
|
@@ -170,7 +86,7 @@ export class Inline {
|
|
|
170
86
|
* Inline.withStrictMode(false).fromJson(hugePayload).get('key');
|
|
171
87
|
*/
|
|
172
88
|
static withStrictMode(strict) {
|
|
173
|
-
return new Inline(
|
|
89
|
+
return new Inline(undefined, undefined, null, null, strict);
|
|
174
90
|
}
|
|
175
91
|
/**
|
|
176
92
|
* Create an ArrayAccessor from a plain object or array.
|
|
@@ -183,7 +99,7 @@ export class Inline {
|
|
|
183
99
|
* inline.fromArray({ name: 'Alice' }).get('name'); // 'Alice'
|
|
184
100
|
*/
|
|
185
101
|
fromArray(data) {
|
|
186
|
-
return this.
|
|
102
|
+
return this.builder().array(data);
|
|
187
103
|
}
|
|
188
104
|
/**
|
|
189
105
|
* Create an ObjectAccessor from a JavaScript object.
|
|
@@ -196,7 +112,7 @@ export class Inline {
|
|
|
196
112
|
* inline.fromObject({ user: { name: 'Alice' } }).get('user.name');
|
|
197
113
|
*/
|
|
198
114
|
fromObject(data) {
|
|
199
|
-
return this.
|
|
115
|
+
return this.builder().object(data);
|
|
200
116
|
}
|
|
201
117
|
/**
|
|
202
118
|
* Create a JsonAccessor from a JSON string.
|
|
@@ -210,11 +126,14 @@ export class Inline {
|
|
|
210
126
|
* inline.fromJson('{"key":"value"}').get('key'); // 'value'
|
|
211
127
|
*/
|
|
212
128
|
fromJson(data) {
|
|
213
|
-
return this.
|
|
129
|
+
return this.builder().json(data);
|
|
214
130
|
}
|
|
215
131
|
/**
|
|
216
132
|
* Create an XmlAccessor from an XML string.
|
|
217
133
|
*
|
|
134
|
+
* Note: The PHP equivalent also accepts `\SimpleXMLElement`; JS only
|
|
135
|
+
* accepts raw XML strings (no pre-parsed equivalent exists in JS).
|
|
136
|
+
*
|
|
218
137
|
* @param data - Raw XML string.
|
|
219
138
|
* @returns Populated XmlAccessor instance.
|
|
220
139
|
* @throws {InvalidFormatException} When the XML is malformed.
|
|
@@ -224,7 +143,7 @@ export class Inline {
|
|
|
224
143
|
* inline.fromXml('<root><key>value</key></root>').get('key');
|
|
225
144
|
*/
|
|
226
145
|
fromXml(data) {
|
|
227
|
-
return this.
|
|
146
|
+
return this.builder().xml(data);
|
|
228
147
|
}
|
|
229
148
|
/**
|
|
230
149
|
* Create a YamlAccessor from a YAML string.
|
|
@@ -238,7 +157,7 @@ export class Inline {
|
|
|
238
157
|
* inline.fromYaml('name: Alice').get('name'); // 'Alice'
|
|
239
158
|
*/
|
|
240
159
|
fromYaml(data) {
|
|
241
|
-
return this.
|
|
160
|
+
return this.builder().yaml(data);
|
|
242
161
|
}
|
|
243
162
|
/**
|
|
244
163
|
* Create an IniAccessor from an INI string.
|
|
@@ -252,7 +171,7 @@ export class Inline {
|
|
|
252
171
|
* inline.fromIni('[section]\nkey=value').get('section.key'); // 'value'
|
|
253
172
|
*/
|
|
254
173
|
fromIni(data) {
|
|
255
|
-
return this.
|
|
174
|
+
return this.builder().ini(data);
|
|
256
175
|
}
|
|
257
176
|
/**
|
|
258
177
|
* Create an EnvAccessor from a dotenv-formatted string.
|
|
@@ -265,7 +184,7 @@ export class Inline {
|
|
|
265
184
|
* inline.fromEnv('APP_NAME=MyApp').get('APP_NAME'); // 'MyApp'
|
|
266
185
|
*/
|
|
267
186
|
fromEnv(data) {
|
|
268
|
-
return this.
|
|
187
|
+
return this.builder().env(data);
|
|
269
188
|
}
|
|
270
189
|
/**
|
|
271
190
|
* Create an NdjsonAccessor from a newline-delimited JSON string.
|
|
@@ -279,7 +198,7 @@ export class Inline {
|
|
|
279
198
|
* inline.fromNdjson('{"id":1}\n{"id":2}').get('0.id'); // 1
|
|
280
199
|
*/
|
|
281
200
|
fromNdjson(data) {
|
|
282
|
-
return this.
|
|
201
|
+
return this.builder().ndjson(data);
|
|
283
202
|
}
|
|
284
203
|
/**
|
|
285
204
|
* Create an AnyAccessor from raw data using a custom integration.
|
|
@@ -297,26 +216,28 @@ export class Inline {
|
|
|
297
216
|
* Inline.withParserIntegration(new CsvIntegration()).fromAny(csvString);
|
|
298
217
|
*/
|
|
299
218
|
fromAny(data, integration) {
|
|
300
|
-
|
|
301
|
-
if (resolved === null) {
|
|
302
|
-
throw new InvalidFormatException('AnyAccessor requires a ParseIntegrationInterface — use Inline.withParserIntegration(integration).fromAny(data).');
|
|
303
|
-
}
|
|
304
|
-
return this.prepare(new AnyAccessor(this.makeParser(), resolved)).from(data);
|
|
219
|
+
return this.builder().any(data, integration);
|
|
305
220
|
}
|
|
306
221
|
/**
|
|
307
222
|
* Create a typed accessor by its constructor.
|
|
308
223
|
*
|
|
224
|
+
* Note: The PHP equivalent accepts a class-string (FQCN) instead of a
|
|
225
|
+
* constructor reference, e.g. `Inline::make(JsonAccessor::class, $data)`.
|
|
226
|
+
*
|
|
309
227
|
* @param AccessorConstructor - The accessor class to instantiate.
|
|
310
228
|
* @param data - Raw data to hydrate the accessor with.
|
|
311
229
|
* @returns Populated accessor instance.
|
|
230
|
+
* @throws {InvalidFormatException} When the data does not match the accessor's expected format.
|
|
231
|
+
* @throws {SecurityException} When security constraints are violated.
|
|
312
232
|
*
|
|
313
233
|
* @example
|
|
314
234
|
* Inline.make(JsonAccessor, '{"key":"value"}').get('key'); // 'value'
|
|
315
235
|
*/
|
|
316
236
|
make(AccessorConstructor, data) {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
237
|
+
const factory = this.builder();
|
|
238
|
+
const accessor = new AccessorConstructor(factory.getParser());
|
|
239
|
+
if (this._strictMode !== null && accessor instanceof AbstractAccessor) {
|
|
240
|
+
return accessor.strict(this._strictMode).from(data);
|
|
320
241
|
}
|
|
321
242
|
return accessor.from(data);
|
|
322
243
|
}
|
|
@@ -329,6 +250,9 @@ export class Inline {
|
|
|
329
250
|
* @throws {InvalidFormatException} When the data is malformed for the target format.
|
|
330
251
|
* @throws {SecurityException} When security constraints are violated.
|
|
331
252
|
* @throws {UnsupportedTypeException} When the TypeFormat is not supported.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* Inline.from(TypeFormat.Json, '{"key":"value"}').get('key'); // 'value'
|
|
332
256
|
*/
|
|
333
257
|
from(typeFormat, data) {
|
|
334
258
|
switch (typeFormat) {
|
|
@@ -399,6 +323,9 @@ export class Inline {
|
|
|
399
323
|
/**
|
|
400
324
|
* Create an XmlAccessor from an XML string.
|
|
401
325
|
*
|
|
326
|
+
* Note: The PHP equivalent also accepts `\SimpleXMLElement`; JS only
|
|
327
|
+
* accepts raw XML strings (no pre-parsed equivalent exists in JS).
|
|
328
|
+
*
|
|
402
329
|
* @param data - Raw XML string.
|
|
403
330
|
* @returns Populated XmlAccessor instance.
|
|
404
331
|
* @throws {InvalidFormatException} When the XML is malformed.
|
|
@@ -499,9 +426,14 @@ export class Inline {
|
|
|
499
426
|
/**
|
|
500
427
|
* Create a typed accessor by its constructor.
|
|
501
428
|
*
|
|
429
|
+
* Note: The PHP equivalent accepts a class-string (FQCN) instead of a
|
|
430
|
+
* constructor reference, e.g. `Inline::make(JsonAccessor::class, $data)`.
|
|
431
|
+
*
|
|
502
432
|
* @param AccessorConstructor - The accessor class to instantiate.
|
|
503
433
|
* @param data - Raw data to hydrate the accessor with.
|
|
504
434
|
* @returns Populated accessor instance.
|
|
435
|
+
* @throws {InvalidFormatException} When the data does not match the accessor's expected format.
|
|
436
|
+
* @throws {SecurityException} When security constraints are violated.
|
|
505
437
|
*
|
|
506
438
|
* @example
|
|
507
439
|
* Inline.make(JsonAccessor, '{"key":"value"}').get('key'); // 'value'
|
|
@@ -21,9 +21,7 @@ export class XmlParser {
|
|
|
21
21
|
*/
|
|
22
22
|
constructor(maxDepth, maxElements = 10_000) {
|
|
23
23
|
this.maxDepth = maxDepth;
|
|
24
|
-
this.maxElements = Number.isFinite(maxElements) && maxElements >= 1
|
|
25
|
-
? maxElements
|
|
26
|
-
: 10_000;
|
|
24
|
+
this.maxElements = Number.isFinite(maxElements) && maxElements >= 1 ? maxElements : 10_000;
|
|
27
25
|
}
|
|
28
26
|
/**
|
|
29
27
|
* Parse an XML body into a plain object using the best available parser.
|
|
@@ -97,7 +95,7 @@ export class XmlParser {
|
|
|
97
95
|
parseXmlManual(xml) {
|
|
98
96
|
const stripped = xml.replace(/<\?xml[^?]*\?>/i, '').trim();
|
|
99
97
|
// Bound parser complexity before the linear inner-content scan: count opening
|
|
100
|
-
// tags as a document-complexity proxy. This is a defence-in-depth limit
|
|
98
|
+
// tags as a document-complexity proxy. This is a defence-in-depth limit -
|
|
101
99
|
// the linear scanner below is already O(n), but bounding element count also
|
|
102
100
|
// caps the total number of recursive parseXmlChildren calls.
|
|
103
101
|
// Browser environments (DOMParser) are unaffected.
|
|
@@ -142,9 +140,10 @@ export class XmlParser {
|
|
|
142
140
|
throw new InvalidFormatException('XmlAccessor failed to parse XML string.');
|
|
143
141
|
}
|
|
144
142
|
// Walk backward from the final '>' to locate the closing tag for this root element.
|
|
145
|
-
// This is O(tagNameLen)
|
|
143
|
+
// This is O(tagNameLen) - the tag name is typically short and always bounded.
|
|
146
144
|
let pos = doc.length - 2;
|
|
147
|
-
while (pos >= 0 &&
|
|
145
|
+
while (pos >= 0 &&
|
|
146
|
+
(doc[pos] === ' ' || doc[pos] === '\t' || doc[pos] === '\n' || doc[pos] === '\r')) {
|
|
148
147
|
pos--;
|
|
149
148
|
}
|
|
150
149
|
// pos must point to the last char of the root tag name.
|
|
@@ -218,7 +217,12 @@ export class XmlParser {
|
|
|
218
217
|
break;
|
|
219
218
|
if (content.startsWith(closeTag, nextLt)) {
|
|
220
219
|
const c = content[nextLt + closeTag.length];
|
|
221
|
-
if (c === '>' ||
|
|
220
|
+
if (c === '>' ||
|
|
221
|
+
c === ' ' ||
|
|
222
|
+
c === '\t' ||
|
|
223
|
+
c === '\n' ||
|
|
224
|
+
c === '\r' ||
|
|
225
|
+
c === undefined) {
|
|
222
226
|
nestDepth--;
|
|
223
227
|
if (nestDepth === 0) {
|
|
224
228
|
innerEnd = nextLt;
|
|
@@ -232,9 +236,18 @@ export class XmlParser {
|
|
|
232
236
|
}
|
|
233
237
|
if (content.startsWith(openPrefix, nextLt)) {
|
|
234
238
|
const c = content[nextLt + openPrefix.length];
|
|
235
|
-
if (c === '>' ||
|
|
239
|
+
if (c === '>' ||
|
|
240
|
+
c === ' ' ||
|
|
241
|
+
c === '\t' ||
|
|
242
|
+
c === '\n' ||
|
|
243
|
+
c === '\r' ||
|
|
244
|
+
c === '/') {
|
|
236
245
|
const ogt = content.indexOf('>', nextLt + openPrefix.length);
|
|
237
|
-
if (ogt !== -1 &&
|
|
246
|
+
if (ogt !== -1 &&
|
|
247
|
+
!content
|
|
248
|
+
.slice(nextLt + openPrefix.length, ogt)
|
|
249
|
+
.trimEnd()
|
|
250
|
+
.endsWith('/')) {
|
|
238
251
|
nestDepth++;
|
|
239
252
|
}
|
|
240
253
|
}
|
|
@@ -242,7 +255,7 @@ export class XmlParser {
|
|
|
242
255
|
pos = nextLt + 1;
|
|
243
256
|
}
|
|
244
257
|
if (innerEnd === -1) {
|
|
245
|
-
// Unclosed or malformed tag
|
|
258
|
+
// Unclosed or malformed tag - skip past the opening tag
|
|
246
259
|
i = gt + 1;
|
|
247
260
|
continue;
|
|
248
261
|
}
|