@stxt-lang/core 0.5.2 → 0.5.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.
Files changed (109) hide show
  1. package/README.md +1 -0
  2. package/out/all.js +3 -3
  3. package/out/core/Constants.d.ts +8 -0
  4. package/out/core/Constants.js +8 -0
  5. package/out/core/Line.d.ts +20 -0
  6. package/out/core/Line.js +15 -0
  7. package/out/core/LineParser.d.ts +17 -0
  8. package/out/core/LineParser.js +27 -10
  9. package/out/core/NameNamespace.d.ts +9 -0
  10. package/out/core/NameNamespace.js +9 -0
  11. package/out/core/NameNamespaceParser.d.ts +11 -0
  12. package/out/core/NameNamespaceParser.js +16 -5
  13. package/out/core/NamespaceValidator.d.ts +18 -0
  14. package/out/core/NamespaceValidator.js +18 -0
  15. package/out/core/Node.d.ts +55 -0
  16. package/out/core/Node.js +56 -1
  17. package/out/core/NodeCreator.d.ts +11 -0
  18. package/out/core/NodeCreator.js +14 -3
  19. package/out/core/ParseResult.d.ts +26 -0
  20. package/out/core/ParseResult.js +26 -0
  21. package/out/core/Parser.d.ts +31 -0
  22. package/out/core/Parser.js +50 -19
  23. package/out/core/StringUtils.d.ts +31 -0
  24. package/out/core/StringUtils.js +40 -9
  25. package/out/exceptions/ParseException.d.ts +14 -0
  26. package/out/exceptions/ParseException.js +12 -0
  27. package/out/exceptions/RuntimeException.d.ts +14 -0
  28. package/out/exceptions/RuntimeException.js +13 -0
  29. package/out/exceptions/ValidationException.d.ts +8 -0
  30. package/out/exceptions/ValidationException.js +8 -0
  31. package/out/processors/Observer.d.ts +29 -0
  32. package/out/processors/Validator.d.ts +9 -0
  33. package/out/runtime/ConditionalValidator.d.ts +15 -0
  34. package/out/runtime/ConditionalValidator.js +16 -2
  35. package/out/runtime/NodeWriter.d.ts +18 -0
  36. package/out/runtime/NodeWriter.js +18 -0
  37. package/out/runtime/UnifiedSchemaProvider.d.ts +23 -5
  38. package/out/runtime/UnifiedSchemaProvider.js +28 -10
  39. package/out/schema/ChildDefinition.d.ts +18 -0
  40. package/out/schema/ChildDefinition.js +18 -0
  41. package/out/schema/NodeDefinition.d.ts +44 -0
  42. package/out/schema/NodeDefinition.js +47 -3
  43. package/out/schema/Schema.d.ts +26 -0
  44. package/out/schema/Schema.js +26 -1
  45. package/out/schema/SchemaParser.d.ts +7 -0
  46. package/out/schema/SchemaParser.js +26 -16
  47. package/out/schema/SchemaProvider.d.ts +7 -0
  48. package/out/schema/SchemaProviderMemory.d.ts +27 -0
  49. package/out/schema/SchemaProviderMemory.js +27 -0
  50. package/out/schema/SchemaProviderMeta.d.ts +16 -0
  51. package/out/schema/SchemaProviderMeta.js +16 -0
  52. package/out/schema/SchemaValidator.d.ts +20 -0
  53. package/out/schema/SchemaValidator.js +27 -7
  54. package/out/schema/Type.d.ts +9 -0
  55. package/out/schema/TypeRegistry.d.ts +13 -0
  56. package/out/schema/TypeRegistry.js +18 -5
  57. package/out/schema/type/BASE64.d.ts +1 -0
  58. package/out/schema/type/BASE64.js +5 -4
  59. package/out/schema/type/BINARY.d.ts +1 -0
  60. package/out/schema/type/BINARY.js +2 -1
  61. package/out/schema/type/BLOCK.d.ts +1 -0
  62. package/out/schema/type/BLOCK.js +2 -1
  63. package/out/schema/type/BOOLEAN.d.ts +1 -0
  64. package/out/schema/type/BOOLEAN.js +1 -0
  65. package/out/schema/type/DATE.d.ts +1 -0
  66. package/out/schema/type/DATE.js +1 -0
  67. package/out/schema/type/EMAIL.d.ts +1 -0
  68. package/out/schema/type/EMAIL.js +1 -0
  69. package/out/schema/type/ENUM.d.ts +1 -0
  70. package/out/schema/type/ENUM.js +2 -1
  71. package/out/schema/type/GROUP.d.ts +1 -0
  72. package/out/schema/type/GROUP.js +2 -1
  73. package/out/schema/type/HEXADECIMAL.d.ts +1 -0
  74. package/out/schema/type/HEXADECIMAL.js +2 -1
  75. package/out/schema/type/INLINE.d.ts +1 -0
  76. package/out/schema/type/INLINE.js +2 -1
  77. package/out/schema/type/INTEGER.d.ts +1 -0
  78. package/out/schema/type/INTEGER.js +1 -0
  79. package/out/schema/type/MARKDOWN.d.ts +4 -0
  80. package/out/schema/type/MARKDOWN.js +4 -2
  81. package/out/schema/type/NATURAL.d.ts +1 -0
  82. package/out/schema/type/NATURAL.js +1 -0
  83. package/out/schema/type/NUMBER.d.ts +1 -0
  84. package/out/schema/type/NUMBER.js +1 -0
  85. package/out/schema/type/TEXT.d.ts +1 -0
  86. package/out/schema/type/TEXT.js +1 -0
  87. package/out/schema/type/TIME.d.ts +1 -0
  88. package/out/schema/type/TIME.js +1 -0
  89. package/out/schema/type/TIMESTAMP.d.ts +1 -0
  90. package/out/schema/type/TIMESTAMP.js +1 -0
  91. package/out/schema/type/URL.d.ts +1 -0
  92. package/out/schema/type/URL.js +2 -1
  93. package/out/schema/type/UUID.d.ts +1 -0
  94. package/out/schema/type/UUID.js +1 -0
  95. package/out/schema/type/binaryValue.d.ts +9 -0
  96. package/out/schema/type/binaryValue.js +9 -3
  97. package/out/schema/type/regexType.d.ts +8 -0
  98. package/out/schema/type/regexType.js +9 -1
  99. package/out/template/ChildLine.d.ts +14 -0
  100. package/out/template/ChildLine.js +14 -0
  101. package/out/template/ChildLineParser.d.ts +10 -0
  102. package/out/template/ChildLineParser.js +17 -8
  103. package/out/template/MetaTemplateSchemaProvider.d.ts +16 -0
  104. package/out/template/MetaTemplateSchemaProvider.js +17 -1
  105. package/out/template/TemplateParser.d.ts +8 -0
  106. package/out/template/TemplateParser.js +49 -39
  107. package/out/template/TemplateSchemaProviderMemory.d.ts +18 -0
  108. package/out/template/TemplateSchemaProviderMemory.js +21 -3
  109. package/package.json +1 -1
@@ -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
  }
@@ -21,13 +21,26 @@ const BASE64_1 = require("./type/BASE64");
21
21
  const GROUP_1 = require("./type/GROUP");
22
22
  const ENUM_1 = require("./type/ENUM");
23
23
  const MARKDOWN_1 = require("./type/MARKDOWN");
24
+ /** Static registry of the STXT value types, indexed by name. Adding a new type: a new {@link Type} + `register(...)` here. */
24
25
  class TypeRegistry {
25
- // STXT-SCHEMA-SPEC 9 / STXT-TEMPLATE-SPEC 15: sólo INLINE y GROUP admiten hijos
26
+ // STXT-SCHEMA-SPEC 9 / STXT-TEMPLATE-SPEC 15: only INLINE and GROUP admit children
27
+ /**
28
+ * Tells whether nodes of a type may have children.
29
+ *
30
+ * @param nodeType name of the type.
31
+ * @returns true if nodes of this type may have children (only INLINE and GROUP).
32
+ */
26
33
  static admitsChildren(nodeType) {
27
34
  return nodeType === "INLINE" || nodeType === "GROUP";
28
35
  }
36
+ /**
37
+ * Looks up a registered type by name.
38
+ *
39
+ * @param nodeType name of the type to look for.
40
+ * @returns the {@link Type} registered under that name, or undefined if it does not exist.
41
+ */
29
42
  static get(nodeType) {
30
- // fuerza que se ejecute _init al cargar la clase (por si el bundler hiciera cosas raras)
43
+ // force _init to run when the class is loaded (in case a bundler does something odd)
31
44
  void this._init;
32
45
  return this.REGISTRY.get(nodeType);
33
46
  }
@@ -41,12 +54,12 @@ class TypeRegistry {
41
54
  }
42
55
  exports.TypeRegistry = TypeRegistry;
43
56
  TypeRegistry.REGISTRY = new Map();
44
- // Inicialización estática (sin INSTANCE)
57
+ // Static initialization (no INSTANCE)
45
58
  TypeRegistry._init = (() => {
46
- // Tipos principales
59
+ // Main types
47
60
  TypeRegistry.register(INLINE_1.INLINE);
48
61
  TypeRegistry.register(BLOCK_1.BLOCK);
49
- // Subtipos
62
+ // Subtypes
50
63
  TypeRegistry.register(TEXT_1.TEXT);
51
64
  TypeRegistry.register(BOOLEAN_1.BOOLEAN);
52
65
  TypeRegistry.register(URL_1.URL);
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `BASE64` type: checks that the content is valid Base64. */
2
3
  export declare const BASE64: Type;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BASE64 = void 0;
4
4
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
5
  const binaryValue_1 = require("./binaryValue");
6
+ /** `BASE64` type: checks that the content is valid Base64. */
6
7
  exports.BASE64 = {
7
8
  getName() {
8
9
  return "BASE64";
@@ -10,12 +11,12 @@ exports.BASE64 = {
10
11
  validate(ndef, n) {
11
12
  const raw = (0, binaryValue_1.binaryValue)(n);
12
13
  try {
13
- // Intentamos decodificar
14
+ // Try to decode it
14
15
  const buf = Buffer.from(raw, "base64");
15
- // Re-encode para verificar consistencia
16
- // (evita aceptar cadenas parcialmente válidas)
16
+ // Re-encode to check consistency
17
+ // (this keeps partially valid strings out)
17
18
  const reencoded = buf.toString("base64");
18
- // Normalizamos padding para comparar
19
+ // Normalize the padding before comparing
19
20
  const normalizedInput = raw.replace(/=+$/, "");
20
21
  const normalizedReencoded = reencoded.replace(/=+$/, "");
21
22
  if (normalizedInput !== normalizedReencoded) {
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `BINARY` type: checks that the content is a string of zeros and ones (`[01]+`). */
2
3
  export declare const BINARY: Type;
@@ -3,11 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BINARY = void 0;
4
4
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
5
  const binaryValue_1 = require("./binaryValue");
6
+ /** `BINARY` type: checks that the content is a string of zeros and ones (`[01]+`). */
6
7
  exports.BINARY = {
7
8
  getName() {
8
9
  return "BINARY";
9
10
  },
10
- // STXT-SCHEMA-SPEC 9.5: cadena [01]+
11
+ // STXT-SCHEMA-SPEC 9.5: [01]+ string
11
12
  validate(ndef, n) {
12
13
  const value = (0, binaryValue_1.binaryValue)(n);
13
14
  if (!/^[01]+$/.test(value)) {
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `BLOCK` type: text block node (`>>`), with no further restriction on the content. */
2
3
  export declare const BLOCK: Type;
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BLOCK = void 0;
4
4
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
+ /** `BLOCK` type: text block node (`>>`), with no further restriction on the content. */
5
6
  exports.BLOCK = {
6
7
  getName() {
7
8
  return "BLOCK";
8
9
  },
9
10
  validate(nodeDef, node) {
10
- // Forma del valor BLOCK (STXT-SCHEMA-SPEC 9.2): sólo bloque '>>', no forma inline
11
+ // BLOCK value form (STXT-SCHEMA-SPEC 9.2): block '>>' only, no inline form
11
12
  if (!node.isTextNode()) {
12
13
  throw new ValidationException_1.ValidationException(node.getLine(), "BLOCK_FORM_REQUIRED", `Node ${node.getQualifiedName()} requires block form '>>'`);
13
14
  }
@@ -1 +1,2 @@
1
+ /** `BOOLEAN` type: checks that the value is `true` or `false`. */
1
2
  export declare const BOOLEAN: import("../Type").Type;
@@ -2,5 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BOOLEAN = void 0;
4
4
  const regexType_1 = require("./regexType");
5
+ /** `BOOLEAN` type: checks that the value is `true` or `false`. */
5
6
  exports.BOOLEAN = (0, regexType_1.regexType)("BOOLEAN", /^(true|false)$/, "Invalid boolean");
6
7
  //# sourceMappingURL=BOOLEAN.js.map
@@ -1 +1,2 @@
1
+ /** `DATE` type: checks the `YYYY-MM-DD` format. */
1
2
  export declare const DATE: import("../Type").Type;
@@ -2,5 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DATE = void 0;
4
4
  const regexType_1 = require("./regexType");
5
+ /** `DATE` type: checks the `YYYY-MM-DD` format. */
5
6
  exports.DATE = (0, regexType_1.regexType)("DATE", /^\d{4}-\d{2}-\d{2}$/, "Invalid date");
6
7
  //# sourceMappingURL=DATE.js.map
@@ -1 +1,2 @@
1
+ /** `EMAIL` type: checks that the value looks like an e-mail address. */
1
2
  export declare const EMAIL: import("../Type").Type;
@@ -2,5 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EMAIL = void 0;
4
4
  const regexType_1 = require("./regexType");
5
+ /** `EMAIL` type: checks that the value looks like an e-mail address. */
5
6
  exports.EMAIL = (0, regexType_1.regexType)("EMAIL", /^(?=.{1,256}$)(?=.{1,64}@.{1,255}$)(?=.{1,64}@.{1,63}\..{1,63}$)[A-Za-z0-9!#$%&'*+/=?^_`{|}~.-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/, "Invalid email");
6
7
  //# sourceMappingURL=EMAIL.js.map
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `ENUM` type: checks that the value is one of those declared in {@link NodeDefinition.getValues}. */
2
3
  export declare const ENUM: Type;
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ENUM = void 0;
4
4
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
+ /** `ENUM` type: checks that the value is one of those declared in {@link NodeDefinition.getValues}. */
5
6
  exports.ENUM = {
6
7
  getName() {
7
8
  return "ENUM";
8
9
  },
9
10
  validate(nodeDef, node) {
10
- // Forma del valor INLINE (STXT-SCHEMA-SPEC 9.3): no admite bloque '>>'
11
+ // INLINE value form (STXT-SCHEMA-SPEC 9.3): the block '>>' form is not allowed
11
12
  if (node.isTextNode()) {
12
13
  throw new ValidationException_1.ValidationException(node.getLine(), "NOT_ALLOWED_TEXT", `Not allowed text in node ${node.getQualifiedName()}`);
13
14
  }
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `GROUP` type: container node with no value of its own, accepting children just like INLINE. */
2
3
  export declare const GROUP: Type;
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GROUP = void 0;
4
4
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
+ /** `GROUP` type: container node with no value of its own, accepting children just like INLINE. */
5
6
  exports.GROUP = {
6
7
  getName() {
7
8
  return "GROUP";
8
9
  },
9
10
  validate(nodeDef, node) {
10
- // Forma del valor NONE (STXT-SCHEMA-SPEC 9.2): ni valor inline ni bloque '>>'
11
+ // NONE value form (STXT-SCHEMA-SPEC 9.2): neither an inline value nor a '>>' block
11
12
  if (node.getValue().length > 0 || node.isTextNode()) {
12
13
  throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_VALUE", `Node '${node.getName()}' has to be empty`);
13
14
  }
@@ -1,2 +1,3 @@
1
1
  import { Type } from "../Type";
2
+ /** `HEXADECIMAL` type: checks a hexadecimal string (`[0-9A-Fa-f]+`), with no prefix and no mandatory even length. */
2
3
  export declare const HEXADECIMAL: Type;