@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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE-is-entities +21 -0
  3. package/LICENSE-is-xml-naming +21 -0
  4. package/README.md +415 -0
  5. package/dist/codec.d.ts +48 -0
  6. package/dist/codec.d.ts.map +1 -0
  7. package/dist/codec.js +63 -0
  8. package/dist/codec.js.map +1 -0
  9. package/dist/conventions.d.ts +88 -0
  10. package/dist/conventions.d.ts.map +1 -0
  11. package/dist/conventions.js +113 -0
  12. package/dist/conventions.js.map +1 -0
  13. package/dist/entities/entity-decoder.d.ts +333 -0
  14. package/dist/entities/entity-decoder.d.ts.map +1 -0
  15. package/dist/entities/entity-decoder.js +841 -0
  16. package/dist/entities/entity-decoder.js.map +1 -0
  17. package/dist/entities/entity-tables.js +16 -0
  18. package/dist/entities/entity-tables.js.map +1 -0
  19. package/dist/errors.d.ts +49 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +48 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.js +11 -0
  25. package/dist/namespaces.d.ts +101 -0
  26. package/dist/namespaces.d.ts.map +1 -0
  27. package/dist/namespaces.js +663 -0
  28. package/dist/namespaces.js.map +1 -0
  29. package/dist/naming.d.ts +149 -0
  30. package/dist/naming.d.ts.map +1 -0
  31. package/dist/naming.js +296 -0
  32. package/dist/naming.js.map +1 -0
  33. package/dist/parse.d.ts +75 -0
  34. package/dist/parse.d.ts.map +1 -0
  35. package/dist/parse.js +437 -0
  36. package/dist/parse.js.map +1 -0
  37. package/dist/render.d.ts +99 -0
  38. package/dist/render.d.ts.map +1 -0
  39. package/dist/render.js +509 -0
  40. package/dist/render.js.map +1 -0
  41. package/dist/xml-error.d.ts +172 -0
  42. package/dist/xml-error.d.ts.map +1 -0
  43. package/dist/xml-error.js +157 -0
  44. package/dist/xml-error.js.map +1 -0
  45. package/dist/xml-value.d.ts +42 -0
  46. package/dist/xml-value.d.ts.map +1 -0
  47. package/dist/xml-value.js +79 -0
  48. package/dist/xml-value.js.map +1 -0
  49. package/package.json +69 -0
  50. package/src/codec.ts +136 -0
  51. package/src/conventions.ts +145 -0
  52. package/src/entities/entity-decoder.ts +1248 -0
  53. package/src/entities/entity-tables.ts +18 -0
  54. package/src/errors.ts +55 -0
  55. package/src/index.ts +79 -0
  56. package/src/namespaces.ts +968 -0
  57. package/src/naming.ts +519 -0
  58. package/src/parse.ts +597 -0
  59. package/src/render.ts +708 -0
  60. package/src/xml-error.ts +168 -0
  61. package/src/xml-value.ts +108 -0
@@ -0,0 +1,18 @@
1
+ // entity-tables
2
+ //
3
+ // The named-entity tables the decoder reads. Only the five XML predefined
4
+ // entities survive here: the HTML tables belonged to the entity encoder, and
5
+ // the encoder was removed when `@endevops/common-xml` was merged into this
6
+ // package. The data is verbatim from `@nodable/entities@2.2.0`
7
+ // (`src/entities.js`); see `LICENSE-is-entities`.
8
+
9
+ /**
10
+ * @description A named-entity lookup: entity name to the replacement text it expands to. Every table in this module has this shape.
11
+ */
12
+ export type EntityTable = Readonly<Record<string, string>>;
13
+
14
+ /**
15
+ * @description The five XML predefined entities. The XML specification fixes these five names, so they are matched as a set rather than drawn from a table of
16
+ * aliases. `EntityDecoder` merges these into its base map by default.
17
+ */
18
+ export const XML: EntityTable = { amp: '&', apos: "'", gt: '>', lt: '<', quot: '"' };
package/src/errors.ts ADDED
@@ -0,0 +1,55 @@
1
+ // The one way XML serialization can fail that a `SchemaIssue.Issue` does not already describe.
2
+ //
3
+ // A schema mismatch — a `number` where the document says `text` — is a
4
+ // `SchemaIssue.Issue` and comes from Effect's own parser. What is left is the
5
+ // part Effect knows nothing about: a document that is not well-formed XML, and a
6
+ // field name that cannot be written as one.
7
+
8
+ import { Schema } from 'effect';
9
+
10
+ /**
11
+ * @description A document could not be read as XML.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { XmlParseError } from '@endevops/effect-xml-codec';
16
+ *
17
+ * const error = new XmlParseError({ message: 'Unclosed element', position: 12, input: '<a><b>' });
18
+ * ```;
19
+ */
20
+ export class XmlParseError extends Schema.TaggedError<XmlParseError>()('XmlParseError', {
21
+ /**
22
+ * @description What was wrong with the document.
23
+ */
24
+ message: Schema.String,
25
+
26
+ /**
27
+ * @description Character offset into the source text where the problem was found. `-1` when the failure is not tied to a position, such as trailing content
28
+ * after the root element.
29
+ */
30
+ position: Schema.Finite,
31
+
32
+ /**
33
+ * @description The source text that failed to parse, so a log can carry the document without the caller re-reading it.
34
+ */
35
+ input: Schema.String,
36
+ }) {}
37
+
38
+ /**
39
+ * @description A value could not be written as XML. A field name that is not a legal XML name fails here, in `'error'` name mode; repair mode rewrites the name
40
+ * instead. The depth cap fails here too, when a value nests past `maxDepth`. Reading uses {@link XmlParseError}, because the two directions fail for
41
+ * different reasons and a caller recovering from one usually does not want to catch the other.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import { XmlRenderError } from '@endevops/effect-xml-codec';
46
+ *
47
+ * const error = new XmlRenderError({ message: 'Invalid XML name "not a name"' });
48
+ * ```;
49
+ */
50
+ export class XmlRenderError extends Schema.TaggedError<XmlRenderError>()('XmlRenderError', {
51
+ /**
52
+ * @description What was wrong with the value.
53
+ */
54
+ message: Schema.String,
55
+ }) {}
package/src/index.ts ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @description A round-trip Effect Schema codec for XML. `toCodecXml(schema)` returns a `Schema` whose `Encoded` is XML text, so `Schema.encodeSync` writes a
3
+ * document and `Schema.decodeSync` reads one back, the way `Schema.toCodecJson` works for JSON. Attributes are the fields whose names start with `@`,
4
+ * so `@xmlns` is written as `xmlns="…"`, and `#text` holds an element's character data. A schema node annotated with `xmlNamespace` is placed in that
5
+ * namespace, and the codec resolves the document's own prefixes back to it. `renderXml` and `parseXml` are the text layer the codec runs underneath,
6
+ * and remain available on their own.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Schema } from 'effect';
11
+ * import { toCodecXml } from '@endevops/effect-xml-codec';
12
+ *
13
+ * const Book = Schema.Struct({
14
+ * '@id': Schema.String,
15
+ * title: Schema.String,
16
+ * tag: Schema.Array(Schema.String),
17
+ * });
18
+ *
19
+ * const codec = toCodecXml(Book, { rootName: 'book' });
20
+ * const value = { '@id': '1', title: 'Dune', tag: ['sci-fi'] };
21
+ *
22
+ * const text = Schema.encodeSync(codec)(value);
23
+ * // => '<book id="1"><title>Dune</title><tag>sci-fi</tag></book>'
24
+ *
25
+ * Schema.decodeSync(codec)(text); // => value
26
+ * ```;
27
+ *
28
+ * @packageDocumentation
29
+ */
30
+
31
+ export { toCodecXml } from './codec.ts';
32
+ export type { XmlCodecOptions } from './codec.ts';
33
+
34
+ export {
35
+ ATTRIBUTE_PREFIX,
36
+ DEFAULT_ITEM_NAME,
37
+ DEFAULT_ROOT_NAME,
38
+ TEXT_KEY,
39
+ attributeName,
40
+ isAttributeKey,
41
+ isReservedKey,
42
+ isTextKey,
43
+ resolveName,
44
+ } from './conventions.ts';
45
+ export type { NameMode, ResolveNameOptions } from './conventions.ts';
46
+
47
+ export { XmlParseError, XmlRenderError } from './errors.ts';
48
+
49
+ export { ATTRIBUTE_KEY, NAME_KEY, NAMESPACE_KEY, PREFIX_KEY, VALUE_KEY } from './namespaces.ts';
50
+ export type { NamespacePlan, XmlNamespace } from './namespaces.ts';
51
+
52
+ export { parseXml } from './parse.ts';
53
+ export type { XmlDocument, XmlParseOptions } from './parse.ts';
54
+
55
+ export { escapeAttribute, escapeText, renderXml } from './render.ts';
56
+ export type { XmlRenderOptions } from './render.ts';
57
+
58
+ export { XmlValue as XmlValueSchema, isXmlValue } from './xml-value.ts';
59
+ export type { XmlRecord, XmlValue } from './xml-value.ts';
60
+
61
+ // The primitives that were `@endevops/common-xml`. The entity decoder and the
62
+ // name validators moved in with the codec; the path matcher, the entity encoder
63
+ // and the HTML tables did not, because nothing in this package reaches them.
64
+ export { EntityDecoder, ENTITY_ACTION } from './entities/entity-decoder.ts';
65
+ export type {
66
+ ApplyLimitsTo,
67
+ EntityDecoderLimitOptions,
68
+ EntityDecoderNCROptions,
69
+ EntityDecoderOptions,
70
+ EntityHookAction,
71
+ EntityRegistrationHook,
72
+ EntityValFn,
73
+ } from './entities/entity-decoder.ts';
74
+
75
+ export { isName, isNcName, isNmToken, isNmTokens, isQName, sanitize, validate } from './naming.ts';
76
+ export type { Production, SanitizeOptions, ValidationOptions, ValidationResult, XmlVersion } from './naming.ts';
77
+
78
+ export { XmlError, XmlErrorReason } from './xml-error.ts';
79
+ export type { XmlErrorReason as XmlErrorReasonType } from './xml-error.ts';