@stxt-lang/core 0.6.2 → 0.7.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.
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeWriter = exports.IndentStyle = void 0;
4
+ const InlineNode_1 = require("../core/InlineNode");
5
+ const TextNode_1 = require("../core/TextNode");
4
6
  /** Indentation style to use when writing. */
5
7
  var IndentStyle;
6
8
  (function (IndentStyle) {
@@ -21,7 +23,7 @@ class NodeWriter {
21
23
  */
22
24
  static toSTXT(node, style = IndentStyle.TABS) {
23
25
  const out = [];
24
- NodeWriter.writeNode(out, node, 0, style, "");
26
+ NodeWriter.writeNode(out, node, 0, style);
25
27
  return out.join("");
26
28
  }
27
29
  /**
@@ -37,34 +39,36 @@ class NodeWriter {
37
39
  if (i > 0) {
38
40
  out.push("\n");
39
41
  }
40
- NodeWriter.writeNode(out, docs[i], 0, style, "");
42
+ NodeWriter.writeNode(out, docs[i], 0, style);
41
43
  }
42
44
  return out.join("");
43
45
  }
44
- static writeNode(out, n, depth, style, parentNs) {
46
+ static writeNode(out, n, depth, style) {
45
47
  NodeWriter.indent(out, depth, style);
46
- const ns = n.getNamespace();
48
+ // The namespace is written where the node declares it; inherited ones are implicit,
49
+ // exactly as in the source (the effective namespace is the same either way)
50
+ const ns = n.getDeclaredNamespace();
47
51
  out.push(n.getName());
48
- if (ns.length > 0 && ns !== parentNs) {
52
+ if (ns.length > 0) {
49
53
  out.push(" (", ns, ")");
50
54
  }
51
- if (n.isTextNode()) {
55
+ if (n instanceof TextNode_1.TextNode) {
52
56
  out.push(" >>\n");
53
57
  for (const line of n.getTextLines()) {
54
58
  NodeWriter.indent(out, depth + 1, style);
55
59
  out.push(line, "\n");
56
60
  }
57
61
  }
58
- else {
62
+ else if (n instanceof InlineNode_1.InlineNode) {
59
63
  out.push(":");
60
64
  const value = n.getValue();
61
65
  if (value.length > 0) {
62
66
  out.push(" ", value);
63
67
  }
64
68
  out.push("\n");
65
- }
66
- for (const child of n.getChildren()) {
67
- NodeWriter.writeNode(out, child, depth + 1, style, ns);
69
+ for (const child of n.getChildren()) {
70
+ NodeWriter.writeNode(out, child, depth + 1, style);
71
+ }
68
72
  }
69
73
  }
70
74
  static indent(out, depth, style) {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toCanonicalTree = toCanonicalTree;
4
4
  exports.toCanonicalJson = toCanonicalJson;
5
+ const TextNode_1 = require("../core/TextNode");
5
6
  /**
6
7
  * Converts every root node of a parsed document to the logical tree defined by
7
8
  * STXT-TREE-SPEC. The result deliberately excludes source positions, indentation
@@ -25,22 +26,23 @@ function toCanonicalJson(nodes) {
25
26
  return JSON.stringify(toCanonicalTree(nodes), null, 2);
26
27
  }
27
28
  function toCanonicalNode(node) {
28
- if (node.isTextNode()) {
29
+ if (node instanceof TextNode_1.TextNode) {
29
30
  return {
30
31
  name: node.getName(),
31
- canonicalName: node.getNormalizedName(),
32
+ canonicalName: node.getCanonicalName(),
32
33
  namespace: node.getNamespace(),
33
34
  form: "block",
34
35
  lines: [...node.getTextLines()],
35
36
  };
36
37
  }
38
+ const inline = node;
37
39
  return {
38
- name: node.getName(),
39
- canonicalName: node.getNormalizedName(),
40
- namespace: node.getNamespace(),
40
+ name: inline.getName(),
41
+ canonicalName: inline.getCanonicalName(),
42
+ namespace: inline.getNamespace(),
41
43
  form: "inline",
42
- value: node.getValue(),
43
- children: node.getChildren().map(child => toCanonicalNode(child)),
44
+ value: inline.getValue(),
45
+ children: inline.getChildren().map(child => toCanonicalNode(child)),
44
46
  };
45
47
  }
46
48
  //# sourceMappingURL=TreeJson.js.map
@@ -19,6 +19,11 @@ export declare class ChildDefinition {
19
19
  /** @returns the name of the expected child, as it appears in the schema. */
20
20
  getName(): string;
21
21
  /** @returns the canonical name of the expected child. */
22
+ getCanonicalName(): string;
23
+ /**
24
+ * @returns the canonical name of the expected child.
25
+ * @deprecated since 0.7.0, use getCanonicalName().
26
+ */
22
27
  getNormalizedName(): string;
23
28
  /** @returns the namespace of the expected child, or the empty string if it has none. */
24
29
  getNamespace(): string;
@@ -32,6 +32,13 @@ class ChildDefinition {
32
32
  return this.name;
33
33
  }
34
34
  /** @returns the canonical name of the expected child. */
35
+ getCanonicalName() {
36
+ return this.normalizedName;
37
+ }
38
+ /**
39
+ * @returns the canonical name of the expected child.
40
+ * @deprecated since 0.7.0, use getCanonicalName().
41
+ */
35
42
  getNormalizedName() {
36
43
  return this.normalizedName;
37
44
  }
@@ -23,6 +23,11 @@ export declare class NodeDefinition {
23
23
  /** @returns the name of the node, as it appears in the schema. */
24
24
  getName(): string;
25
25
  /** @returns the canonical name of the node. */
26
+ getCanonicalName(): string;
27
+ /**
28
+ * @returns the canonical name of the node.
29
+ * @deprecated since 0.7.0, use getCanonicalName().
30
+ */
26
31
  getNormalizedName(): string;
27
32
  /** @returns the name of the value type of this node (see {@link TypeRegistry}). */
28
33
  getType(): string;
@@ -33,6 +33,13 @@ class NodeDefinition {
33
33
  return this.name;
34
34
  }
35
35
  /** @returns the canonical name of the node. */
36
+ getCanonicalName() {
37
+ return this.normalizedName;
38
+ }
39
+ /**
40
+ * @returns the canonical name of the node.
41
+ * @deprecated since 0.7.0, use getCanonicalName().
42
+ */
36
43
  getNormalizedName() {
37
44
  return this.normalizedName;
38
45
  }
@@ -40,7 +40,7 @@ class Schema {
40
40
  * @throws ValidationException with code `NODE_DEF_ALREADY_DEFINED` if there already was a node definition with the same name.
41
41
  */
42
42
  addNodeDefinition(nodeDefinition) {
43
- const qname = nodeDefinition.getNormalizedName();
43
+ const qname = nodeDefinition.getCanonicalName();
44
44
  if (this.nodes.has(qname)) {
45
45
  throw new ValidationException_1.ValidationException(0, "NODE_DEF_ALREADY_DEFINED", `Exists a previous node definition with: ${qname}`);
46
46
  }
@@ -4,6 +4,7 @@ exports.transformNodeToSchema = transformNodeToSchema;
4
4
  const Schema_1 = require("./Schema");
5
5
  const NodeDefinition_1 = require("./NodeDefinition");
6
6
  const ChildDefinition_1 = require("./ChildDefinition");
7
+ const InlineNode_1 = require("../core/InlineNode");
7
8
  const ValidationException_1 = require("../exceptions/ValidationException");
8
9
  const RuntimeException_1 = require("../exceptions/RuntimeException");
9
10
  const NameNamespaceParser_1 = require("../core/NameNamespaceParser");
@@ -17,34 +18,30 @@ const TypeRegistry_1 = require("./TypeRegistry");
17
18
  */
18
19
  function transformNodeToSchema(node) {
19
20
  // Node name
20
- const nodeName = node.getNormalizedName();
21
+ const nodeName = node.getCanonicalName();
21
22
  const namespaceSchema = node.getNamespace();
22
23
  // Get the name and the namespace
23
24
  if (nodeName !== "schema" || namespaceSchema !== Schema_1.Schema.SCHEMA_NAMESPACE) {
24
25
  throw new ValidationException_1.ValidationException(node.getLine(), "NOT_STXT_SCHEMA", `Expected schema(${Schema_1.Schema.SCHEMA_NAMESPACE}) but got ${nodeName}(${namespaceSchema})`);
25
26
  }
27
+ const root = inline(node);
26
28
  // Get the description
27
- const descrip = node.getChild("description")?.getText();
28
- const schema = new Schema_1.Schema(node.getValue(), node.getLine(), descrip);
29
+ const descrip = root.getChild("description")?.getText();
30
+ const schema = new Schema_1.Schema(root.getValue(), root.getLine(), descrip);
29
31
  // Used to check that every child is defined
30
32
  const allNames = new Set();
31
33
  // Get the nodes
32
- for (const n of node.getChildrenByName("node")) {
34
+ for (const n of root.getChildrenByName("node")) {
33
35
  const schNode = createFrom(n, schema.getNamespace());
34
36
  schema.addNodeDefinition(schNode);
35
- allNames.add(schNode.getNormalizedName());
37
+ allNames.add(schNode.getCanonicalName());
36
38
  }
37
39
  // Check that every name is defined
38
40
  for (const schNode of schema.getNodes().values()) {
39
41
  for (const schChild of schNode.getChildren().values()) {
40
42
  // Only names of the same namespace are checked
41
43
  if (schChild.getNamespace() === schema.getNamespace()) {
42
- // Defensive leftover from the Java port: ChildDefinition does expose
43
- // getNormalizedName(), so this check can never fail with the current class.
44
- const childNorm = schChild.getNormalizedName?.();
45
- if (!childNorm) {
46
- throw new RuntimeException_1.RuntimeException("CHILD_DEFINITION_API_MISMATCH", "ChildDefinition.getNormalizedName() is missing in TypeScript version. Add it to ChildDefinition.");
47
- }
44
+ const childNorm = schChild.getCanonicalName();
48
45
  if (!allNames.has(childNorm)) {
49
46
  throw new ValidationException_1.ValidationException(0, "CHILD_NOT_DEFINED", `Child ${childNorm} not defined in ${schema.getNamespace()}`);
50
47
  }
@@ -53,13 +50,21 @@ function transformNodeToSchema(node) {
53
50
  }
54
51
  return schema;
55
52
  }
53
+ /** The schema language is written with inline nodes; anything else is not a schema. */
54
+ function inline(node) {
55
+ if (node instanceof InlineNode_1.InlineNode) {
56
+ return node;
57
+ }
58
+ throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_SCHEMA", `Node '${node.getName()}' must be inline in a schema`);
59
+ }
56
60
  /** Builds the definition of a node from a `Node:` entry of the schema document. */
57
- function createFrom(n, namespace) {
61
+ function createFrom(node, namespace) {
62
+ const n = inline(node);
58
63
  const name = n.getValue();
59
64
  let type = "INLINE";
60
65
  const typeNode = n.getChild("type");
61
66
  if (typeNode) {
62
- type = typeNode.getValue();
67
+ type = typeNode.getText();
63
68
  }
64
69
  const description = n.getChild("description")?.getText();
65
70
  const result = new NodeDefinition_1.NodeDefinition(name, type, n.getLine(), description);
@@ -69,7 +74,7 @@ function createFrom(n, namespace) {
69
74
  if (!TypeRegistry_1.TypeRegistry.admitsChildren(type)) {
70
75
  throw new ValidationException_1.ValidationException(children.getLine(), "CHILDREN_NOT_ALLOWED_FOR_TYPE", `Type ${type} does not allow children (node ${name})`);
71
76
  }
72
- for (const child of children.getChildrenByName("child")) {
77
+ for (const child of inline(children).getChildrenByName("child")) {
73
78
  putChildToSchemaNode(result, child, namespace);
74
79
  }
75
80
  }
@@ -83,9 +88,9 @@ function createFrom(n, namespace) {
83
88
  throw new RuntimeException_1.RuntimeException("INVALID_SIZE_VALUES", `Unexpected number of values: ${valuesNodes.length}`);
84
89
  }
85
90
  const valuesNode = valuesNodes[0];
86
- const values = valuesNode.getChildrenByName("value");
91
+ const values = inline(valuesNode).getChildrenByName("value");
87
92
  for (const v of values) {
88
- result.addValue(v.getValue(), v.getLine());
93
+ result.addValue(v.getText(), v.getLine());
89
94
  }
90
95
  // For the final ENUM check
91
96
  valuesNodes = values;
@@ -97,7 +102,8 @@ function createFrom(n, namespace) {
97
102
  return result;
98
103
  }
99
104
  /** Adds to a node definition the expected child a `Child:` entry declares. */
100
- function putChildToSchemaNode(schemaNode, child, defNamespace) {
105
+ function putChildToSchemaNode(schemaNode, childNode, defNamespace) {
106
+ const child = inline(childNode);
101
107
  // Get the name and the namespace
102
108
  const ns = NameNamespaceParser_1.NameNamespaceParser.parse(child.getValue(), defNamespace, child.getLine(), child.getValue());
103
109
  const name = ns.getName();
@@ -117,7 +123,7 @@ function getInteger(node, name) {
117
123
  if (!n) {
118
124
  return null;
119
125
  }
120
- const raw = n.getValue();
126
+ const raw = n.getText();
121
127
  const parsed = Number.parseInt(raw, 10);
122
128
  if (Number.isNaN(parsed)) {
123
129
  throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_INTEGER", `Integer not valid: ${raw}`);
@@ -16,9 +16,13 @@ export declare class SchemaProviderMeta implements SchemaProvider {
16
16
  /**
17
17
  * Serves the meta-schema of the schema language.
18
18
  *
19
+ * Follows the {@link SchemaProvider} contract: providers never throw "not found". Any
20
+ * namespace other than `@stxt.schema` yields `null`, so that this provider can sit at
21
+ * the end of a fallback chain (it is the default parent of {@link SchemaProviderMemory})
22
+ * and the {@link SchemaValidator} is the only one reporting `SCHEMA_NOT_FOUND`.
23
+ *
19
24
  * @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.
25
+ * @returns the meta-schema of the schema language, or `null` for any other namespace.
22
26
  */
23
- getSchema(namespace: string): Schema;
27
+ getSchema(namespace: string): Schema | null;
24
28
  }
@@ -4,7 +4,6 @@ exports.SchemaProviderMeta = void 0;
4
4
  const Schema_1 = require("./Schema");
5
5
  const Parser_1 = require("../core/Parser");
6
6
  const ValidationException_1 = require("../exceptions/ValidationException");
7
- const RuntimeException_1 = require("../exceptions/RuntimeException");
8
7
  const SchemaParser_1 = require("./SchemaParser");
9
8
  /**
10
9
  * {@link SchemaProvider} that defines in code the meta-schema of the schema language itself
@@ -27,13 +26,17 @@ class SchemaProviderMeta {
27
26
  /**
28
27
  * Serves the meta-schema of the schema language.
29
28
  *
29
+ * Follows the {@link SchemaProvider} contract: providers never throw "not found". Any
30
+ * namespace other than `@stxt.schema` yields `null`, so that this provider can sit at
31
+ * the end of a fallback chain (it is the default parent of {@link SchemaProviderMemory})
32
+ * and the {@link SchemaValidator} is the only one reporting `SCHEMA_NOT_FOUND`.
33
+ *
30
34
  * @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.
35
+ * @returns the meta-schema of the schema language, or `null` for any other namespace.
33
36
  */
34
37
  getSchema(namespace) {
35
38
  if (namespace !== Schema_1.Schema.SCHEMA_NAMESPACE) {
36
- throw new RuntimeException_1.RuntimeException("RESOURCE_NOT_FOUND", `Not found '${namespace}' in namespace: ${Schema_1.Schema.SCHEMA_NAMESPACE}`);
39
+ return null;
37
40
  }
38
41
  if (!this.meta) {
39
42
  throw new ValidationException_1.ValidationException(0, "META_SCHEMA_NOT_AVAILABLE", "Meta schema not available");
@@ -29,6 +29,7 @@ export declare class SchemaValidator implements Validator {
29
29
  * @returns the validation errors found, empty if the node is valid.
30
30
  */
31
31
  validateAgainstSchema(node: Node, schema: Schema): ValidationException[];
32
+ private static childrenOf;
32
33
  private static validateChildrenDeclared;
33
34
  private static validateValue;
34
35
  private static validateCount;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SchemaValidator = void 0;
4
+ const InlineNode_1 = require("../core/InlineNode");
4
5
  const ValidationException_1 = require("../exceptions/ValidationException");
5
6
  const TypeRegistry_1 = require("./TypeRegistry");
6
7
  /** {@link Validator} that, for each node, resolves its {@link Schema} through a {@link SchemaProvider} and validates type and cardinality. */
@@ -32,8 +33,8 @@ class SchemaValidator {
32
33
  }
33
34
  // Validate the node
34
35
  errors.push(...this.validateAgainstSchema(node, schema));
35
- // Validate the children
36
- if (this.recursiveValidation) {
36
+ // Validate the children (only an inline node has any)
37
+ if (this.recursiveValidation && node instanceof InlineNode_1.InlineNode) {
37
38
  for (const childNode of node.getChildren()) {
38
39
  errors.push(...this.validate(childNode));
39
40
  }
@@ -49,9 +50,9 @@ class SchemaValidator {
49
50
  */
50
51
  validateAgainstSchema(node, schema) {
51
52
  const errors = [];
52
- const schemaNode = schema.getNodeDefinition(node.getNormalizedName());
53
+ const schemaNode = schema.getNodeDefinition(node.getCanonicalName());
53
54
  if (!schemaNode) {
54
- const error = `NOT EXIST NODE ${node.getNormalizedName()} for namespace ${schema.getNamespace()}`;
55
+ const error = `NOT EXIST NODE ${node.getCanonicalName()} for namespace ${schema.getNamespace()}`;
55
56
  errors.push(new ValidationException_1.ValidationException(node.getLine(), "NODE_NOT_EXIST_IN_SCHEMA", error));
56
57
  return errors;
57
58
  }
@@ -60,11 +61,15 @@ class SchemaValidator {
60
61
  errors.push(...SchemaValidator.validateCount(schemaNode, node));
61
62
  return errors;
62
63
  }
64
+ // The children of a node for the purposes of the content model: a text node has none
65
+ static childrenOf(node) {
66
+ return node instanceof InlineNode_1.InlineNode ? node.getChildren() : [];
67
+ }
63
68
  // Closed content model (STXT-SCHEMA-SPEC, section 6): only the direct children declared
64
69
  // in the definition of the parent are allowed; with no Children, nothing is
65
70
  static validateChildrenDeclared(nodeDef, node) {
66
71
  const errors = [];
67
- for (const child of node.getChildren()) {
72
+ for (const child of SchemaValidator.childrenOf(node)) {
68
73
  if (!nodeDef.getChildren().has(child.getQualifiedName())) {
69
74
  errors.push(new ValidationException_1.ValidationException(child.getLine(), "CHILD_NOT_DECLARED", `Child '${child.getQualifiedName()}' not declared in node '${node.getQualifiedName()}'`));
70
75
  }
@@ -99,7 +104,7 @@ class SchemaValidator {
99
104
  const errors = [];
100
105
  const count = new Map();
101
106
  const childrenByType = new Map();
102
- for (const child of node.getChildren()) {
107
+ for (const child of SchemaValidator.childrenOf(node)) {
103
108
  const childName = child.getQualifiedName();
104
109
  count.set(childName, (count.get(childName) ?? 0) + 1);
105
110
  if (!childrenByType.has(childName)) {
@@ -12,7 +12,7 @@ exports.ENUM = {
12
12
  if (node.isTextNode()) {
13
13
  throw new ValidationException_1.ValidationException(node.getLine(), "NOT_ALLOWED_TEXT", `Not allowed text in node ${node.getQualifiedName()}`);
14
14
  }
15
- const value = node.getValue();
15
+ const value = node.getText();
16
16
  const allowed = nodeDef.getValues(); // ReadonlySet<string>
17
17
  if (!nodeDef.isAllowedValue(value)) {
18
18
  throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_VALUE", `The value '${value}' not allowed. Only: ${Array.from(allowed).join(", ")}`);
@@ -9,7 +9,7 @@ exports.GROUP = {
9
9
  },
10
10
  validate(nodeDef, node) {
11
11
  // NONE value form (STXT-SCHEMA-SPEC 9.2): neither an inline value nor a '>>' block
12
- if (node.getValue().length > 0 || node.isTextNode()) {
12
+ if (node.isTextNode() || node.getText().length > 0) {
13
13
  throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_VALUE", `Node '${node.getName()}' has to be empty`);
14
14
  }
15
15
  },
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MARKDOWN = void 0;
4
+ const InlineNode_1 = require("../../core/InlineNode");
4
5
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
6
  /**
6
7
  * `MARKDOWN` type. STXT-SCHEMA-SPEC 9.7: for validation purposes it is equivalent to TEXT
@@ -11,7 +12,7 @@ exports.MARKDOWN = {
11
12
  return "MARKDOWN";
12
13
  },
13
14
  validate(nodeDef, node) {
14
- if (node.getChildren().length > 0) {
15
+ if (node instanceof InlineNode_1.InlineNode && node.getChildren().length > 0) {
15
16
  throw new ValidationException_1.ValidationException(node.getLine(), "NOT_ALLOWED_CHILDREN_TEXT", `Not allowed children nodes in node ${node.getQualifiedName()}`);
16
17
  }
17
18
  },
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TEXT = void 0;
4
+ const InlineNode_1 = require("../../core/InlineNode");
4
5
  const ValidationException_1 = require("../../exceptions/ValidationException");
5
6
  /** `TEXT` type: free text node, with no children allowed. */
6
7
  exports.TEXT = {
@@ -8,7 +9,7 @@ exports.TEXT = {
8
9
  return "TEXT";
9
10
  },
10
11
  validate(nodeDef, node) {
11
- if (node.getChildren().length > 0) {
12
+ if (node instanceof InlineNode_1.InlineNode && node.getChildren().length > 0) {
12
13
  throw new ValidationException_1.ValidationException(node.getLine(), "NOT_ALLOWED_CHILDREN_TEXT", `Not allowed children nodes in node ${node.getQualifiedName()}`);
13
14
  }
14
15
  },
@@ -12,7 +12,7 @@ exports.URL = {
12
12
  if (n.isTextNode()) {
13
13
  throw new ValidationException_1.ValidationException(n.getLine(), "NOT_ALLOWED_TEXT", `Not allowed text in node ${n.getQualifiedName()}`);
14
14
  }
15
- const url = n.getValue();
15
+ const url = n.getText();
16
16
  try {
17
17
  const parsed = new globalThis.URL(url);
18
18
  const ok = !!parsed.protocol && !!parsed.hostname;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.binaryValue = binaryValue;
4
+ const TextNode_1 = require("../../core/TextNode");
4
5
  /**
5
6
  * STXT-SCHEMA-SPEC 9.5: effective value for the INLINE/BLOCK binary types
6
7
  * (HEXADECIMAL, BINARY, BASE64). In BLOCK form, validation applies to the
@@ -11,8 +12,8 @@ exports.binaryValue = binaryValue;
11
12
  * @returns the inline value, or the lines of the block already concatenated.
12
13
  */
13
14
  function binaryValue(node) {
14
- if (!node.isTextNode()) {
15
- return node.getValue();
15
+ if (!(node instanceof TextNode_1.TextNode)) {
16
+ return node.getText();
16
17
  }
17
18
  return node.getTextLines().map((line) => line.trim()).join("");
18
19
  }
@@ -16,9 +16,12 @@ export declare class MetaTemplateSchemaProvider implements SchemaProvider {
16
16
  /**
17
17
  * Serves the meta-schema of the template language.
18
18
  *
19
+ * Follows the {@link SchemaProvider} contract: providers never throw "not found". Any
20
+ * namespace other than `@stxt.template` yields `null`; only the `SchemaValidator`
21
+ * reports `SCHEMA_NOT_FOUND`.
22
+ *
19
23
  * @param namespace namespace whose schema is wanted; only `@stxt.template` is served.
20
- * @returns the meta-schema of the template language.
21
- * @throws RuntimeException with code `RESOURCE_NOT_FOUND` if any other namespace is asked for.
24
+ * @returns the meta-schema of the template language, or `null` for any other namespace.
22
25
  */
23
- getSchema(namespace: string): Schema;
26
+ getSchema(namespace: string): Schema | null;
24
27
  }
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MetaTemplateSchemaProvider = void 0;
4
4
  const Parser_1 = require("../core/Parser");
5
5
  const ValidationException_1 = require("../exceptions/ValidationException");
6
- const RuntimeException_1 = require("../exceptions/RuntimeException");
7
6
  const TemplateParser_1 = require("./TemplateParser");
8
7
  /**
9
8
  * {@link SchemaProvider} that defines in code the meta-schema of the template language itself
@@ -26,13 +25,16 @@ class MetaTemplateSchemaProvider {
26
25
  /**
27
26
  * Serves the meta-schema of the template language.
28
27
  *
28
+ * Follows the {@link SchemaProvider} contract: providers never throw "not found". Any
29
+ * namespace other than `@stxt.template` yields `null`; only the `SchemaValidator`
30
+ * reports `SCHEMA_NOT_FOUND`.
31
+ *
29
32
  * @param namespace namespace whose schema is wanted; only `@stxt.template` is served.
30
- * @returns the meta-schema of the template language.
31
- * @throws RuntimeException with code `RESOURCE_NOT_FOUND` if any other namespace is asked for.
33
+ * @returns the meta-schema of the template language, or `null` for any other namespace.
32
34
  */
33
35
  getSchema(namespace) {
34
36
  if (namespace !== "@stxt.template") {
35
- throw new RuntimeException_1.RuntimeException("RESOURCE_NOT_FOUND", `Not found '${namespace}' in namespace: @stxt.template`);
37
+ return null;
36
38
  }
37
39
  // meta always exists once the constructor finished, but this mirrors the Java version
38
40
  if (!this.meta) {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformTemplateNodeToSchema = transformTemplateNodeToSchema;
4
+ const InlineNode_1 = require("../core/InlineNode");
4
5
  const Parser_1 = require("../core/Parser");
5
6
  const ValidationException_1 = require("../exceptions/ValidationException");
6
7
  const ChildDefinition_1 = require("../schema/ChildDefinition");
@@ -20,9 +21,9 @@ const TypeRegistry_1 = require("../schema/TypeRegistry");
20
21
  */
21
22
  function transformTemplateNodeToSchema(node) {
22
23
  // Set the namespace
23
- const result = new Schema_1.Schema(node.getValue(), node.getLine(), undefined);
24
- // Look for the structure node
25
- const structure = node.getChild("structure");
24
+ const result = new Schema_1.Schema(node.getText(), node.getLine(), undefined);
25
+ // Look for the structure node (a template is an inline root; a text root has none)
26
+ const structure = node instanceof InlineNode_1.InlineNode ? node.getChild("structure") : null;
26
27
  if (!structure) {
27
28
  throw new ValidationException_1.ValidationException(node.getLine(), "TEMPLATE_STRUCTURE_REQUIRED", "Template must define 'Structure >>'");
28
29
  }
@@ -74,7 +75,7 @@ function transformTemplateNodeToSchema(node) {
74
75
  function addToSchema(schema, node) {
75
76
  // A Structure line must use the template grammar's ':' form. The core parser
76
77
  // also accepts BLOCK nodes here, so reject them explicitly (STXT-TEMPLATE-SPEC 6.3).
77
- if (node.isTextNode()) {
78
+ if (!(node instanceof InlineNode_1.InlineNode)) {
78
79
  throw new ValidationException_1.ValidationException(node.getLine(), "INVALID_CHILD_LINE", "Template Structure lines must use ':'");
79
80
  }
80
81
  // Get the qualified name
@@ -142,11 +143,11 @@ function addToSchema(schema, node) {
142
143
  }
143
144
  const reference = type.substring(1).trim();
144
145
  // Reference and explicit type on the same line (STXT-TEMPLATE-SPEC 14.13)
145
- const explicitType = referenceType(reference, node.getNormalizedName());
146
+ const explicitType = referenceType(reference, node.getCanonicalName());
146
147
  if (explicitType) {
147
148
  throw new ValidationException_1.ValidationException(node.getLine(), "REFERENCE_WITH_TYPE_NOT_ALLOWED", `Reference '@${node.getName()}' can not declare a type: ${explicitType}`);
148
149
  }
149
- if (StringUtils_1.StringUtils.normalize(reference) !== node.getNormalizedName()) {
150
+ if (StringUtils_1.StringUtils.normalize(reference) !== node.getCanonicalName()) {
150
151
  throw new ValidationException_1.ValidationException(node.getLine(), "NODE_REFERENCE_NOT_VALID", `Reference must be '@${node.getName()}', not '${reference}'`);
151
152
  }
152
153
  // A reference may override the cardinality, but it may redefine neither the ENUM
@@ -168,6 +169,10 @@ function addToSchema(schema, node) {
168
169
  }
169
170
  // Add the children
170
171
  for (const child of childrenNode) {
172
+ // STXT-TEMPLATE-SPEC 6.3: every Structure line uses ':', so a child is inline too
173
+ if (!(child instanceof InlineNode_1.InlineNode)) {
174
+ throw new ValidationException_1.ValidationException(child.getLine(), "INVALID_CHILD_LINE", "Template Structure lines must use ':'");
175
+ }
171
176
  cl = ChildLineParser_1.ChildLineParser.parse(child.getValue(), child.getLine());
172
177
  const childName = child.getName();
173
178
  let childNamespace = child.getNamespace();
@@ -211,7 +216,7 @@ function addDescriptions(schema, nodes) {
211
216
  throw new ValidationException_1.ValidationException(node.getLine(), "EXTERNAL_DESCRIPTION_NOT_ALLOWED", "Not allowed description in external namespaces");
212
217
  }
213
218
  // No children either
214
- if (node.getChildren().length > 0) {
219
+ if (node instanceof InlineNode_1.InlineNode && node.getChildren().length > 0) {
215
220
  throw new ValidationException_1.ValidationException(node.getLine(), "CHILDREN_DESCRIPTION_NOT_ALLOWED", "Not allowed children in description");
216
221
  }
217
222
  // Look for the node in the schema
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stxt-lang/core",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "Parser and schema validator for STXT, an indentation-based structured-text format.",
5
5
  "main": "out/all.js",
6
6
  "types": "out/all.d.ts",