@stxt-lang/core 0.5.2 → 0.6.0

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 (120) hide show
  1. package/README.md +116 -1
  2. package/out/all.d.ts +5 -0
  3. package/out/all.js +10 -4
  4. package/out/core/Constants.d.ts +8 -0
  5. package/out/core/Constants.js +8 -0
  6. package/out/core/Line.d.ts +20 -0
  7. package/out/core/Line.js +15 -0
  8. package/out/core/LineParser.d.ts +17 -0
  9. package/out/core/LineParser.js +27 -10
  10. package/out/core/NameNamespace.d.ts +9 -0
  11. package/out/core/NameNamespace.js +9 -0
  12. package/out/core/NameNamespaceParser.d.ts +11 -0
  13. package/out/core/NameNamespaceParser.js +16 -5
  14. package/out/core/NamespaceValidator.d.ts +18 -0
  15. package/out/core/NamespaceValidator.js +18 -0
  16. package/out/core/Node.d.ts +55 -0
  17. package/out/core/Node.js +56 -1
  18. package/out/core/NodeCreator.d.ts +11 -0
  19. package/out/core/NodeCreator.js +14 -3
  20. package/out/core/ParseResult.d.ts +26 -0
  21. package/out/core/ParseResult.js +26 -0
  22. package/out/core/Parser.d.ts +31 -0
  23. package/out/core/Parser.js +50 -19
  24. package/out/core/StringUtils.d.ts +31 -0
  25. package/out/core/StringUtils.js +40 -9
  26. package/out/discovery/DiscoveryEnvironment.d.ts +35 -0
  27. package/out/discovery/DiscoveryEnvironment.js +3 -0
  28. package/out/discovery/DiscoveryError.d.ts +30 -0
  29. package/out/discovery/DiscoveryError.js +36 -0
  30. package/out/discovery/DiscoveryFileSystem.d.ts +57 -0
  31. package/out/discovery/DiscoveryFileSystem.js +3 -0
  32. package/out/discovery/DiscoveryResolver.d.ts +74 -0
  33. package/out/discovery/DiscoveryResolver.js +232 -0
  34. package/out/discovery/DiscoveryResult.d.ts +94 -0
  35. package/out/discovery/DiscoveryResult.js +111 -0
  36. package/out/exceptions/ParseException.d.ts +14 -0
  37. package/out/exceptions/ParseException.js +12 -0
  38. package/out/exceptions/RuntimeException.d.ts +14 -0
  39. package/out/exceptions/RuntimeException.js +13 -0
  40. package/out/exceptions/ValidationException.d.ts +8 -0
  41. package/out/exceptions/ValidationException.js +8 -0
  42. package/out/processors/Observer.d.ts +29 -0
  43. package/out/processors/Validator.d.ts +9 -0
  44. package/out/runtime/ConditionalValidator.d.ts +15 -0
  45. package/out/runtime/ConditionalValidator.js +16 -2
  46. package/out/runtime/NodeWriter.d.ts +18 -0
  47. package/out/runtime/NodeWriter.js +18 -0
  48. package/out/runtime/UnifiedSchemaProvider.d.ts +23 -5
  49. package/out/runtime/UnifiedSchemaProvider.js +28 -10
  50. package/out/schema/ChildDefinition.d.ts +18 -0
  51. package/out/schema/ChildDefinition.js +18 -0
  52. package/out/schema/NodeDefinition.d.ts +44 -0
  53. package/out/schema/NodeDefinition.js +47 -3
  54. package/out/schema/Schema.d.ts +26 -0
  55. package/out/schema/Schema.js +26 -1
  56. package/out/schema/SchemaParser.d.ts +7 -0
  57. package/out/schema/SchemaParser.js +26 -16
  58. package/out/schema/SchemaProvider.d.ts +7 -0
  59. package/out/schema/SchemaProviderMemory.d.ts +27 -0
  60. package/out/schema/SchemaProviderMemory.js +27 -0
  61. package/out/schema/SchemaProviderMeta.d.ts +16 -0
  62. package/out/schema/SchemaProviderMeta.js +16 -0
  63. package/out/schema/SchemaValidator.d.ts +20 -0
  64. package/out/schema/SchemaValidator.js +27 -7
  65. package/out/schema/Type.d.ts +9 -0
  66. package/out/schema/TypeRegistry.d.ts +13 -0
  67. package/out/schema/TypeRegistry.js +18 -5
  68. package/out/schema/type/BASE64.d.ts +1 -0
  69. package/out/schema/type/BASE64.js +5 -4
  70. package/out/schema/type/BINARY.d.ts +1 -0
  71. package/out/schema/type/BINARY.js +2 -1
  72. package/out/schema/type/BLOCK.d.ts +1 -0
  73. package/out/schema/type/BLOCK.js +2 -1
  74. package/out/schema/type/BOOLEAN.d.ts +1 -0
  75. package/out/schema/type/BOOLEAN.js +1 -0
  76. package/out/schema/type/DATE.d.ts +1 -0
  77. package/out/schema/type/DATE.js +1 -0
  78. package/out/schema/type/EMAIL.d.ts +1 -0
  79. package/out/schema/type/EMAIL.js +1 -0
  80. package/out/schema/type/ENUM.d.ts +1 -0
  81. package/out/schema/type/ENUM.js +2 -1
  82. package/out/schema/type/GROUP.d.ts +1 -0
  83. package/out/schema/type/GROUP.js +2 -1
  84. package/out/schema/type/HEXADECIMAL.d.ts +1 -0
  85. package/out/schema/type/HEXADECIMAL.js +2 -1
  86. package/out/schema/type/INLINE.d.ts +1 -0
  87. package/out/schema/type/INLINE.js +2 -1
  88. package/out/schema/type/INTEGER.d.ts +1 -0
  89. package/out/schema/type/INTEGER.js +1 -0
  90. package/out/schema/type/MARKDOWN.d.ts +4 -0
  91. package/out/schema/type/MARKDOWN.js +4 -2
  92. package/out/schema/type/NATURAL.d.ts +1 -0
  93. package/out/schema/type/NATURAL.js +1 -0
  94. package/out/schema/type/NUMBER.d.ts +1 -0
  95. package/out/schema/type/NUMBER.js +1 -0
  96. package/out/schema/type/TEXT.d.ts +1 -0
  97. package/out/schema/type/TEXT.js +1 -0
  98. package/out/schema/type/TIME.d.ts +1 -0
  99. package/out/schema/type/TIME.js +1 -0
  100. package/out/schema/type/TIMESTAMP.d.ts +1 -0
  101. package/out/schema/type/TIMESTAMP.js +1 -0
  102. package/out/schema/type/URL.d.ts +1 -0
  103. package/out/schema/type/URL.js +2 -1
  104. package/out/schema/type/UUID.d.ts +1 -0
  105. package/out/schema/type/UUID.js +1 -0
  106. package/out/schema/type/binaryValue.d.ts +9 -0
  107. package/out/schema/type/binaryValue.js +9 -3
  108. package/out/schema/type/regexType.d.ts +8 -0
  109. package/out/schema/type/regexType.js +9 -1
  110. package/out/template/ChildLine.d.ts +14 -0
  111. package/out/template/ChildLine.js +14 -0
  112. package/out/template/ChildLineParser.d.ts +10 -0
  113. package/out/template/ChildLineParser.js +17 -8
  114. package/out/template/MetaTemplateSchemaProvider.d.ts +16 -0
  115. package/out/template/MetaTemplateSchemaProvider.js +17 -1
  116. package/out/template/TemplateParser.d.ts +8 -0
  117. package/out/template/TemplateParser.js +49 -39
  118. package/out/template/TemplateSchemaProviderMemory.d.ts +18 -0
  119. package/out/template/TemplateSchemaProviderMemory.js +21 -3
  120. package/package.json +2 -1
@@ -3,7 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeDefinition = void 0;
4
4
  const ValidationException_1 = require("../exceptions/ValidationException");
5
5
  const StringUtils_1 = require("../core/StringUtils");
6
+ /**
7
+ * Definition of a node inside a {@link Schema}: its name, its value type, the children it expects
8
+ * ({@link ChildDefinition}) and, for ENUM, the values it allows.
9
+ */
6
10
  class NodeDefinition {
11
+ /**
12
+ * Creates the definition of a node.
13
+ *
14
+ * @param name name of the node.
15
+ * @param type name of the type (see {@link TypeRegistry}).
16
+ * @param line line number, for the error message.
17
+ * @param description optional description of the node.
18
+ * @throws ValidationException with code `INVALID_NODE_NAME` if the name is not valid.
19
+ */
7
20
  constructor(name, type, line, description) {
8
21
  this.children = new Map();
9
22
  this.values = new Set();
@@ -15,24 +28,40 @@ class NodeDefinition {
15
28
  throw new ValidationException_1.ValidationException(line, "INVALID_NODE_NAME", `Node name not valid: ${name}`);
16
29
  }
17
30
  }
31
+ /** @returns the name of the node, as it appears in the schema. */
18
32
  getName() {
19
33
  return this.name;
20
34
  }
35
+ /** @returns the canonical name of the node. */
21
36
  getNormalizedName() {
22
37
  return this.normalizedName;
23
38
  }
39
+ /** @returns the name of the value type of this node (see {@link TypeRegistry}). */
24
40
  getType() {
25
41
  return this.type;
26
42
  }
43
+ /** @returns the definitions of the expected children, indexed by their qualified canonical name. */
27
44
  getChildren() {
28
45
  return this.children;
29
46
  }
47
+ /** @returns the optional description of the node, or undefined if it has none. */
30
48
  getDescription() {
31
49
  return this.description;
32
50
  }
51
+ /**
52
+ * Sets the optional description of the node.
53
+ *
54
+ * @param description new optional description of the node.
55
+ */
33
56
  setDescription(description) {
34
57
  this.description = description;
35
58
  }
59
+ /**
60
+ * Adds the definition of an expected child.
61
+ *
62
+ * @param childDefinition definition of the child to add.
63
+ * @throws ValidationException with code `CHILD_DEF_ALREADY_DEFINED` if a definition for that child already existed.
64
+ */
36
65
  addChildDefinition(childDefinition) {
37
66
  const qname = childDefinition.getQualifiedName();
38
67
  if (this.children.has(qname)) {
@@ -40,9 +69,16 @@ class NodeDefinition {
40
69
  }
41
70
  this.children.set(qname, childDefinition);
42
71
  }
43
- // STXT-SCHEMA-SPEC 13.9 / STXT-TEMPLATE-SPEC 14.14: no puede haber valores duplicados
44
- // tras la normalización por trim. Mismo código que ChildLineParser: es la misma condición
45
- // por la otra puerta de entrada.
72
+ // STXT-SCHEMA-SPEC 13.9 / STXT-TEMPLATE-SPEC 14.14: there can be no duplicated values
73
+ // after the trim normalization. Same code as ChildLineParser: it is the same condition
74
+ // coming through the other entry point.
75
+ /**
76
+ * Adds a value to the list of values allowed for this node.
77
+ *
78
+ * @param value value to add to the list of allowed values.
79
+ * @param line line number, for the error message.
80
+ * @throws ValidationException with code `VALUE_DUPLICATED` if the value (once trimmed) had already been added.
81
+ */
46
82
  addValue(value, line) {
47
83
  const trimmed = value?.trim() ?? "";
48
84
  if (this.values.has(trimmed)) {
@@ -50,15 +86,23 @@ class NodeDefinition {
50
86
  }
51
87
  this.values.add(trimmed);
52
88
  }
89
+ /**
90
+ * Tells whether a value is allowed for this node.
91
+ *
92
+ * @param value value to check.
93
+ * @returns true if no restricted values are defined, or if the value is among the allowed ones.
94
+ */
53
95
  isAllowedValue(value) {
54
96
  if (this.values.size === 0) {
55
97
  return true;
56
98
  }
57
99
  return this.values.has(value);
58
100
  }
101
+ /** @returns the values allowed for this node (ENUM), or empty if there is no restriction. */
59
102
  getValues() {
60
103
  return this.values;
61
104
  }
105
+ /** @returns a plain object with the definition, so that JSON.stringify serializes it. */
62
106
  toJSON() {
63
107
  return {
64
108
  name: this.getName(),
@@ -1,14 +1,39 @@
1
1
  import { NodeDefinition } from "./NodeDefinition";
2
+ /** Schema of a namespace: the set of {@link NodeDefinition} valid for the nodes of that namespace. */
2
3
  export declare class Schema {
4
+ /** Namespace of the schema language itself, `@stxt.schema`. */
3
5
  static readonly SCHEMA_NAMESPACE = "@stxt.schema";
4
6
  private readonly nodes;
5
7
  private readonly namespace;
6
8
  private readonly description;
9
+ /**
10
+ * Creates an empty schema for a namespace.
11
+ *
12
+ * @param namespace namespace this schema applies to.
13
+ * @param line line number, for the error message.
14
+ * @param description optional description of the schema.
15
+ * @throws ParseException if the namespace is not well formed.
16
+ */
7
17
  constructor(namespace: string | null | undefined, line: number, description: string | undefined);
18
+ /** @returns the node definitions, indexed by their canonical name. */
8
19
  getNodes(): ReadonlyMap<string, NodeDefinition>;
20
+ /**
21
+ * Looks up the definition of a node by name.
22
+ *
23
+ * @param name name of the node to look for.
24
+ * @returns the definition of the node with that name, or undefined if it is not defined in this schema.
25
+ */
9
26
  getNodeDefinition(name: string): NodeDefinition | undefined;
27
+ /**
28
+ * Adds the definition of a node to this schema.
29
+ *
30
+ * @param nodeDefinition node definition to add.
31
+ * @throws ValidationException with code `NODE_DEF_ALREADY_DEFINED` if there already was a node definition with the same name.
32
+ */
10
33
  addNodeDefinition(nodeDefinition: NodeDefinition): void;
34
+ /** @returns the namespace this schema applies to. */
11
35
  getNamespace(): string;
36
+ /** @returns a plain object with the schema, so that JSON.stringify serializes it. */
12
37
  toJSON(): {
13
38
  namespace: string;
14
39
  nodes: {
@@ -26,5 +51,6 @@ export declare class Schema {
26
51
  values: string[];
27
52
  }[];
28
53
  };
54
+ /** @returns the schema as pretty-printed JSON, for debugging. */
29
55
  toString(): string;
30
56
  }
@@ -4,19 +4,41 @@ exports.Schema = void 0;
4
4
  const NamespaceValidator_1 = require("../core/NamespaceValidator");
5
5
  const StringUtils_1 = require("../core/StringUtils");
6
6
  const ValidationException_1 = require("../exceptions/ValidationException");
7
+ /** Schema of a namespace: the set of {@link NodeDefinition} valid for the nodes of that namespace. */
7
8
  class Schema {
9
+ /**
10
+ * Creates an empty schema for a namespace.
11
+ *
12
+ * @param namespace namespace this schema applies to.
13
+ * @param line line number, for the error message.
14
+ * @param description optional description of the schema.
15
+ * @throws ParseException if the namespace is not well formed.
16
+ */
8
17
  constructor(namespace, line, description) {
9
18
  this.nodes = new Map();
10
19
  this.namespace = StringUtils_1.StringUtils.lowerCase(namespace);
11
20
  this.description = description;
12
21
  NamespaceValidator_1.NamespaceValidator.validateNamespaceFormat(this.namespace, line);
13
22
  }
23
+ /** @returns the node definitions, indexed by their canonical name. */
14
24
  getNodes() {
15
25
  return this.nodes;
16
26
  }
27
+ /**
28
+ * Looks up the definition of a node by name.
29
+ *
30
+ * @param name name of the node to look for.
31
+ * @returns the definition of the node with that name, or undefined if it is not defined in this schema.
32
+ */
17
33
  getNodeDefinition(name) {
18
34
  return this.nodes.get(StringUtils_1.StringUtils.normalize(name));
19
35
  }
36
+ /**
37
+ * Adds the definition of a node to this schema.
38
+ *
39
+ * @param nodeDefinition node definition to add.
40
+ * @throws ValidationException with code `NODE_DEF_ALREADY_DEFINED` if there already was a node definition with the same name.
41
+ */
20
42
  addNodeDefinition(nodeDefinition) {
21
43
  const qname = nodeDefinition.getNormalizedName();
22
44
  if (this.nodes.has(qname)) {
@@ -24,20 +46,23 @@ class Schema {
24
46
  }
25
47
  this.nodes.set(qname, nodeDefinition);
26
48
  }
49
+ /** @returns the namespace this schema applies to. */
27
50
  getNamespace() {
28
51
  return this.namespace;
29
52
  }
30
- // Dentro de la clase Schema
53
+ /** @returns a plain object with the schema, so that JSON.stringify serializes it. */
31
54
  toJSON() {
32
55
  return {
33
56
  namespace: this.namespace,
34
57
  nodes: Array.from(this.nodes.values()).map(n => n.toJSON()),
35
58
  };
36
59
  }
60
+ /** @returns the schema as pretty-printed JSON, for debugging. */
37
61
  toString() {
38
62
  return JSON.stringify(this, null, 2); // pretty print
39
63
  }
40
64
  }
41
65
  exports.Schema = Schema;
66
+ /** Namespace of the schema language itself, `@stxt.schema`. */
42
67
  Schema.SCHEMA_NAMESPACE = "@stxt.schema";
43
68
  //# sourceMappingURL=Schema.js.map
@@ -1,3 +1,10 @@
1
1
  import { Schema } from "./Schema";
2
2
  import { Node } from "../core/Node";
3
+ /**
4
+ * Turns the tree of an already parsed `@stxt.schema` document into a {@link Schema}.
5
+ *
6
+ * @param node root node of the schema document, `Schema (@stxt.schema): ...`.
7
+ * @returns the schema the document defines.
8
+ * @throws ValidationException if the document is not a valid `@stxt.schema` one.
9
+ */
3
10
  export declare function transformNodeToSchema(node: Node): Schema;
@@ -8,32 +8,39 @@ const ValidationException_1 = require("../exceptions/ValidationException");
8
8
  const RuntimeException_1 = require("../exceptions/RuntimeException");
9
9
  const NameNamespaceParser_1 = require("../core/NameNamespaceParser");
10
10
  const TypeRegistry_1 = require("./TypeRegistry");
11
+ /**
12
+ * Turns the tree of an already parsed `@stxt.schema` document into a {@link Schema}.
13
+ *
14
+ * @param node root node of the schema document, `Schema (@stxt.schema): ...`.
15
+ * @returns the schema the document defines.
16
+ * @throws ValidationException if the document is not a valid `@stxt.schema` one.
17
+ */
11
18
  function transformNodeToSchema(node) {
12
19
  // Node name
13
20
  const nodeName = node.getNormalizedName();
14
21
  const namespaceSchema = node.getNamespace();
15
- // Obtenemos name y namespace
22
+ // Get the name and the namespace
16
23
  if (nodeName !== "schema" || namespaceSchema !== Schema_1.Schema.SCHEMA_NAMESPACE) {
17
- throw new ValidationException_1.ValidationException(node.getLine(), "NOT_STXT_SCHEMA", `Se espera schema(${Schema_1.Schema.SCHEMA_NAMESPACE}) y es ${nodeName}(${namespaceSchema})`);
24
+ throw new ValidationException_1.ValidationException(node.getLine(), "NOT_STXT_SCHEMA", `Expected schema(${Schema_1.Schema.SCHEMA_NAMESPACE}) but got ${nodeName}(${namespaceSchema})`);
18
25
  }
19
- // Obtenemos description
26
+ // Get the description
20
27
  const descrip = node.getChild("description")?.getText();
21
28
  const schema = new Schema_1.Schema(node.getValue(), node.getLine(), descrip);
22
- // Para validar
23
- const allNames = new Set(); // Para validar que existan los childs
24
- // Obtenemos los nodos
29
+ // Used to check that every child is defined
30
+ const allNames = new Set();
31
+ // Get the nodes
25
32
  for (const n of node.getChildrenByName("node")) {
26
33
  const schNode = createFrom(n, schema.getNamespace());
27
34
  schema.addNodeDefinition(schNode);
28
35
  allNames.add(schNode.getNormalizedName());
29
36
  }
30
- // Validamos que todos los nombres estén definidos
37
+ // Check that every name is defined
31
38
  for (const schNode of schema.getNodes().values()) {
32
39
  for (const schChild of schNode.getChildren().values()) {
33
- // Sólo validamos del mismo namespace
40
+ // Only names of the same namespace are checked
34
41
  if (schChild.getNamespace() === schema.getNamespace()) {
35
- // Ojo: en Java aquí se usa schChild.getNormalizedName(), pero ChildDefinition no lo expone.
36
- // Para mantener el comportamiento, se recomienda añadir getNormalizedName() a ChildDefinition.
42
+ // Defensive leftover from the Java port: ChildDefinition does expose
43
+ // getNormalizedName(), so this check can never fail with the current class.
37
44
  const childNorm = schChild.getNormalizedName?.();
38
45
  if (!childNorm) {
39
46
  throw new RuntimeException_1.RuntimeException("CHILD_DEFINITION_API_MISMATCH", "ChildDefinition.getNormalizedName() is missing in TypeScript version. Add it to ChildDefinition.");
@@ -46,6 +53,7 @@ function transformNodeToSchema(node) {
46
53
  }
47
54
  return schema;
48
55
  }
56
+ /** Builds the definition of a node from a `Node:` entry of the schema document. */
49
57
  function createFrom(n, namespace) {
50
58
  const name = n.getValue();
51
59
  let type = "INLINE";
@@ -57,7 +65,7 @@ function createFrom(n, namespace) {
57
65
  const result = new NodeDefinition_1.NodeDefinition(name, type, n.getLine(), description);
58
66
  const children = n.getChild("children");
59
67
  if (children) {
60
- // Error de schema 13.5: Children en un Node cuyo tipo no admite hijos
68
+ // Schema error 13.5: Children in a Node whose type does not admit children
61
69
  if (!TypeRegistry_1.TypeRegistry.admitsChildren(type)) {
62
70
  throw new ValidationException_1.ValidationException(children.getLine(), "CHILDREN_NOT_ALLOWED_FOR_TYPE", `Type ${type} does not allow children (node ${name})`);
63
71
  }
@@ -65,7 +73,7 @@ function createFrom(n, namespace) {
65
73
  putChildToSchemaNode(result, child, namespace);
66
74
  }
67
75
  }
68
- // Miramos values
76
+ // Look at the values
69
77
  let valuesNodes = n.getChildrenByName("values");
70
78
  if (valuesNodes && valuesNodes.length > 0) {
71
79
  if (type !== "ENUM") {
@@ -79,29 +87,31 @@ function createFrom(n, namespace) {
79
87
  for (const v of values) {
80
88
  result.addValue(v.getValue(), v.getLine());
81
89
  }
82
- // Para la comprobación final de ENUM
90
+ // For the final ENUM check
83
91
  valuesNodes = values;
84
92
  }
85
- // Miramos enum
93
+ // Look at the enum
86
94
  if (type === "ENUM" && (!valuesNodes || valuesNodes.length === 0)) {
87
95
  throw new ValidationException_1.ValidationException(n.getLine(), "VALUES_EMPTY_FOR_ENUM", "ENUM Type must include values");
88
96
  }
89
97
  return result;
90
98
  }
99
+ /** Adds to a node definition the expected child a `Child:` entry declares. */
91
100
  function putChildToSchemaNode(schemaNode, child, defNamespace) {
92
- // Obtenemos name y namespace
101
+ // Get the name and the namespace
93
102
  const ns = NameNamespaceParser_1.NameNamespaceParser.parse(child.getValue(), defNamespace, child.getLine(), child.getValue());
94
103
  const name = ns.getName();
95
104
  const namespace = ns.getNamespace();
96
105
  const min = getInteger(child, "min");
97
106
  const max = getInteger(child, "max");
98
- // Cardinalidad inválida si Min > Max (STXT-SCHEMA-SPEC 10 y 13.7)
107
+ // Invalid cardinality when Min > Max (STXT-SCHEMA-SPEC 10 and 13.7)
99
108
  if (min !== null && max !== null && min > max) {
100
109
  throw new ValidationException_1.ValidationException(child.getLine(), "MIN_GREATER_THAN_MAX", `Min ${min} greater than Max ${max}`);
101
110
  }
102
111
  const schemaChild = new ChildDefinition_1.ChildDefinition(name, namespace, min, max, child.getLine());
103
112
  schemaNode.addChildDefinition(schemaChild);
104
113
  }
114
+ /** Reads an integer child (`Min`, `Max`) of a node, or null when it is not there. */
105
115
  function getInteger(node, name) {
106
116
  const n = node.getChild(name);
107
117
  if (!n) {
@@ -1,4 +1,11 @@
1
1
  import { Schema } from "./Schema";
2
+ /** Resolves the {@link Schema} that applies to a namespace. Composable implementations (memory, meta-schema...). */
2
3
  export interface SchemaProvider {
4
+ /**
5
+ * Resolves the schema that applies to a namespace.
6
+ *
7
+ * @param namespace namespace whose schema is wanted.
8
+ * @returns the schema of the namespace, or null/undefined if there is none for that namespace.
9
+ */
3
10
  getSchema(namespace: string): Schema | null | undefined;
4
11
  }
@@ -1,11 +1,38 @@
1
1
  import { Schema } from "./Schema";
2
2
  import { SchemaProvider } from "./SchemaProvider";
3
+ /**
4
+ * In-memory {@link SchemaProvider}: it keeps the schemas added with {@link SchemaProviderMemory.addSchema}
5
+ * indexed by namespace, and falls back to a parent provider (the meta-schema by default) for the
6
+ * namespaces it does not know.
7
+ */
3
8
  export declare class SchemaProviderMemory implements SchemaProvider {
4
9
  private readonly parentSchema;
10
+ /**
11
+ * Creates an empty provider.
12
+ *
13
+ * @param parent provider to fall back to when a namespace is not registered here; the
14
+ * meta-schema provider when omitted.
15
+ */
5
16
  constructor(parent?: SchemaProvider | null | undefined);
6
17
  protected readonly schemas: Map<string, Schema>;
18
+ /**
19
+ * Resolves the schema that applies to a namespace, delegating to the parent provider when it
20
+ * is not registered here.
21
+ *
22
+ * @param namespace namespace whose schema is wanted.
23
+ * @returns the schema of the namespace, or null/undefined if neither this provider nor its parent has one.
24
+ */
7
25
  getSchema(namespace: string): Schema | undefined | null;
26
+ /**
27
+ * Parses a schema document, validates it against the meta-schema and registers it under its
28
+ * own namespace.
29
+ *
30
+ * @param txt text of the `@stxt.schema` document.
31
+ * @throws ParseException or ValidationException if the document is not a valid schema.
32
+ */
8
33
  addSchema(txt: string): void;
34
+ /** Removes every schema registered in this provider (the parent one is left untouched). */
9
35
  clear(): void;
36
+ /** @returns every schema registered in this provider, in registration order. */
10
37
  getAllSchemas(): ReadonlyArray<Schema>;
11
38
  }
@@ -6,7 +6,18 @@ const StringUtils_1 = require("../core/StringUtils");
6
6
  const SchemaParser_1 = require("./SchemaParser");
7
7
  const SchemaProviderMeta_1 = require("./SchemaProviderMeta");
8
8
  const SchemaValidator_1 = require("./SchemaValidator");
9
+ /**
10
+ * In-memory {@link SchemaProvider}: it keeps the schemas added with {@link SchemaProviderMemory.addSchema}
11
+ * indexed by namespace, and falls back to a parent provider (the meta-schema by default) for the
12
+ * namespaces it does not know.
13
+ */
9
14
  class SchemaProviderMemory {
15
+ /**
16
+ * Creates an empty provider.
17
+ *
18
+ * @param parent provider to fall back to when a namespace is not registered here; the
19
+ * meta-schema provider when omitted.
20
+ */
10
21
  constructor(parent) {
11
22
  this.schemas = new Map();
12
23
  if (!parent) {
@@ -16,6 +27,13 @@ class SchemaProviderMemory {
16
27
  this.parentSchema = parent;
17
28
  }
18
29
  }
30
+ /**
31
+ * Resolves the schema that applies to a namespace, delegating to the parent provider when it
32
+ * is not registered here.
33
+ *
34
+ * @param namespace namespace whose schema is wanted.
35
+ * @returns the schema of the namespace, or null/undefined if neither this provider nor its parent has one.
36
+ */
19
37
  getSchema(namespace) {
20
38
  const key = StringUtils_1.StringUtils.lowerCase(namespace);
21
39
  let result = this.schemas.get(key);
@@ -24,6 +42,13 @@ class SchemaProviderMemory {
24
42
  }
25
43
  return result;
26
44
  }
45
+ /**
46
+ * Parses a schema document, validates it against the meta-schema and registers it under its
47
+ * own namespace.
48
+ *
49
+ * @param txt text of the `@stxt.schema` document.
50
+ * @throws ParseException or ValidationException if the document is not a valid schema.
51
+ */
27
52
  addSchema(txt) {
28
53
  const parser = new Parser_1.Parser();
29
54
  const node = parser.parse(txt)[0];
@@ -33,9 +58,11 @@ class SchemaProviderMemory {
33
58
  const key = schema.getNamespace();
34
59
  this.schemas.set(key, schema);
35
60
  }
61
+ /** Removes every schema registered in this provider (the parent one is left untouched). */
36
62
  clear() {
37
63
  this.schemas.clear();
38
64
  }
65
+ /** @returns every schema registered in this provider, in registration order. */
39
66
  getAllSchemas() {
40
67
  return Array.from(this.schemas.values());
41
68
  }
@@ -1,8 +1,24 @@
1
1
  import { Schema } from "./Schema";
2
2
  import { SchemaProvider } from "./SchemaProvider";
3
+ /**
4
+ * {@link SchemaProvider} that defines in code the meta-schema of the schema language itself
5
+ * (`@stxt.schema`), so that a loaded schema can validate itself.
6
+ */
3
7
  export declare class SchemaProviderMeta implements SchemaProvider {
4
8
  private static readonly META_TEXT;
5
9
  private readonly meta;
10
+ /**
11
+ * Parses the meta-schema and keeps it ready to be served.
12
+ *
13
+ * @throws ValidationException with code `META_SCHEMA_INVALID` if the meta-schema does not produce exactly one document.
14
+ */
6
15
  constructor();
16
+ /**
17
+ * Serves the meta-schema of the schema language.
18
+ *
19
+ * @param namespace namespace whose schema is wanted; only `@stxt.schema` is served.
20
+ * @returns the meta-schema of the schema language.
21
+ * @throws RuntimeException with code `RESOURCE_NOT_FOUND` if any other namespace is asked for.
22
+ */
7
23
  getSchema(namespace: string): Schema;
8
24
  }
@@ -6,7 +6,16 @@ const Parser_1 = require("../core/Parser");
6
6
  const ValidationException_1 = require("../exceptions/ValidationException");
7
7
  const RuntimeException_1 = require("../exceptions/RuntimeException");
8
8
  const SchemaParser_1 = require("./SchemaParser");
9
+ /**
10
+ * {@link SchemaProvider} that defines in code the meta-schema of the schema language itself
11
+ * (`@stxt.schema`), so that a loaded schema can validate itself.
12
+ */
9
13
  class SchemaProviderMeta {
14
+ /**
15
+ * Parses the meta-schema and keeps it ready to be served.
16
+ *
17
+ * @throws ValidationException with code `META_SCHEMA_INVALID` if the meta-schema does not produce exactly one document.
18
+ */
10
19
  constructor() {
11
20
  const parser = new Parser_1.Parser();
12
21
  const nodes = parser.parse(SchemaProviderMeta.META_TEXT);
@@ -15,6 +24,13 @@ class SchemaProviderMeta {
15
24
  }
16
25
  this.meta = (0, SchemaParser_1.transformNodeToSchema)(nodes[0]);
17
26
  }
27
+ /**
28
+ * Serves the meta-schema of the schema language.
29
+ *
30
+ * @param namespace namespace whose schema is wanted; only `@stxt.schema` is served.
31
+ * @returns the meta-schema of the schema language.
32
+ * @throws RuntimeException with code `RESOURCE_NOT_FOUND` if any other namespace is asked for.
33
+ */
18
34
  getSchema(namespace) {
19
35
  if (namespace !== Schema_1.Schema.SCHEMA_NAMESPACE) {
20
36
  throw new RuntimeException_1.RuntimeException("RESOURCE_NOT_FOUND", `Not found '${namespace}' in namespace: ${Schema_1.Schema.SCHEMA_NAMESPACE}`);
@@ -3,11 +3,31 @@ import { ValidationException } from "../exceptions/ValidationException";
3
3
  import { Validator } from "../processors/Validator";
4
4
  import { SchemaProvider } from "./SchemaProvider";
5
5
  import { Schema } from "./Schema";
6
+ /** {@link Validator} that, for each node, resolves its {@link Schema} through a {@link SchemaProvider} and validates type and cardinality. */
6
7
  export declare class SchemaValidator implements Validator {
7
8
  private readonly schemaProvider;
8
9
  private readonly recursiveValidation;
10
+ /**
11
+ * Creates a validator that resolves schemas through the given provider.
12
+ *
13
+ * @param schemaProvider where to resolve the schema of each namespace from.
14
+ * @param recursive whether the children of each node are validated recursively too.
15
+ */
9
16
  constructor(schemaProvider: SchemaProvider, recursive?: boolean);
17
+ /**
18
+ * Validates a node against the schema of its namespace.
19
+ *
20
+ * @param node already closed node to validate.
21
+ * @returns the validation errors found, or an empty array if the node is valid.
22
+ */
10
23
  validate(node: Node): ValidationException[];
24
+ /**
25
+ * Validates a node against an already resolved schema: existence, value type and cardinalities of its children.
26
+ *
27
+ * @param node node to validate.
28
+ * @param schema schema to validate against.
29
+ * @returns the validation errors found, empty if the node is valid.
30
+ */
11
31
  validateAgainstSchema(node: Node, schema: Schema): ValidationException[];
12
32
  private static validateChildrenDeclared;
13
33
  private static validateValue;
@@ -3,23 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaValidator = void 0;
4
4
  const ValidationException_1 = require("../exceptions/ValidationException");
5
5
  const TypeRegistry_1 = require("./TypeRegistry");
6
+ /** {@link Validator} that, for each node, resolves its {@link Schema} through a {@link SchemaProvider} and validates type and cardinality. */
6
7
  class SchemaValidator {
8
+ /**
9
+ * Creates a validator that resolves schemas through the given provider.
10
+ *
11
+ * @param schemaProvider where to resolve the schema of each namespace from.
12
+ * @param recursive whether the children of each node are validated recursively too.
13
+ */
7
14
  constructor(schemaProvider, recursive = false) {
8
15
  this.schemaProvider = schemaProvider;
9
16
  this.recursiveValidation = recursive;
10
17
  }
18
+ /**
19
+ * Validates a node against the schema of its namespace.
20
+ *
21
+ * @param node already closed node to validate.
22
+ * @returns the validation errors found, or an empty array if the node is valid.
23
+ */
11
24
  validate(node) {
12
25
  const errors = [];
13
- // Obtenemos namespace
26
+ // Get the namespace
14
27
  const namespace = node.getNamespace();
15
28
  const schema = this.schemaProvider.getSchema(namespace);
16
29
  if (!schema) {
17
30
  errors.push(new ValidationException_1.ValidationException(node.getLine(), "SCHEMA_NOT_FOUND", `Not found schema: ${namespace}`));
18
31
  return errors;
19
32
  }
20
- // Validamos nodo
33
+ // Validate the node
21
34
  errors.push(...this.validateAgainstSchema(node, schema));
22
- // Validamos children
35
+ // Validate the children
23
36
  if (this.recursiveValidation) {
24
37
  for (const childNode of node.getChildren()) {
25
38
  errors.push(...this.validate(childNode));
@@ -27,6 +40,13 @@ class SchemaValidator {
27
40
  }
28
41
  return errors;
29
42
  }
43
+ /**
44
+ * Validates a node against an already resolved schema: existence, value type and cardinalities of its children.
45
+ *
46
+ * @param node node to validate.
47
+ * @param schema schema to validate against.
48
+ * @returns the validation errors found, empty if the node is valid.
49
+ */
30
50
  validateAgainstSchema(node, schema) {
31
51
  const errors = [];
32
52
  const schemaNode = schema.getNodeDefinition(node.getNormalizedName());
@@ -40,8 +60,8 @@ class SchemaValidator {
40
60
  errors.push(...SchemaValidator.validateCount(schemaNode, node));
41
61
  return errors;
42
62
  }
43
- // Modelo de contenido cerrado (STXT-SCHEMA-SPEC, sección 6): solo se permiten
44
- // los hijos directos declarados en la definición del padre; sin Children, cierre total
63
+ // Closed content model (STXT-SCHEMA-SPEC, section 6): only the direct children declared
64
+ // in the definition of the parent are allowed; with no Children, nothing is
45
65
  static validateChildrenDeclared(nodeDef, node) {
46
66
  const errors = [];
47
67
  for (const child of node.getChildren()) {
@@ -101,9 +121,9 @@ class SchemaValidator {
101
121
  errors.push(new ValidationException_1.ValidationException(node.getLine(), "INVALID_NUMBER", `${childCount} nodes of '${childDef.getQualifiedName()}' and min is ${min}`));
102
122
  }
103
123
  if (max !== null && childCount > max) {
104
- // Error en el parent
124
+ // Error on the parent
105
125
  errors.push(new ValidationException_1.ValidationException(node.getLine(), "INVALID_NUMBER", `${childCount} nodes of '${childDef.getQualifiedName()}' and max is ${max}`));
106
- // Error en cada nodo hijo que excede el máximo permitido
126
+ // Error on each child node beyond the allowed maximum
107
127
  for (const child of children) {
108
128
  errors.push(new ValidationException_1.ValidationException(child.getLine(), "INVALID_NUMBER", `Too many '${childDef.getQualifiedName()}' nodes: found ${childCount}, max is ${max}`));
109
129
  }
@@ -1,6 +1,15 @@
1
1
  import { Node } from "../core/Node";
2
2
  import { NodeDefinition } from "./NodeDefinition";
3
+ /** Value type of a node (TEXT, INTEGER, URL...). Each type lives in `src/schema/type` as a singleton. */
3
4
  export interface Type {
5
+ /**
6
+ * Validates the value of a node against this type.
7
+ *
8
+ * @param nodeDef definition of the node in the schema.
9
+ * @param node node to validate.
10
+ * @throws ValidationException if the value of the node does not match the type.
11
+ */
4
12
  validate(nodeDef: NodeDefinition, node: Node): void;
13
+ /** @returns the name of the type, as used in the schemas (e.g. `"TEXT"`). */
5
14
  getName(): string;
6
15
  }
@@ -1,8 +1,21 @@
1
1
  import { Type } from "./Type";
2
+ /** Static registry of the STXT value types, indexed by name. Adding a new type: a new {@link Type} + `register(...)` here. */
2
3
  export declare class TypeRegistry {
3
4
  private static readonly REGISTRY;
4
5
  private static readonly _init;
6
+ /**
7
+ * Tells whether nodes of a type may have children.
8
+ *
9
+ * @param nodeType name of the type.
10
+ * @returns true if nodes of this type may have children (only INLINE and GROUP).
11
+ */
5
12
  static admitsChildren(nodeType: string): boolean;
13
+ /**
14
+ * Looks up a registered type by name.
15
+ *
16
+ * @param nodeType name of the type to look for.
17
+ * @returns the {@link Type} registered under that name, or undefined if it does not exist.
18
+ */
6
19
  static get(nodeType: string): Type | undefined;
7
20
  private static register;
8
21
  }