@endevops/effect-codec-xml 0.0.1
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/LICENSE +21 -0
- package/LICENSE-is-entities +21 -0
- package/LICENSE-is-xml-naming +21 -0
- package/README.md +415 -0
- package/dist/codec.d.ts +48 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +63 -0
- package/dist/codec.js.map +1 -0
- package/dist/conventions.d.ts +88 -0
- package/dist/conventions.d.ts.map +1 -0
- package/dist/conventions.js +113 -0
- package/dist/conventions.js.map +1 -0
- package/dist/entities/entity-decoder.d.ts +333 -0
- package/dist/entities/entity-decoder.d.ts.map +1 -0
- package/dist/entities/entity-decoder.js +841 -0
- package/dist/entities/entity-decoder.js.map +1 -0
- package/dist/entities/entity-tables.js +16 -0
- package/dist/entities/entity-tables.js.map +1 -0
- package/dist/errors.d.ts +49 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +48 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/namespaces.d.ts +101 -0
- package/dist/namespaces.d.ts.map +1 -0
- package/dist/namespaces.js +663 -0
- package/dist/namespaces.js.map +1 -0
- package/dist/naming.d.ts +149 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +296 -0
- package/dist/naming.js.map +1 -0
- package/dist/parse.d.ts +75 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +437 -0
- package/dist/parse.js.map +1 -0
- package/dist/render.d.ts +99 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +509 -0
- package/dist/render.js.map +1 -0
- package/dist/xml-error.d.ts +172 -0
- package/dist/xml-error.d.ts.map +1 -0
- package/dist/xml-error.js +157 -0
- package/dist/xml-error.js.map +1 -0
- package/dist/xml-value.d.ts +42 -0
- package/dist/xml-value.d.ts.map +1 -0
- package/dist/xml-value.js +79 -0
- package/dist/xml-value.js.map +1 -0
- package/package.json +69 -0
- package/src/codec.ts +136 -0
- package/src/conventions.ts +145 -0
- package/src/entities/entity-decoder.ts +1248 -0
- package/src/entities/entity-tables.ts +18 -0
- package/src/errors.ts +55 -0
- package/src/index.ts +79 -0
- package/src/namespaces.ts +968 -0
- package/src/naming.ts +519 -0
- package/src/parse.ts +597 -0
- package/src/render.ts +708 -0
- package/src/xml-error.ts +168 -0
- package/src/xml-value.ts +108 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { XmlVersion } from "./naming.js";
|
|
2
|
+
import { XmlParseError } from "./errors.js";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
//#region src/conventions.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description The key prefix that marks a field as an XML attribute. `@xmlns` is written as `xmlns="…"`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ATTRIBUTE_PREFIX = "@";
|
|
9
|
+
/**
|
|
10
|
+
* @description The reserved key holding an element's character data, alongside its attributes and child elements.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TEXT_KEY = "#text";
|
|
13
|
+
/**
|
|
14
|
+
* @description The element name used when nothing else names the root. Matches the default Effect uses in `Schema.toEncoderXml`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const DEFAULT_ROOT_NAME = "root";
|
|
17
|
+
/**
|
|
18
|
+
* @description The element name used for array members that have no natural name of their own. Matches the default in `Schema.toEncoderXml`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_ITEM_NAME = "item";
|
|
21
|
+
/**
|
|
22
|
+
* @description What to do with a name that is not a legal XML name.
|
|
23
|
+
*
|
|
24
|
+
* - `repair` rewrites it into the nearest legal name. The default, because a serializer that silently produces a different tag name is worse than one
|
|
25
|
+
* that produces a legal one.
|
|
26
|
+
* - `error` fails the render. Use it when a rewritten name would silently change the meaning of the document.
|
|
27
|
+
* - `ignore` writes the name as given, producing a document that is not well-formed. Only useful when a downstream step rewrites names anyway.
|
|
28
|
+
*/
|
|
29
|
+
export type NameMode = 'error' | 'ignore' | 'repair';
|
|
30
|
+
/**
|
|
31
|
+
* @description Options for {@link resolveName}.
|
|
32
|
+
*/
|
|
33
|
+
export interface ResolveNameOptions {
|
|
34
|
+
/**
|
|
35
|
+
* @description What to do with an illegal name. Defaults to `'repair'`.
|
|
36
|
+
*/
|
|
37
|
+
readonly mode?: NameMode | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* @description XML version to validate against. Defaults to `'1.0'`.
|
|
40
|
+
*/
|
|
41
|
+
readonly xmlVersion?: XmlVersion | undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @description Whether a record key names an attribute rather than a child element.
|
|
45
|
+
*
|
|
46
|
+
* @param key - The key to classify.
|
|
47
|
+
*
|
|
48
|
+
* @returns Whether the key carries the {@link ATTRIBUTE_PREFIX}.
|
|
49
|
+
*/
|
|
50
|
+
export declare const isAttributeKey: (key: string) => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* @description The attribute name a record key stands for: `@xmlns` becomes `xmlns`.
|
|
53
|
+
*
|
|
54
|
+
* @param key - A key that {@link isAttributeKey} accepted.
|
|
55
|
+
*
|
|
56
|
+
* @returns The name with the prefix removed.
|
|
57
|
+
*/
|
|
58
|
+
export declare const attributeName: (key: string) => string;
|
|
59
|
+
/**
|
|
60
|
+
* @description Whether a record key holds character data rather than a child element or an attribute.
|
|
61
|
+
*
|
|
62
|
+
* @param key - The key to classify.
|
|
63
|
+
*
|
|
64
|
+
* @returns Whether the key is the reserved {@link TEXT_KEY}.
|
|
65
|
+
*/
|
|
66
|
+
export declare const isTextKey: (key: string) => boolean;
|
|
67
|
+
/**
|
|
68
|
+
* @description Whether a key is one this package reserves. Only {@link TEXT_KEY} is reserved today; every other key is read as a child element name.
|
|
69
|
+
*
|
|
70
|
+
* @param key - The key to classify.
|
|
71
|
+
*
|
|
72
|
+
* @returns Whether the key is reserved.
|
|
73
|
+
*/
|
|
74
|
+
export declare const isReservedKey: (key: string) => boolean;
|
|
75
|
+
/**
|
|
76
|
+
* @description Resolves a name to something legal in an XML document. The renderer and the parser both resolve a name per element and per attribute, and an
|
|
77
|
+
* illegal name under `'error'` mode is a rejection rather than a value, so this returns an `Effect` with the `XmlParseError` in its error channel
|
|
78
|
+
* rather than throwing it. Callers `yield*` it and the failure composes with `catchTag` and the rest; the two internal call sites in `parse.ts` and
|
|
79
|
+
* `render.ts` use {@link resolveNameSync} directly, because their walks are synchronous hot paths.
|
|
80
|
+
*
|
|
81
|
+
* @param name - The candidate element or attribute name.
|
|
82
|
+
* @param options - Repair mode and XML version.
|
|
83
|
+
*
|
|
84
|
+
* @returns An effect producing the name to write, unchanged when it was already legal.
|
|
85
|
+
*/
|
|
86
|
+
export declare const resolveName: (name: string, options?: ResolveNameOptions) => Effect.Effect<string, XmlParseError>;
|
|
87
|
+
//#endregion
|
|
88
|
+
//# sourceMappingURL=conventions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.d.ts","names":[],"sources":["../src/conventions.ts"],"mappings":";;;;;;;qBAUa;;;;qBAKA;;;;qBAKA;;;;qBAKA;;;;;;;;;YAUD;;;;iBAKK;;;;WAIN,OAAO;;;;WAKP,aAAa;;;;;;;;;qBAUX,iBAAc;;;;;;;;qBASd,gBAAa;;;;;;;;qBASb,YAAS;;;;;;;;qBAST,gBAAa;;;;;;;;;;;;qBAyDb,cAAW,cAAgB,UAAW,uBAA0B,OAAO,eAAe"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { XmlParseError } from "./errors.js";
|
|
2
|
+
import { isQName, sanitize, validate } from "./naming.js";
|
|
3
|
+
import { Effect, Predicate, Result } from "effect";
|
|
4
|
+
//#region src/conventions.ts
|
|
5
|
+
/**
|
|
6
|
+
* @description The key prefix that marks a field as an XML attribute. `@xmlns` is written as `xmlns="…"`.
|
|
7
|
+
*/
|
|
8
|
+
const ATTRIBUTE_PREFIX = "@";
|
|
9
|
+
/**
|
|
10
|
+
* @description The reserved key holding an element's character data, alongside its attributes and child elements.
|
|
11
|
+
*/
|
|
12
|
+
const TEXT_KEY = "#text";
|
|
13
|
+
/**
|
|
14
|
+
* @description The element name used when nothing else names the root. Matches the default Effect uses in `Schema.toEncoderXml`.
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_ROOT_NAME = "root";
|
|
17
|
+
/**
|
|
18
|
+
* @description The element name used for array members that have no natural name of their own. Matches the default in `Schema.toEncoderXml`.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_ITEM_NAME = "item";
|
|
21
|
+
/**
|
|
22
|
+
* @description Whether a record key names an attribute rather than a child element.
|
|
23
|
+
*
|
|
24
|
+
* @param key - The key to classify.
|
|
25
|
+
*
|
|
26
|
+
* @returns Whether the key carries the {@link ATTRIBUTE_PREFIX}.
|
|
27
|
+
*/
|
|
28
|
+
const isAttributeKey = (key) => key.charCodeAt(0) === 64 && key.length > 1;
|
|
29
|
+
/**
|
|
30
|
+
* @description The attribute name a record key stands for: `@xmlns` becomes `xmlns`.
|
|
31
|
+
*
|
|
32
|
+
* @param key - A key that {@link isAttributeKey} accepted.
|
|
33
|
+
*
|
|
34
|
+
* @returns The name with the prefix removed.
|
|
35
|
+
*/
|
|
36
|
+
const attributeName = (key) => key.slice(1);
|
|
37
|
+
/**
|
|
38
|
+
* @description Whether a record key holds character data rather than a child element or an attribute.
|
|
39
|
+
*
|
|
40
|
+
* @param key - The key to classify.
|
|
41
|
+
*
|
|
42
|
+
* @returns Whether the key is the reserved {@link TEXT_KEY}.
|
|
43
|
+
*/
|
|
44
|
+
const isTextKey = (key) => key === TEXT_KEY;
|
|
45
|
+
/**
|
|
46
|
+
* @description Whether a key is one this package reserves. Only {@link TEXT_KEY} is reserved today; every other key is read as a child element name.
|
|
47
|
+
*
|
|
48
|
+
* @param key - The key to classify.
|
|
49
|
+
*
|
|
50
|
+
* @returns Whether the key is reserved.
|
|
51
|
+
*/
|
|
52
|
+
const isReservedKey = (key) => isTextKey(key);
|
|
53
|
+
/**
|
|
54
|
+
* @description Resolves a name to something legal in an XML document, synchronously. The renderer and the parser both resolve a name per element and per attribute
|
|
55
|
+
* — the codec's hot path — so the walk calls this directly and keeps the work in plain JavaScript. `'error'` mode reports an illegal name by throwing
|
|
56
|
+
* an {@link XmlParseError}; the callers that need it in a typed channel use {@link resolveName}, which wraps this.
|
|
57
|
+
*
|
|
58
|
+
* @param name - The candidate element or attribute name.
|
|
59
|
+
* @param options - Repair mode and XML version.
|
|
60
|
+
*
|
|
61
|
+
* @returns The name to write, unchanged when it was already legal.
|
|
62
|
+
*
|
|
63
|
+
* @throws {XmlParseError} When the name is illegal and the mode is `'error'`.
|
|
64
|
+
*/
|
|
65
|
+
const resolveNameSync = (name, { mode = "repair", xmlVersion = "1.0" } = {}) => {
|
|
66
|
+
if (isQName(name, { xmlVersion })) return name;
|
|
67
|
+
if (mode === "ignore") return name;
|
|
68
|
+
if (mode === "repair") return sanitize(name, "name", { replacement: "_" });
|
|
69
|
+
const result = Effect.runSync(validate(name, "qName", { xmlVersion }));
|
|
70
|
+
const reason = !result.valid ? result.reason : "is not a legal XML name";
|
|
71
|
+
throw new XmlParseError({
|
|
72
|
+
message: `Invalid XML name ${JSON.stringify(name)}: ${reason}`,
|
|
73
|
+
position: -1,
|
|
74
|
+
input: name
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* @description {@link resolveNameSync} with the thrown failure folded into a {@link Result}, so an effectful caller can carry it in a typed channel without a
|
|
79
|
+
* try/catch of its own.
|
|
80
|
+
*
|
|
81
|
+
* @param name - The candidate element or attribute name.
|
|
82
|
+
* @param options - Repair mode and XML version.
|
|
83
|
+
*
|
|
84
|
+
* @returns The resolved name, or the failure to report.
|
|
85
|
+
*/
|
|
86
|
+
const resolveNameResult = (name, options) => {
|
|
87
|
+
try {
|
|
88
|
+
return Result.succeed(resolveNameSync(name, options));
|
|
89
|
+
} catch (cause) {
|
|
90
|
+
if (cause instanceof XmlParseError) return Result.fail(cause);
|
|
91
|
+
return Result.fail(new XmlParseError({
|
|
92
|
+
message: Predicate.isError(cause) ? cause.message : String(cause),
|
|
93
|
+
position: -1,
|
|
94
|
+
input: name
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* @description Resolves a name to something legal in an XML document. The renderer and the parser both resolve a name per element and per attribute, and an
|
|
100
|
+
* illegal name under `'error'` mode is a rejection rather than a value, so this returns an `Effect` with the `XmlParseError` in its error channel
|
|
101
|
+
* rather than throwing it. Callers `yield*` it and the failure composes with `catchTag` and the rest; the two internal call sites in `parse.ts` and
|
|
102
|
+
* `render.ts` use {@link resolveNameSync} directly, because their walks are synchronous hot paths.
|
|
103
|
+
*
|
|
104
|
+
* @param name - The candidate element or attribute name.
|
|
105
|
+
* @param options - Repair mode and XML version.
|
|
106
|
+
*
|
|
107
|
+
* @returns An effect producing the name to write, unchanged when it was already legal.
|
|
108
|
+
*/
|
|
109
|
+
const resolveName = (name, options = {}) => Effect.suspend(() => Effect.fromResult(resolveNameResult(name, options)));
|
|
110
|
+
//#endregion
|
|
111
|
+
export { ATTRIBUTE_PREFIX, DEFAULT_ITEM_NAME, DEFAULT_ROOT_NAME, TEXT_KEY, attributeName, isAttributeKey, isReservedKey, isTextKey, resolveName, resolveNameSync };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=conventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.js","names":[],"sources":["../src/conventions.ts"],"sourcesContent":["import { Effect, Predicate, Result } from 'effect';\n\nimport type { XmlVersion } from './naming.ts';\n\nimport { XmlParseError } from './errors.ts';\nimport { isQName, sanitize, validate } from './naming.ts';\n\n/**\n * @description The key prefix that marks a field as an XML attribute. `@xmlns` is written as `xmlns=\"…\"`.\n */\nexport const ATTRIBUTE_PREFIX = '@';\n\n/**\n * @description The reserved key holding an element's character data, alongside its attributes and child elements.\n */\nexport const TEXT_KEY = '#text';\n\n/**\n * @description The element name used when nothing else names the root. Matches the default Effect uses in `Schema.toEncoderXml`.\n */\nexport const DEFAULT_ROOT_NAME = 'root';\n\n/**\n * @description The element name used for array members that have no natural name of their own. Matches the default in `Schema.toEncoderXml`.\n */\nexport const DEFAULT_ITEM_NAME = 'item';\n\n/**\n * @description What to do with a name that is not a legal XML name.\n *\n * - `repair` rewrites it into the nearest legal name. The default, because a serializer that silently produces a different tag name is worse than one\n * that produces a legal one.\n * - `error` fails the render. Use it when a rewritten name would silently change the meaning of the document.\n * - `ignore` writes the name as given, producing a document that is not well-formed. Only useful when a downstream step rewrites names anyway.\n */\nexport type NameMode = 'error' | 'ignore' | 'repair';\n\n/**\n * @description Options for {@link resolveName}.\n */\nexport interface ResolveNameOptions {\n /**\n * @description What to do with an illegal name. Defaults to `'repair'`.\n */\n readonly mode?: NameMode | undefined;\n\n /**\n * @description XML version to validate against. Defaults to `'1.0'`.\n */\n readonly xmlVersion?: XmlVersion | undefined;\n}\n\n/**\n * @description Whether a record key names an attribute rather than a child element.\n *\n * @param key - The key to classify.\n *\n * @returns Whether the key carries the {@link ATTRIBUTE_PREFIX}.\n */\nexport const isAttributeKey = (key: string): boolean => key.charCodeAt(0) === 64 && key.length > 1;\n\n/**\n * @description The attribute name a record key stands for: `@xmlns` becomes `xmlns`.\n *\n * @param key - A key that {@link isAttributeKey} accepted.\n *\n * @returns The name with the prefix removed.\n */\nexport const attributeName = (key: string): string => key.slice(1);\n\n/**\n * @description Whether a record key holds character data rather than a child element or an attribute.\n *\n * @param key - The key to classify.\n *\n * @returns Whether the key is the reserved {@link TEXT_KEY}.\n */\nexport const isTextKey = (key: string): boolean => key === TEXT_KEY;\n\n/**\n * @description Whether a key is one this package reserves. Only {@link TEXT_KEY} is reserved today; every other key is read as a child element name.\n *\n * @param key - The key to classify.\n *\n * @returns Whether the key is reserved.\n */\nexport const isReservedKey = (key: string): boolean => isTextKey(key);\n\n/**\n * @description Resolves a name to something legal in an XML document, synchronously. The renderer and the parser both resolve a name per element and per attribute\n * — the codec's hot path — so the walk calls this directly and keeps the work in plain JavaScript. `'error'` mode reports an illegal name by throwing\n * an {@link XmlParseError}; the callers that need it in a typed channel use {@link resolveName}, which wraps this.\n *\n * @param name - The candidate element or attribute name.\n * @param options - Repair mode and XML version.\n *\n * @returns The name to write, unchanged when it was already legal.\n *\n * @throws {XmlParseError} When the name is illegal and the mode is `'error'`.\n */\nexport const resolveNameSync = (name: string, { mode = 'repair', xmlVersion = '1.0' }: ResolveNameOptions = {}): string => {\n if (isQName(name, { xmlVersion })) return name;\n if (mode === 'ignore') return name;\n if (mode === 'repair') return sanitize(name, 'name', { replacement: '_' });\n\n // `validate` only fails for an unknown production, which `'qName'` is not, so\n // this runs a plain result and the failure is the reason the name is refused.\n const result = Effect.runSync(validate(name, 'qName', { xmlVersion }));\n const reason = !result.valid ? result.reason : 'is not a legal XML name';\n throw new XmlParseError({ message: `Invalid XML name ${JSON.stringify(name)}: ${reason}`, position: -1, input: name });\n};\n\n/**\n * @description {@link resolveNameSync} with the thrown failure folded into a {@link Result}, so an effectful caller can carry it in a typed channel without a\n * try/catch of its own.\n *\n * @param name - The candidate element or attribute name.\n * @param options - Repair mode and XML version.\n *\n * @returns The resolved name, or the failure to report.\n */\nconst resolveNameResult = (name: string, options: ResolveNameOptions): Result.Result<string, XmlParseError> => {\n try {\n return Result.succeed(resolveNameSync(name, options));\n } catch (cause) {\n if (cause instanceof XmlParseError) {\n return Result.fail(cause);\n }\n return Result.fail(new XmlParseError({ message: Predicate.isError(cause) ? cause.message : String(cause), position: -1, input: name }));\n }\n};\n\n/**\n * @description Resolves a name to something legal in an XML document. The renderer and the parser both resolve a name per element and per attribute, and an\n * illegal name under `'error'` mode is a rejection rather than a value, so this returns an `Effect` with the `XmlParseError` in its error channel\n * rather than throwing it. Callers `yield*` it and the failure composes with `catchTag` and the rest; the two internal call sites in `parse.ts` and\n * `render.ts` use {@link resolveNameSync} directly, because their walks are synchronous hot paths.\n *\n * @param name - The candidate element or attribute name.\n * @param options - Repair mode and XML version.\n *\n * @returns An effect producing the name to write, unchanged when it was already legal.\n */\nexport const resolveName = (name: string, options: ResolveNameOptions = {}): Effect.Effect<string, XmlParseError> =>\n Effect.suspend(() => Effect.fromResult(resolveNameResult(name, options)));\n"],"mappings":";;;;;;;AAUA,MAAa,mBAAmB;;;;AAKhC,MAAa,WAAW;;;;AAKxB,MAAa,oBAAoB;;;;AAKjC,MAAa,oBAAoB;;;;;;;;AAkCjC,MAAa,kBAAkB,QAAyB,IAAI,WAAW,CAAC,MAAM,MAAM,IAAI,SAAS;;;;;;;;AASjG,MAAa,iBAAiB,QAAwB,IAAI,MAAM,CAAC;;;;;;;;AASjE,MAAa,aAAa,QAAyB,QAAQ;;;;;;;;AAS3D,MAAa,iBAAiB,QAAyB,UAAU,GAAG;;;;;;;;;;;;;AAcpE,MAAa,mBAAmB,MAAc,EAAE,OAAO,UAAU,aAAa,UAA8B,CAAC,MAAc;CACzH,IAAI,QAAQ,MAAM,EAAE,WAAW,CAAC,GAAG,OAAO;CAC1C,IAAI,SAAS,UAAU,OAAO;CAC9B,IAAI,SAAS,UAAU,OAAO,SAAS,MAAM,QAAQ,EAAE,aAAa,IAAI,CAAC;CAIzE,MAAM,SAAS,OAAO,QAAQ,SAAS,MAAM,SAAS,EAAE,WAAW,CAAC,CAAC;CACrE,MAAM,SAAS,CAAC,OAAO,QAAQ,OAAO,SAAS;CAC/C,MAAM,IAAI,cAAc;EAAE,SAAS,oBAAoB,KAAK,UAAU,IAAI,EAAE,IAAI;EAAU,UAAU;EAAI,OAAO;CAAK,CAAC;AACvH;;;;;;;;;;AAWA,MAAM,qBAAqB,MAAc,YAAsE;CAC7G,IAAI;EACF,OAAO,OAAO,QAAQ,gBAAgB,MAAM,OAAO,CAAC;CACtD,SAAS,OAAO;EACd,IAAI,iBAAiB,eACnB,OAAO,OAAO,KAAK,KAAK;EAE1B,OAAO,OAAO,KAAK,IAAI,cAAc;GAAE,SAAS,UAAU,QAAQ,KAAK,IAAI,MAAM,UAAU,OAAO,KAAK;GAAG,UAAU;GAAI,OAAO;EAAK,CAAC,CAAC;CACxI;AACF;;;;;;;;;;;;AAaA,MAAa,eAAe,MAAc,UAA8B,CAAC,MACvE,OAAO,cAAc,OAAO,WAAW,kBAAkB,MAAM,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { XmlError } from "../xml-error.js";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/entities/entity-decoder.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* @description What an {@link EntityRegistrationHook} returns. Use {@link ENTITY_ACTION} rather than the bare strings, so a typo is a type error instead of an
|
|
6
|
+
* entity that is accepted by default.
|
|
7
|
+
*/
|
|
8
|
+
export type EntityHookAction = 'allow' | 'block' | 'throw';
|
|
9
|
+
/**
|
|
10
|
+
* @description A function-valued entity replacement: the `val` of the legacy `{ regex, val }` form when it is not a string. This decoder cannot use one — a
|
|
11
|
+
* function has no meaning without the regex it was meant to be matched against — so such an entry is dropped at registration rather than expanded.
|
|
12
|
+
*/
|
|
13
|
+
export type EntityValFn = (match: string, captured: string, ...rest: Array<unknown>) => string;
|
|
14
|
+
/**
|
|
15
|
+
* @description Called once per entity _at registration time_, never during {@link EntityDecoder.decode}. Receives the name without `&` and `;` and the resolved
|
|
16
|
+
* string value, after any `{ regex, val }` envelope has been unwrapped.
|
|
17
|
+
*
|
|
18
|
+
* @param name - The entity name, e.g. `brand`.
|
|
19
|
+
* @param value - The string the entity expands to.
|
|
20
|
+
*
|
|
21
|
+
* @returns The action to take. Anything other than `block` and `throw` is treated as `allow`, so an unrecognised return value never rejects an entity
|
|
22
|
+
* by accident.
|
|
23
|
+
*/
|
|
24
|
+
export type EntityRegistrationHook = (name: string, value: string) => EntityHookAction;
|
|
25
|
+
/**
|
|
26
|
+
* @description The three actions a registration hook can return, as a frozen object. Prefer it over the bare strings: the literals stay narrow string-literal
|
|
27
|
+
* types, so `ENTITY_ACTION.BLOK` fails to compile instead of silently registering the entity.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const decoder = new EntityDecoder({
|
|
32
|
+
* onInputEntity: () => ENTITY_ACTION.BLOCK,
|
|
33
|
+
* });
|
|
34
|
+
* ```;
|
|
35
|
+
*/
|
|
36
|
+
export declare const ENTITY_ACTION: Readonly<{
|
|
37
|
+
ALLOW: 'allow';
|
|
38
|
+
BLOCK: 'block';
|
|
39
|
+
THROW: 'throw';
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* @description Which entity categories count toward the expansion limits.
|
|
43
|
+
*
|
|
44
|
+
* - `'external'` — only input/runtime + persistent external entities. The default, and the only one that ignores the built-in XML entities.
|
|
45
|
+
* - `'base'` — only the built-in XML entities, the caller's `namedEntities`, and numeric references.
|
|
46
|
+
* - `'all'` — every entity regardless of tier.
|
|
47
|
+
* - `Array<'external' | 'base'>` — an explicit combination. An empty array is honoured literally: nothing counts, so the limits can never trip.
|
|
48
|
+
*/
|
|
49
|
+
export type ApplyLimitsTo = 'external' | 'base' | 'all' | Array<'external' | 'base'>;
|
|
50
|
+
/**
|
|
51
|
+
* @description Ceilings on what a single document's entity references may cost. Both are cumulative across {@link EntityDecoder.decode} calls until
|
|
52
|
+
* {@link EntityDecoder.reset}, and both default to `0`, meaning unlimited. `0` — and any negative or non-numeric value — is unlimited, because the
|
|
53
|
+
* runtime tests `> 0` rather than truthiness of the configured number.
|
|
54
|
+
*/
|
|
55
|
+
export interface EntityDecoderLimitOptions {
|
|
56
|
+
/**
|
|
57
|
+
* @description Maximum number of tracked entity references expanded per document. The check is `> maxTotalExpansions`, so a limit of `2` allows two expansions
|
|
58
|
+
* and throws on the third.
|
|
59
|
+
*
|
|
60
|
+
* @default 0
|
|
61
|
+
*/
|
|
62
|
+
maxTotalExpansions?: number;
|
|
63
|
+
/**
|
|
64
|
+
* @description Maximum number of characters _added_ by expansion per document. Only the surplus counts: a reference whose replacement is no longer than the
|
|
65
|
+
* `&token;` it replaces contributes zero, and a shrinking one contributes nothing and cannot trip the limit.
|
|
66
|
+
*
|
|
67
|
+
* @default 0
|
|
68
|
+
*/
|
|
69
|
+
maxExpandedLength?: number;
|
|
70
|
+
/**
|
|
71
|
+
* @description Which tiers count against both limits. Defaults to `'external'`, which is what keeps the built-in entities — including every numeric reference —
|
|
72
|
+
* from being able to trip a limit on a document the caller already trusts.
|
|
73
|
+
*
|
|
74
|
+
* @default 'external'
|
|
75
|
+
*/
|
|
76
|
+
applyLimitsTo?: ApplyLimitsTo;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @description Policy for numeric character references. The three fields are flattened into numeric levels at construction so the decode loop never re-reads the
|
|
80
|
+
* object.
|
|
81
|
+
*/
|
|
82
|
+
export interface EntityDecoderNCROptions {
|
|
83
|
+
/**
|
|
84
|
+
* @description The XML version whose codepoint restrictions apply. `1.0` prohibits the C0 controls U+0001–U+001F other than tab, newline and carriage return;
|
|
85
|
+
* `1.1` does not, since it permits them when written as references. Any value other than `1.1` is read as `1.0`.
|
|
86
|
+
*
|
|
87
|
+
* @default 1.0
|
|
88
|
+
*/
|
|
89
|
+
xmlVersion?: 1.0 | 1.1;
|
|
90
|
+
/**
|
|
91
|
+
* @description The base action for every numeric reference. Codepoint ranges that carry a minimum — surrogates always, the XML 1.0 C0 controls under `1.0`, and
|
|
92
|
+
* null under `nullNCR` — take the stricter of the two, so this is a floor and not an override.
|
|
93
|
+
*
|
|
94
|
+
* @default 'allow'
|
|
95
|
+
*/
|
|
96
|
+
onNCR?: 'allow' | 'leave' | 'remove' | 'throw';
|
|
97
|
+
/**
|
|
98
|
+
* @description The action for U+0000. `'allow'` and `'leave'` are clamped up to `'remove'`, so a null reference is always at least deleted.
|
|
99
|
+
*
|
|
100
|
+
* @default 'remove'
|
|
101
|
+
*/
|
|
102
|
+
nullNCR?: 'remove' | 'throw';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @description Construction options for {@link EntityDecoder}. Every field is optional, and the defaults are the permissive ones.
|
|
106
|
+
*/
|
|
107
|
+
export interface EntityDecoderOptions {
|
|
108
|
+
/**
|
|
109
|
+
* @description Extra named entities merged into the `base` map alongside the five XML predefined ones. A string value is used directly; a `{ regex, val }` or `{
|
|
110
|
+
* regx, val }` envelope is unwrapped to its `val`. Anything else — a number, `null`, a function, an envelope whose `val` is a function — is
|
|
111
|
+
* dropped, leaving the name unresolvable rather than failing the construction. Upstream's documentation says a value containing `&` is skipped
|
|
112
|
+
* here, to prevent recursive expansion. It is not: the code stores the value unchanged, and only {@link EntityDecoder.addExternalEntity} checks for
|
|
113
|
+
* `&`. Preserved as-is; see the note on the class.
|
|
114
|
+
*
|
|
115
|
+
* @default null
|
|
116
|
+
*/
|
|
117
|
+
namedEntities?: Record<string, string | {
|
|
118
|
+
regex: RegExp;
|
|
119
|
+
val: string | EntityValFn;
|
|
120
|
+
}> | null;
|
|
121
|
+
/**
|
|
122
|
+
* @description Called once on the finished string. Receives `(resolved, original)` and must return a string; return `original` to reject the expansion outright,
|
|
123
|
+
* or a sanitised form of `resolved` to clean it. It is _not_ called for a string that never reaches the scanning loop — an empty string, a
|
|
124
|
+
* non-string, or any string with no `&` in it. A caller relying on `postCheck` to sanitise therefore has to know that a string with no ampersand is
|
|
125
|
+
* never inspected.
|
|
126
|
+
*
|
|
127
|
+
* @default null
|
|
128
|
+
*/
|
|
129
|
+
postCheck?: ((resolved: string, original: string) => string) | null;
|
|
130
|
+
/**
|
|
131
|
+
* @description Whether numeric references expand at all. Turning it off leaves every one of them in the output verbatim — _except_ the codepoints that carry a
|
|
132
|
+
* minimum action of `remove` or stricter, which are still handled, because that classification runs first and is what makes the option safe to rely
|
|
133
|
+
* on.
|
|
134
|
+
*
|
|
135
|
+
* @default true
|
|
136
|
+
*/
|
|
137
|
+
numericAllowed?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* @description Names to keep as literal `&name;` text, matched against the token with no `&` or `;`. Numeric references are matched as `#38` or `#x26`.
|
|
140
|
+
*
|
|
141
|
+
* @default [ ]
|
|
142
|
+
*/
|
|
143
|
+
leave?: Array<string>;
|
|
144
|
+
/**
|
|
145
|
+
* @description Names to delete outright, matched the same way as {@link EntityDecoderOptions.leave}. A removed reference is charged to the `external` tier even
|
|
146
|
+
* when the name is a built-in one, so a document full of removed built-ins can trip an `applyLimitsTo: 'external'` limit it would not otherwise be
|
|
147
|
+
* subject to. Preserved as-is; the only in-code comment claims the charge is for unknown references, which is not what distinguishes them.
|
|
148
|
+
*
|
|
149
|
+
* @default [ ]
|
|
150
|
+
*/
|
|
151
|
+
remove?: Array<string>;
|
|
152
|
+
/**
|
|
153
|
+
* @description Ceilings on expansion count and expanded length. See {@link EntityDecoderLimitOptions}.
|
|
154
|
+
*/
|
|
155
|
+
limit?: EntityDecoderLimitOptions;
|
|
156
|
+
/**
|
|
157
|
+
* @description Policy for numeric references. See {@link EntityDecoderNCROptions}.
|
|
158
|
+
*/
|
|
159
|
+
ncr?: EntityDecoderNCROptions;
|
|
160
|
+
/**
|
|
161
|
+
* @description Called once per entity as it is registered through {@link EntityDecoder.setExternalEntities} or {@link EntityDecoder.addExternalEntity}. `block`
|
|
162
|
+
* skips the entity, `throw` aborts the whole registration, anything else registers it. With {@link EntityDecoder.setExternalEntities} a `throw`
|
|
163
|
+
* leaves the previous external map in place, because the replacement is only assigned once every entry has passed.
|
|
164
|
+
*
|
|
165
|
+
* @default null
|
|
166
|
+
*/
|
|
167
|
+
onExternalEntity?: EntityRegistrationHook | null;
|
|
168
|
+
/**
|
|
169
|
+
* @description Called once per entity as it is registered through {@link EntityDecoder.addInputEntities}. Same contract as
|
|
170
|
+
* {@link EntityDecoderOptions.onExternalEntity}, and unlike it the hook is not the only filter — see the class note on name validation.
|
|
171
|
+
*
|
|
172
|
+
* @default null
|
|
173
|
+
*/
|
|
174
|
+
onInputEntity?: EntityRegistrationHook | null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* @description Single-pass, zero-regex entity decoder for XML and HTML content.
|
|
178
|
+
*
|
|
179
|
+
* ### Entity lookup priority
|
|
180
|
+
*
|
|
181
|
+
* 1. **input / runtime** — injected per document through {@link EntityDecoder.addInputEntities}
|
|
182
|
+
* 2. **persistent external** — set through {@link EntityDecoder.setExternalEntities} and {@link EntityDecoder.addExternalEntity}, surviving
|
|
183
|
+
* {@link EntityDecoder.reset}
|
|
184
|
+
* 3. **base** — the five XML predefined entities plus the constructor's `namedEntities` Both input and external resolve as the `external` tier for limit
|
|
185
|
+
* purposes, because both are injected at runtime. Numeric references (`&#NNN;`, `&#xHH;`) resolve directly through `String.fromCodePoint` and are
|
|
186
|
+
* always `base` tier: they cannot recurse, so a limit that counted them would only punish a document that spells its characters out.
|
|
187
|
+
*
|
|
188
|
+
* ### Upstream behaviour preserved
|
|
189
|
+
*
|
|
190
|
+
* Several quirks of the original are kept deliberately, because a consumer's output already depends on them:
|
|
191
|
+
*
|
|
192
|
+
* - A value containing `&` is **not** filtered from `namedEntities` or `setExternalEntities`, contrary to the documentation. Only
|
|
193
|
+
* {@link EntityDecoder.addExternalEntity} checks, and it drops the entry rather than storing it, so the same name registered either way can resolve
|
|
194
|
+
* to nothing.
|
|
195
|
+
* - {@link EntityDecoderOptions.postCheck} is skipped entirely for input that never reaches the scan — an empty string, a non-string, or a string with
|
|
196
|
+
* no `&`.
|
|
197
|
+
* - {@link EntityDecoder.decode} returns a non-string argument unchanged, despite being typed `string`.
|
|
198
|
+
* - The expansion-limit errors are prefixed `EntityReplacer`, not `EntityDecoder`.
|
|
199
|
+
* - Nothing in XML 1.0 §2.2 is enforced for U+007F–U+009F or for the U+FFFE/U+FFFF noncharacters, and the sweep for `&` leaves a name of
|
|
200
|
+
* {@link MAX_TOKEN_LENGTH} + 1 characters unresolvable.
|
|
201
|
+
* - Numeric references are parsed with `parseInt`, so a leading space, sign, or trailing garbage is accepted: `&# 41;`, `&#x+41;` and `)zz;` all
|
|
202
|
+
* decode, and `�x41;` parses as a null reference rather than `A`.
|
|
203
|
+
* - {@link EntityDecoder.addInputEntities} validates no names, so a `#`-prefixed or `&`-bearing name registers without complaint, where the two
|
|
204
|
+
* external setters would throw.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* const decoder = new EntityDecoder({ namedEntities: { copy: '©' } });
|
|
209
|
+
* decoder.setExternalEntities({ brand: 'Acme' });
|
|
210
|
+
* decoder.addInputEntities({ version: '1.0' });
|
|
211
|
+
*
|
|
212
|
+
* decoder.decode('&brand; v&version; ©'); // 'Acme v1.0 ©'
|
|
213
|
+
* decoder.decode('&#38;'); // '&&' — one pass, the output is never re-scanned
|
|
214
|
+
*
|
|
215
|
+
* decoder.reset(); // drops the input entities and the counters, keeps the external ones
|
|
216
|
+
* ```;
|
|
217
|
+
*/
|
|
218
|
+
export declare class EntityDecoder {
|
|
219
|
+
#private;
|
|
220
|
+
/**
|
|
221
|
+
* @description Create a decoder. A factory rather than a constructor, because it refuses a `null` options object. Every field is optional, so `null` is not "a
|
|
222
|
+
* decoder with the defaults" — a caller who wrote it meant something the signature does not allow, and a decoder built from it would be
|
|
223
|
+
* indistinguishable from one built from `{}` while hiding the mistake. Saying so is worth a factory; `EntityDecoderOptions` is a plain object and
|
|
224
|
+
* nothing else about construction can fail.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```typescript
|
|
228
|
+
* const decoder = yield* EntityDecoder.make({ numericAllowed: false });
|
|
229
|
+
* yield* decoder.decode('café'); // 'café'
|
|
230
|
+
* ```;
|
|
231
|
+
*
|
|
232
|
+
* @param options - Configuration. See {@link EntityDecoderOptions}. Defaults to every field's own default.
|
|
233
|
+
*
|
|
234
|
+
* @returns An effect producing the decoder. Fails with {@link XmlError} and the `MissingOptions` reason for a `null`.
|
|
235
|
+
*/
|
|
236
|
+
static make: (options?: EntityDecoderOptions) => Effect.Effect<EntityDecoder, XmlError>;
|
|
237
|
+
/**
|
|
238
|
+
* @description Create a decoder. Every option is resolved here into the flat fields the decode loop reads, so nothing per-reference has to re-derive it. The
|
|
239
|
+
* options whose wrong type disables them rather than failing the construction — the two hooks, the two name lists — are read through
|
|
240
|
+
* {@link readHook} and {@link readNameList}, so that rule is written once instead of four times.
|
|
241
|
+
*
|
|
242
|
+
* @param resolved - Configuration, already checked. See {@link EntityDecoderOptions}.
|
|
243
|
+
*/
|
|
244
|
+
private constructor();
|
|
245
|
+
/**
|
|
246
|
+
* @description Replace the whole set of persistent external entities. Every key is validated _before_ any value is read, so an invalid name fails even when its
|
|
247
|
+
* value is a form the merge would have dropped. A non-object or `null` map clears the set without validating anything.
|
|
248
|
+
*
|
|
249
|
+
* @param map - The entities to register, or nothing to clear.
|
|
250
|
+
*
|
|
251
|
+
* @returns An effect that registers the map. Fails with {@link XmlError} when a key contains a character from {@link SPECIAL_CHARS} or begins with
|
|
252
|
+
* `#` (`InvalidEntityName`), or when {@link EntityDecoderOptions.onExternalEntity} returns `throw` (`EntityRejected`). A rejection from the hook
|
|
253
|
+
* aborts before the assignment, so the previous map survives.
|
|
254
|
+
*/
|
|
255
|
+
setExternalEntities: (this: EntityDecoder, map: Record<string, string | {
|
|
256
|
+
regex: RegExp;
|
|
257
|
+
val: string | EntityValFn;
|
|
258
|
+
}>) => Effect.Effect<void, XmlError, never>;
|
|
259
|
+
/**
|
|
260
|
+
* @description Add one persistent external entity, keeping whatever is already registered. This is the only registration path that refuses a value containing
|
|
261
|
+
* `&`; the two map setters store one unchanged. The omission is upstream's, and it is kept: the same name registered through either route can end
|
|
262
|
+
* up resolving, or not resolving at all.
|
|
263
|
+
*
|
|
264
|
+
* @param key - The entity name, without `&` or `;`.
|
|
265
|
+
* @param value - The replacement text.
|
|
266
|
+
*
|
|
267
|
+
* @returns An effect that adds the entity. Fails with {@link XmlError} and the `InvalidEntityName` reason when `key` contains a character from
|
|
268
|
+
* {@link SPECIAL_CHARS} or begins with `#`, or with the `EntityRejected` reason when {@link EntityDecoderOptions.onExternalEntity} returns
|
|
269
|
+
* `throw`.
|
|
270
|
+
*/
|
|
271
|
+
addExternalEntity: (this: EntityDecoder, key: string, value: string) => Effect.Effect<void, XmlError, never>;
|
|
272
|
+
/**
|
|
273
|
+
* @description Register the DOCTYPE entities for the document about to be decoded, replacing any previous set and clearing both counters. Unlike the external
|
|
274
|
+
* setters, no name is validated: a `#`-prefixed name, or one containing `&` or `<`, registers without complaint. A `#`-prefixed name is then
|
|
275
|
+
* unreachable, since `decode` routes `#`-prefixed tokens to the numeric pipeline first.
|
|
276
|
+
*
|
|
277
|
+
* @param map - The entities to register, or nothing to clear.
|
|
278
|
+
*
|
|
279
|
+
* @returns An effect that registers the map. Fails with {@link XmlError} and the `EntityRejected` reason when
|
|
280
|
+
* {@link EntityDecoderOptions.onInputEntity} returns `throw`. The counters have already been cleared by then.
|
|
281
|
+
*/
|
|
282
|
+
addInputEntities: (this: EntityDecoder, map: Record<string, string | {
|
|
283
|
+
regx: RegExp;
|
|
284
|
+
val: string | EntityValFn;
|
|
285
|
+
} | {
|
|
286
|
+
regex: RegExp;
|
|
287
|
+
val: string | EntityValFn;
|
|
288
|
+
}>) => Effect.Effect<void, XmlError, never>;
|
|
289
|
+
/**
|
|
290
|
+
* @description Start a new document: drop the input entities and both counters. The persistent external entities, the base map, the limits, the NCR policy and
|
|
291
|
+
* the XML version all survive, which is the difference between this and constructing a fresh decoder.
|
|
292
|
+
*
|
|
293
|
+
* @returns This decoder, so a call can be chained onto the document it ends.
|
|
294
|
+
*/
|
|
295
|
+
reset(): this;
|
|
296
|
+
/**
|
|
297
|
+
* @description Set the XML version used to classify numeric references, once a `<?xml version="…"?>` declaration has been read. Only the exact number `1.1`
|
|
298
|
+
* selects XML 1.1; `1.0`, `1.15`, `'1.1'` and `NaN` all become `1.0`, so the stricter classification is the default rather than the looser one.
|
|
299
|
+
*
|
|
300
|
+
* @param version - The declared version.
|
|
301
|
+
*
|
|
302
|
+
* @returns Nothing.
|
|
303
|
+
*/
|
|
304
|
+
setXmlVersion(version: number): void;
|
|
305
|
+
/**
|
|
306
|
+
* @description Expand every entity reference in a string, in one pass. The output is never re-scanned, so no expansion can produce a _second_ one: a registered
|
|
307
|
+
* value that itself contains reference text reaches the caller as that literal text, unexpanded. What the limits bound is the growth of this single
|
|
308
|
+
* pass — how much one round of expansion can add. Three inputs return before the scan and therefore never reach
|
|
309
|
+
* {@link EntityDecoderOptions.postCheck}: a non-string, the empty string, and any string with no `&` in it. The scan itself is `#expandAll`; what
|
|
310
|
+
* this method adds is the three inputs that skip it and the single join of what it collected.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```typescript
|
|
314
|
+
* import { Effect } from 'effect';
|
|
315
|
+
* import { EntityDecoder } from '@endevops/effect-xml-codec';
|
|
316
|
+
*
|
|
317
|
+
* const decoder = new EntityDecoder({ namedEntities: { copy: '©' } });
|
|
318
|
+
* Effect.runSync(Effect.orElseSucceed(decoder.addExternalEntity('brand', 'Acme'), () => undefined));
|
|
319
|
+
* Effect.runSync(decoder.decode('&brand; ©')); // 'Acme ©'
|
|
320
|
+
* ```;
|
|
321
|
+
*
|
|
322
|
+
* @param str - The string to decode.
|
|
323
|
+
*
|
|
324
|
+
* @returns An effect producing the decoded string. A non-string argument comes back as the same non-string, which the `string` return type does not
|
|
325
|
+
* describe but callers passing untyped values depend on. Fails with {@link XmlError} when a numeric reference is prohibited under the configured
|
|
326
|
+
* policy (`ProhibitedCharacterReference`), or when a tracked tier would exceed {@link EntityDecoderLimitOptions.maxTotalExpansions}
|
|
327
|
+
* (`ExpansionLimitExceeded`) or {@link EntityDecoderLimitOptions.maxExpandedLength} (`ExpandedLengthLimitExceeded`). The two limit messages keep
|
|
328
|
+
* the `EntityReplacer` prefix from the original throw, which named a class this decoder does not have.
|
|
329
|
+
*/
|
|
330
|
+
decode: (this: EntityDecoder, str: string) => Effect.Effect<string, XmlError, never>;
|
|
331
|
+
}
|
|
332
|
+
//#endregion
|
|
333
|
+
//# sourceMappingURL=entity-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-decoder.d.ts","names":[],"sources":["../../src/entities/entity-decoder.ts"],"mappings":";;;;;;;YA6HY;;;;;YAMA,eAAe,eAAe,qBAAqB,MAAM;;;;;;;;;;;YAYzD,0BAA0B,cAAc,kBAAkB;;;;;;;;;;;;qBAazD,eAAe;EAAW;EAAgB;EAAgB;;;;;;;;;;YAkB3D,8CAA8C;;;;;;iBAOzC;;;;;;;EAOf;;;;;;;EAQA;;;;;;;EAQA,gBAAgB;;;;;;iBAOD;;;;;;;EAOf;;;;;;;EAQA;;;;;;EAOA;;;;;iBAMe;;;;;;;;;;EAUf,gBAAgB;IAA0B,OAAO;IAAQ,cAAc;;;;;;;;;;EAUvE,cAAc,kBAAkB;;;;;;;;EAShC;;;;;;EAOA,QAAQ;;;;;;;;EASR,SAAS;;;;EAKT,QAAQ;;;;EAKR,MAAM;;;;;;;;EASN,mBAAmB;;;;;;;EAQnB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAoSL;;;;;;;;;;;;;;;;;;SAiHJ,OAAI,UAAa,yBAA4B,OAAO,OAAO,eAAe;;;;;;;;UAiB1E;;;;;;;;;;;EAkEP,sBAAmB,MAAA,eAAA,KAAA;IAEqB,OAAA;IAAa,cAAS;SAoB3D,OAAA,aAAA;;;;;;;;;;;;;EAcH,oBAAiB,MAAA,eAAA,aAAA,kBAAA,OAAA,aAAA;;;;;;;;;;;EAqBjB,mBAAgB,MAAA,eAAA,KAAA;IAEuB,MAAA;IAAa,cAAS;;IAAyB,OAAA;IAAa,cAAS;SAkBzG,OAAA,aAAA;;;;;;;EAQH;;;;;;;;;EAeA,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;EA6Bd,SAAM,MAAA,eAAA,gBAAA,OAAA,eAAA"}
|