@lionweb/validation 0.6.3-beta.4 → 0.6.13-beta.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 (160) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/runners/FileUtils.d.ts +1 -1
  3. package/dist/runners/FileUtils.d.ts.map +1 -1
  4. package/dist/runners/FileUtils.js +1 -1
  5. package/dist/runners/FileUtils.js.map +1 -1
  6. package/dist/runners/Utils.d.ts +1 -1
  7. package/dist/runners/Utils.d.ts.map +1 -1
  8. package/dist/validators/LionWebChunkDefinitions.d.ts +9 -0
  9. package/dist/validators/LionWebChunkDefinitions.d.ts.map +1 -0
  10. package/dist/validators/LionWebChunkDefinitions.js +106 -0
  11. package/dist/validators/LionWebChunkDefinitions.js.map +1 -0
  12. package/dist/validators/LionWebLanguageReferenceValidator.d.ts +1 -3
  13. package/dist/validators/LionWebLanguageReferenceValidator.d.ts.map +1 -1
  14. package/dist/validators/LionWebLanguageReferenceValidator.js +4 -5
  15. package/dist/validators/LionWebLanguageReferenceValidator.js.map +1 -1
  16. package/dist/validators/LionWebLanguageValidator.d.ts +2 -2
  17. package/dist/validators/LionWebLanguageValidator.d.ts.map +1 -1
  18. package/dist/validators/LionWebLanguageValidator.js +1 -1
  19. package/dist/validators/LionWebReferenceValidator.d.ts +3 -4
  20. package/dist/validators/LionWebReferenceValidator.d.ts.map +1 -1
  21. package/dist/validators/LionWebReferenceValidator.js +2 -3
  22. package/dist/validators/LionWebReferenceValidator.js.map +1 -1
  23. package/dist/validators/LionWebSyntaxValidator.d.ts +4 -83
  24. package/dist/validators/LionWebSyntaxValidator.d.ts.map +1 -1
  25. package/dist/validators/LionWebSyntaxValidator.js +5 -248
  26. package/dist/validators/LionWebSyntaxValidator.js.map +1 -1
  27. package/dist/validators/LionWebValidator.d.ts +1 -1
  28. package/dist/validators/LionWebValidator.d.ts.map +1 -1
  29. package/dist/validators/LionWebValidator.js +2 -3
  30. package/dist/validators/LionWebValidator.js.map +1 -1
  31. package/dist/validators/ValidationFunctions.d.ts +56 -0
  32. package/dist/validators/ValidationFunctions.d.ts.map +1 -0
  33. package/dist/validators/ValidationFunctions.js +114 -0
  34. package/dist/validators/ValidationFunctions.js.map +1 -0
  35. package/dist/validators/generic/SyntaxValidator.d.ts +37 -0
  36. package/dist/validators/generic/SyntaxValidator.d.ts.map +1 -0
  37. package/dist/validators/generic/SyntaxValidator.js +159 -0
  38. package/dist/validators/generic/SyntaxValidator.js.map +1 -0
  39. package/dist/validators/{ValidationResult.d.ts → generic/ValidationResult.d.ts} +1 -1
  40. package/dist/validators/generic/ValidationResult.d.ts.map +1 -0
  41. package/dist/validators/generic/ValidationResult.js.map +1 -0
  42. package/dist/validators/generic/ValidationTypes.d.ts +64 -0
  43. package/dist/validators/generic/ValidationTypes.d.ts.map +1 -0
  44. package/dist/validators/generic/ValidationTypes.js +45 -0
  45. package/dist/validators/generic/ValidationTypes.js.map +1 -0
  46. package/dist/validators/generic/index.d.ts +4 -0
  47. package/dist/validators/generic/index.d.ts.map +1 -0
  48. package/dist/validators/generic/index.js +4 -0
  49. package/dist/validators/generic/index.js.map +1 -0
  50. package/dist/validators/index.d.ts +3 -2
  51. package/dist/validators/index.d.ts.map +1 -1
  52. package/dist/validators/index.js +3 -2
  53. package/dist/validators/index.js.map +1 -1
  54. package/package.json +3 -3
  55. package/src/json/ChunkUtils.d.ts +26 -0
  56. package/src/json/ChunkUtils.d.ts.map +1 -0
  57. package/src/json/ChunkUtils.js +46 -0
  58. package/src/json/ChunkUtils.js.map +1 -0
  59. package/src/json/JsonContext.d.ts +11 -0
  60. package/src/json/JsonContext.d.ts.map +1 -0
  61. package/src/json/JsonContext.js +25 -0
  62. package/src/json/JsonContext.js.map +1 -0
  63. package/src/json/LionCore_M3.json +2320 -0
  64. package/src/json/LionCore_builtins.json +231 -0
  65. package/src/json/LionWebJson.d.ts +50 -0
  66. package/src/json/LionWebJson.d.ts.map +1 -0
  67. package/src/json/LionWebJson.js +27 -0
  68. package/src/json/LionWebJson.js.map +1 -0
  69. package/src/json/LionWebJsonChunkWrapper.d.ts +39 -0
  70. package/src/json/LionWebJsonChunkWrapper.d.ts.map +1 -0
  71. package/src/json/LionWebJsonChunkWrapper.js +119 -0
  72. package/src/json/LionWebJsonChunkWrapper.js.map +1 -0
  73. package/src/json/M3definitions.d.ts +176 -0
  74. package/src/json/M3definitions.d.ts.map +1 -0
  75. package/src/json/M3definitions.js +174 -0
  76. package/src/json/M3definitions.js.map +1 -0
  77. package/src/json/NodeUtils.d.ts +23 -0
  78. package/src/json/NodeUtils.d.ts.map +1 -0
  79. package/src/json/NodeUtils.js +57 -0
  80. package/src/json/NodeUtils.js.map +1 -0
  81. package/src/json/index.d.ts +7 -0
  82. package/src/json/index.d.ts.map +1 -0
  83. package/src/json/index.js +7 -0
  84. package/src/json/index.js.map +1 -0
  85. package/src/languages/CompositeLionWebLanguageWrapper.d.ts +24 -0
  86. package/src/languages/CompositeLionWebLanguageWrapper.d.ts.map +1 -0
  87. package/src/languages/CompositeLionWebLanguageWrapper.js +56 -0
  88. package/src/languages/CompositeLionWebLanguageWrapper.js.map +1 -0
  89. package/src/languages/LanguageRegistry.d.ts +19 -0
  90. package/src/languages/LanguageRegistry.d.ts.map +1 -0
  91. package/src/languages/LanguageRegistry.js +37 -0
  92. package/src/languages/LanguageRegistry.js.map +1 -0
  93. package/src/languages/LanguageUtils.d.ts +35 -0
  94. package/src/languages/LanguageUtils.d.ts.map +1 -0
  95. package/src/languages/LanguageUtils.js +54 -0
  96. package/src/languages/LanguageUtils.js.map +1 -0
  97. package/src/languages/LionWebLanguageWrapper.d.ts +31 -0
  98. package/src/languages/LionWebLanguageWrapper.d.ts.map +1 -0
  99. package/src/languages/LionWebLanguageWrapper.js +69 -0
  100. package/src/languages/LionWebLanguageWrapper.js.map +1 -0
  101. package/src/languages/MetaPointerMap.d.ts +11 -0
  102. package/src/languages/MetaPointerMap.d.ts.map +1 -0
  103. package/src/languages/MetaPointerMap.js +39 -0
  104. package/src/languages/MetaPointerMap.js.map +1 -0
  105. package/src/languages/index.d.ts +3 -0
  106. package/src/languages/index.d.ts.map +1 -0
  107. package/src/languages/index.js +3 -0
  108. package/src/languages/index.js.map +1 -0
  109. package/src/runners/FileUtils.d.ts +6 -0
  110. package/src/runners/FileUtils.d.ts.map +1 -0
  111. package/src/runners/FileUtils.js +53 -0
  112. package/src/runners/FileUtils.js.map +1 -0
  113. package/src/runners/FileUtils.ts +1 -1
  114. package/src/runners/RunCheckFolder.d.ts +2 -0
  115. package/src/runners/RunCheckFolder.d.ts.map +1 -0
  116. package/src/runners/RunCheckFolder.js +6 -0
  117. package/src/runners/RunCheckFolder.js.map +1 -0
  118. package/src/runners/RunCheckFolderWithLanguage.d.ts +2 -0
  119. package/src/runners/RunCheckFolderWithLanguage.d.ts.map +1 -0
  120. package/src/runners/RunCheckFolderWithLanguage.js +40 -0
  121. package/src/runners/RunCheckFolderWithLanguage.js.map +1 -0
  122. package/src/runners/RunLioncoreDiff.d.ts +2 -0
  123. package/src/runners/RunLioncoreDiff.d.ts.map +1 -0
  124. package/src/runners/RunLioncoreDiff.js +22 -0
  125. package/src/runners/RunLioncoreDiff.js.map +1 -0
  126. package/src/runners/Utils.d.ts +7 -0
  127. package/src/runners/Utils.d.ts.map +1 -0
  128. package/src/runners/Utils.js +48 -0
  129. package/src/runners/Utils.js.map +1 -0
  130. package/src/runners/Utils.ts +1 -1
  131. package/src/runners/index.d.ts +3 -0
  132. package/src/runners/index.d.ts.map +1 -0
  133. package/src/runners/index.js +3 -0
  134. package/src/runners/index.js.map +1 -0
  135. package/src/tryout.js +21 -0
  136. package/src/util/graphs.d.ts +18 -0
  137. package/src/util/graphs.d.ts.map +1 -0
  138. package/src/util/graphs.js +27 -0
  139. package/src/util/graphs.js.map +1 -0
  140. package/src/validators/LionWebChunkDefinitions.ts +120 -0
  141. package/src/validators/LionWebLanguageReferenceValidator.ts +5 -7
  142. package/src/validators/LionWebLanguageValidator.ts +2 -2
  143. package/src/validators/LionWebReferenceValidator.ts +3 -5
  144. package/src/validators/LionWebSyntaxValidator.ts +6 -300
  145. package/src/validators/LionWebValidator.ts +2 -3
  146. package/src/validators/ValidationFunctions.ts +135 -0
  147. package/src/validators/generic/SyntaxValidator.ts +173 -0
  148. package/src/validators/{ValidationResult.ts → generic/ValidationResult.ts} +1 -1
  149. package/src/validators/generic/ValidationTypes.ts +100 -0
  150. package/src/validators/generic/index.ts +3 -0
  151. package/src/validators/index.ts +3 -2
  152. package/structure.puml +25 -0
  153. package/dist/validators/SimpleFieldValidator.d.ts +0 -27
  154. package/dist/validators/SimpleFieldValidator.d.ts.map +0 -1
  155. package/dist/validators/SimpleFieldValidator.js +0 -80
  156. package/dist/validators/SimpleFieldValidator.js.map +0 -1
  157. package/dist/validators/ValidationResult.d.ts.map +0 -1
  158. package/dist/validators/ValidationResult.js.map +0 -1
  159. package/src/validators/SimpleFieldValidator.ts +0 -98
  160. /package/dist/validators/{ValidationResult.js → generic/ValidationResult.js} +0 -0
@@ -0,0 +1,120 @@
1
+ import {
2
+ validateId,
3
+ validateKey,
4
+ validateSerializationFormatVersion,
5
+ validateVersion
6
+ } from "./ValidationFunctions.js"
7
+ import {
8
+ TypeDefinition,
9
+ MAY_BE_NULL,
10
+ PrimitiveDef,
11
+ PropertyDef,
12
+ } from "./generic/ValidationTypes.js"
13
+
14
+ /**
15
+ * The structure below defines the structure of a LionWeb Chunk by defining all the properties.
16
+ * It can
17
+ * - be fed to the SyntaxValidator to validate an object sat runtime.
18
+ * - used to generate all the types for a LionWebChunk.
19
+ */
20
+ export const expectedTypes: Map<string, TypeDefinition> = new Map<string, TypeDefinition>([
21
+ [
22
+ "LionWebMetaPointer",
23
+ [
24
+ PropertyDef({ property: "key", expectedType: "LionWebKey" }),
25
+ PropertyDef({ property: "version", expectedType: "LionWebVersion" }),
26
+ PropertyDef({ property: "language", expectedType: "LionWebKey" })
27
+ ]
28
+ ],
29
+ [
30
+ "ResponseMessage",
31
+ [
32
+ PropertyDef({ property: "kind", expectedType: "string" }),
33
+ PropertyDef({ property: "message", expectedType: "string" }),
34
+ PropertyDef({ property: "data", expectedType: "object", mayBeNull: true })
35
+ ]
36
+ ],
37
+ [
38
+ "LionWebChunk",
39
+ [
40
+ PropertyDef({ property: "serializationFormatVersion", expectedType: "LionWebSerializationFormatVersion" }),
41
+ PropertyDef({ property: "languages", expectedType: "LionWebUsedLanguage", isList: true }),
42
+ PropertyDef({ property: "nodes", expectedType: "LionWebNode", isList: true })
43
+ ]
44
+ ],
45
+ [
46
+ "LionWebUsedLanguage",
47
+ [
48
+ PropertyDef({ property: "key", expectedType: "LionWebKey" }),
49
+ PropertyDef({ property: "version", expectedType: "LionWebVersion" })
50
+ ]
51
+ ],
52
+ [
53
+ "LionWebNode",
54
+ [
55
+ PropertyDef({ property: "id", expectedType: "LionWebId" }),
56
+ PropertyDef({ property: "classifier", expectedType: "LionWebMetaPointer" }),
57
+ PropertyDef({ property: "properties", expectedType: "LionWebProperty", isList: true }),
58
+ PropertyDef({ property: "containments", expectedType: "LionWebContainment", isList: true }),
59
+ PropertyDef({ property: "references", expectedType: "LionWebReference", isList: true }),
60
+ PropertyDef({ property: "annotations", expectedType: "LionWebId", isList: true }),
61
+ PropertyDef({ property: "parent", expectedType: "LionWebId", mayBeNull: MAY_BE_NULL }),
62
+ ]
63
+ ],
64
+ [
65
+ "LionWebProperty",
66
+ [
67
+ PropertyDef({ property: "property", expectedType: "LionWebMetaPointer" }),
68
+ PropertyDef({ property: "value", expectedType: "string", mayBeNull: MAY_BE_NULL }),
69
+ ]
70
+ ],
71
+ [
72
+ "LionWebContainment",
73
+ [
74
+ PropertyDef({ property: "containment", expectedType: "LionWebMetaPointer" }),
75
+ PropertyDef({ property: "children", expectedType: "LionWebId", isList: true }),
76
+ ]
77
+ ],
78
+ [
79
+ "LionWebReference",
80
+ [
81
+ PropertyDef({ property: "reference", expectedType: "LionWebMetaPointer"}),
82
+ PropertyDef({ property: "targets", expectedType: "LionWebReferenceTarget", isList: true}),
83
+ ]
84
+ ],
85
+ [
86
+ "LionWebReferenceTarget",
87
+ [
88
+ PropertyDef({ property: "resolveInfo", expectedType: "string", mayBeNull: MAY_BE_NULL }),
89
+ PropertyDef({ property: "reference", expectedType: "LionWebId", mayBeNull: MAY_BE_NULL }),
90
+ ]
91
+ ],
92
+ /**
93
+ * Elements without properties are assumed to be JSON/JS primitive values, and tested using `typeof`
94
+ * and the (optional) validate function.
95
+ */
96
+ [
97
+ "LionWebId",
98
+ PrimitiveDef({ primitiveType: "string", validate: validateId }),
99
+ ],
100
+ [
101
+ "LionWebKey",
102
+ PrimitiveDef({ primitiveType: "string", validate: validateKey }),
103
+ ],
104
+ [
105
+ "LionWebVersion",
106
+ PrimitiveDef({ primitiveType: "string", validate: validateVersion }),
107
+ ],
108
+ [
109
+ "LionWebSerializationFormatVersion",
110
+ PrimitiveDef({ primitiveType: "string", validate: validateSerializationFormatVersion }),
111
+ ],
112
+ [
113
+ "string",
114
+ PrimitiveDef({ primitiveType: "string" }),
115
+ ],
116
+ ])
117
+
118
+
119
+
120
+
@@ -30,19 +30,17 @@ import {
30
30
  M3_Keys
31
31
  } from "../json/M3definitions.js"
32
32
  import { LanguageRegistry } from "../languages/index.js"
33
- import { SimpleFieldValidator } from "./SimpleFieldValidator.js"
34
- import { ValidationResult } from "./ValidationResult.js"
33
+ import { validateBoolean, validateInteger, validateJSON } from "./ValidationFunctions.js"
34
+ import { ValidationResult } from "./generic/ValidationResult.js"
35
35
 
36
36
  /**
37
37
  * Check against the language definition
38
38
  */
39
39
  export class LionWebLanguageReferenceValidator {
40
40
  validationResult: ValidationResult
41
- simpleFieldValidator: SimpleFieldValidator
42
41
 
43
42
  constructor(validationResult: ValidationResult, private registry: LanguageRegistry) {
44
43
  this.validationResult = validationResult
45
- this.simpleFieldValidator = new SimpleFieldValidator(this.validationResult)
46
44
  }
47
45
 
48
46
  // reset() {
@@ -147,16 +145,16 @@ export class LionWebLanguageReferenceValidator {
147
145
  const typeReferenceId = refType.targets[0].reference
148
146
  switch (typeReferenceId) {
149
147
  case LIONWEB_BOOLEAN_TYPE:
150
- this.simpleFieldValidator.validateBoolean(prop, propertyName, context)
148
+ validateBoolean(prop.value, this.validationResult, context)
151
149
  break
152
150
  case LIONWEB_INTEGER_TYPE:
153
- this.simpleFieldValidator.validateInteger(prop, propertyName, context)
151
+ validateInteger(prop.value, this.validationResult, context)
154
152
  break
155
153
  case LIONWEB_STRING_TYPE:
156
154
  // Each string is correct and having another JSON type is already captured
157
155
  break
158
156
  case LIONWEB_JSON_TYPE:
159
- this.simpleFieldValidator.validateJSON(prop, propertyName, context)
157
+ validateJSON(prop.value, this.validationResult, context)
160
158
  break
161
159
  default: {
162
160
  // Check for enumeration
@@ -5,7 +5,7 @@ import { JsonContext } from "../json/JsonContext.js"
5
5
  import { isLionWebM3Language, LionWebJsonChunk } from "../json/LionWebJson.js"
6
6
  import { LionWebJsonChunkWrapper } from "../json/LionWebJsonChunkWrapper.js"
7
7
  import { isConcept, LanguageRegistry } from "../languages/index.js"
8
- import { ValidationResult } from "./ValidationResult.js"
8
+ import { ValidationResult } from "./generic/ValidationResult.js"
9
9
 
10
10
  /**
11
11
  * Validates whether a chunk is a valid language definition
@@ -23,7 +23,7 @@ export class LionWebLanguageValidator {
23
23
  /**
24
24
  * Check whether the metamodel is a Language.
25
25
  * Assumption is that _chunk_ is already validated as a correct :LionWebJsonChunk
26
- * @param obj
26
+ * @param chunk
27
27
  */
28
28
  validateLanguage(chunk: LionWebJsonChunk) {
29
29
  this.chunkWrapper = new LionWebJsonChunkWrapper(chunk)
@@ -16,8 +16,7 @@ import {
16
16
  LwJsonUsedLanguage,
17
17
  } from "../json/LionWebJson.js"
18
18
  import { LionWebJsonChunkWrapper } from "../json/LionWebJsonChunkWrapper.js"
19
- import { SimpleFieldValidator } from "./SimpleFieldValidator.js"
20
- import { ValidationResult } from "./ValidationResult.js"
19
+ import { ValidationResult } from "./generic/ValidationResult.js"
21
20
 
22
21
  /**
23
22
  * Assuming that the syntax is correct, check whether all LionWeb references are correct,
@@ -26,11 +25,9 @@ import { ValidationResult } from "./ValidationResult.js"
26
25
  export class LionWebReferenceValidator {
27
26
  validationResult: ValidationResult
28
27
  nodesIdMap: Map<string, LionWebJsonNode> = new Map<string, LionWebJsonNode>()
29
- simpleFieldValidator: SimpleFieldValidator
30
28
 
31
29
  constructor(validationResult: ValidationResult) {
32
30
  this.validationResult = validationResult
33
- this.simpleFieldValidator = new SimpleFieldValidator(this.validationResult)
34
31
  }
35
32
 
36
33
  validateNodeIds(obj: LionWebJsonChunk, ctx: JsonContext): void {
@@ -158,7 +155,8 @@ export class LionWebReferenceValidator {
158
155
 
159
156
  /**
160
157
  * Checks whether the parent of node recursively points to `node` itself.
161
- * @param node
158
+ * @param node The noide being checked
159
+ * @param context The location in the JSON
162
160
  */
163
161
  checkParentCircular(node: LionWebJsonNode, context: JsonContext) {
164
162
  if (node === null || node === undefined) {
@@ -1,308 +1,14 @@
1
- import {
2
- Syntax_ArrayContainsNull_Issue,
3
- Syntax_PropertyMissingIssue,
4
- Syntax_PropertyNullIssue,
5
- Syntax_PropertyTypeIssue,
6
- Syntax_PropertyUnknownIssue,
7
- } from "../issues/SyntaxIssues.js"
8
- import { SimpleFieldValidator, ValidatorFunction } from "./SimpleFieldValidator.js"
9
- import { JsonContext } from "../json/JsonContext.js"
10
- import { ValidationResult } from "./ValidationResult.js"
11
-
12
- export type UnknownObjectType = { [key: string]: unknown }
13
-
14
- export type PropertyType = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "array"
15
-
16
- export type PropertyDefinition = {
17
- /**
18
- * The property name
19
- */
20
- property: string
21
- /**
22
- * The expected type of the property value
23
- */
24
- expectedType: PropertyType
25
- /**
26
- * Whether the property value is allowed to be null
27
- */
28
- mayBeNull: boolean
29
- /**
30
- * If the property type is correct, check its value further with this function.
31
- * Will, only be called if `this.recursive === true`.
32
- * If the property value is an Array, the `checkValue` will be called on each element in the array.
33
- * @param obj
34
- * @param ctx
35
- */
36
- validateValue?: ValidatorFunction
37
- }
38
-
39
- // Make boolean argument more readable.
40
- const MAY_BE_NULL = true
41
- const NOT_NULL = false
1
+ import { expectedTypes } from "./LionWebChunkDefinitions.js"
2
+ import { SyntaxValidator } from "./generic/SyntaxValidator.js"
3
+ import { ValidationResult } from "./generic/ValidationResult.js"
42
4
 
43
5
  /**
44
- * LionWebCheck can check whether objects are structurally LionWeb JSON objects.
45
- * The check can be on a single object, or recursively on an object and its children.
6
+ * LionWebSyntaxValidator can check whether objects are structurally LionWeb objects.
46
7
  */
47
- export class LionWebSyntaxValidator {
48
- validationResult: ValidationResult
49
- simpleFieldValidator: SimpleFieldValidator
50
- /**
51
- * When true, each function will work recursively on the given object.
52
- * When false, will only check the given object.
53
- * Metapointers are always checked as part of the object, disregarding the va;lue of `recursive`.
54
- */
55
- recursive: boolean = true
8
+ export class LionWebSyntaxValidator extends SyntaxValidator {
56
9
 
57
10
  constructor(validationResult: ValidationResult) {
58
- this.validationResult = validationResult
59
- this.simpleFieldValidator = new SimpleFieldValidator(this.validationResult)
60
- }
61
-
62
- /**
63
- * Check whether `obj` is a JSON object that conforms to the serialization syntax of LionCore.
64
- * All errors found will be pushed into the `errors` array, if its length is not 0, the check has failed.
65
- * @param obj
66
- */
67
- validate(obj: unknown) {
68
- this.validateLwChunk(obj, new JsonContext(null, ["$"]))
69
- }
70
-
71
- validateLwChunk = (obj: unknown, ctx: JsonContext): void => {
72
- const expected: PropertyDefinition[] = [
73
- {
74
- property: "serializationFormatVersion",
75
- expectedType: "string",
76
- mayBeNull: NOT_NULL,
77
- validateValue: this.simpleFieldValidator.validateSerializationFormatVersion,
78
- },
79
- { property: "languages", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwUsedLanguage },
80
- { property: "nodes", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwNode },
81
- ]
82
- this.propertyChecks(obj, expected, ctx)
83
- }
84
-
85
- validateLwUsedLanguage = (obj: unknown, ctx: JsonContext): void => {
86
- const expected: PropertyDefinition[] = [
87
- { property: "key", expectedType: "string", mayBeNull: NOT_NULL, validateValue: this.simpleFieldValidator.validateKey },
88
- { property: "version", expectedType: "string", mayBeNull: NOT_NULL, validateValue: this.simpleFieldValidator.validateVersion },
89
- ]
90
- // if (this.checkType(obj, "object", ctx)) {
91
- this.propertyChecks(obj, expected, ctx)
92
- // }
93
- }
94
-
95
- validateLwNode = (obj: unknown, ctx: JsonContext): void => {
96
- const expected: PropertyDefinition[] = [
97
- { property: "id", expectedType: "string", mayBeNull: NOT_NULL, validateValue: this.simpleFieldValidator.validateId },
98
- { property: "classifier", expectedType: "object", mayBeNull: NOT_NULL, validateValue: this.validateLwMetaPointer },
99
- { property: "properties", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwProperty },
100
- { property: "containments", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwChild },
101
- { property: "references", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwReference },
102
- { property: "annotations", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwAnnotation },
103
- { property: "parent", expectedType: "string", mayBeNull: MAY_BE_NULL, validateValue: this.simpleFieldValidator.validateId },
104
- ]
105
- this.propertyChecks(obj, expected, ctx)
106
- }
107
-
108
- validateLwAnnotation = (obj: unknown, context: JsonContext) => {
109
- if (this.checkType(obj, "string", context)) {
110
- this.simpleFieldValidator.validateId(obj as string, context)
111
- }
112
- }
113
-
114
- validateLwProperty = (obj: unknown, ctx: JsonContext): void => {
115
- const expected: PropertyDefinition[] = [
116
- { property: "property", expectedType: "object", mayBeNull: NOT_NULL, validateValue: this.validateLwMetaPointer },
117
- { property: "value", expectedType: "string", mayBeNull: MAY_BE_NULL },
118
- ]
119
- this.propertyChecks(obj, expected, ctx)
120
- // TODO: hack for keys in M2 models
121
- // if ((obj as any)["property"].key === "IKeyed-key") {
122
- // // console.log("CHECKING KEY");
123
- // this.simpleFieldValidator.validateKey((obj as any)["value"], ctx);
124
- // }
125
- }
126
-
127
- validateLwMetaPointer = (obj: unknown, ctx: JsonContext): void => {
128
- const expected: PropertyDefinition[] = [
129
- { property: "key", expectedType: "string", mayBeNull: NOT_NULL, validateValue: this.simpleFieldValidator.validateKey },
130
- {
131
- property: "version",
132
- expectedType: "string",
133
- mayBeNull: MAY_BE_NULL,
134
- validateValue: this.simpleFieldValidator.validateVersion,
135
- },
136
- { property: "language", expectedType: "string", mayBeNull: MAY_BE_NULL, validateValue: this.simpleFieldValidator.validateKey },
137
- ]
138
- this.propertyChecks(obj, expected, ctx)
139
- }
140
-
141
- validateLwChild = (obj: unknown, ctx: JsonContext): void => {
142
- const expected: PropertyDefinition[] = [
143
- { property: "containment", expectedType: "object", mayBeNull: NOT_NULL, validateValue: this.validateLwMetaPointer },
144
- { property: "children", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.checkChild },
145
- ]
146
- this.propertyChecks(obj, expected, ctx)
147
- }
148
-
149
- private checkChild = (obj: unknown, context: JsonContext) => {
150
- if (this.checkType(obj, "string", context)) {
151
- this.simpleFieldValidator.validateId(obj as string, context)
152
- }
153
- }
154
-
155
- /** Checks whether `obj` is not null or defined and has the correct type.
156
- */
157
- private checkType = (obj: unknown, expectedType: PropertyType, context: JsonContext): boolean => {
158
- if (obj === null || obj === undefined) {
159
- this.validationResult.issue(new Syntax_PropertyTypeIssue(context, "obj", expectedType, typeof obj))
160
- return false
161
- } else if (typeof obj !== expectedType) {
162
- // TODO Better context: where does obj come from
163
- this.validationResult.issue(new Syntax_PropertyTypeIssue(context, "obj", expectedType, typeof obj))
164
- return false
165
- }
166
- return true
167
- }
168
-
169
- validateLwReference = (obj: unknown, ctx: JsonContext): void => {
170
- const expected: PropertyDefinition[] = [
171
- { property: "reference", expectedType: "object", mayBeNull: NOT_NULL, validateValue: this.validateLwMetaPointer },
172
- { property: "targets", expectedType: "array", mayBeNull: NOT_NULL, validateValue: this.validateLwReferenceTarget },
173
- ]
174
- this.propertyChecks(obj, expected, ctx)
175
- }
176
-
177
- validateLwReferenceTarget = (obj: unknown, ctx: JsonContext): void => {
178
- const expected: PropertyDefinition[] = [
179
- { property: "resolveInfo", expectedType: "string", mayBeNull: MAY_BE_NULL },
180
- { property: "reference", expectedType: "string", mayBeNull: MAY_BE_NULL, validateValue: this.simpleFieldValidator.validateId },
181
- ]
182
- this.propertyChecks(obj, expected, ctx)
183
- }
184
-
185
- /**
186
- * Check whether all property definitions in `propDef` are correct and check that there are
187
- * no iother properties in `obj`.
188
- * @param obj
189
- * @param propDefs
190
- * @param context
191
- */
192
- propertyChecks(obj: unknown, propDefs: PropertyDefinition[], context: JsonContext): void {
193
- if (!this.checkType(obj, "object", context)) {
194
- return
195
- }
196
- const object = obj as UnknownObjectType
197
- const allProperties: string[] = []
198
- propDefs.forEach(propDef => {
199
- if (propDef.property === "key") {
200
- // console.log("CHECKING KEY of " + JSON.stringify(obj))
201
- }
202
- if (
203
- this.checkPropertyType(object, propDef.property, propDef.expectedType, propDef.mayBeNull, context.concat(propDef.property))
204
- ) {
205
- const propValue = object[propDef.property]
206
- if (this.recursive && propDef.expectedType === "array" && Array.isArray(propValue) && !!propDef.validateValue) {
207
- propValue.forEach((arrayItem: unknown, index: number) => {
208
- if (arrayItem === null) {
209
- this.validationResult.issue(
210
- new Syntax_ArrayContainsNull_Issue(context.concat(propDef.property, index), propDef.property, index),
211
- )
212
- } else {
213
- if (propDef.validateValue !== null && propDef.validateValue !== undefined) {
214
- propDef.validateValue(arrayItem, context.concat(propDef.property, index))
215
- } else {
216
- // TODO: give an error, whih ine?
217
- }
218
- }
219
- })
220
- } else if (propDef.validateValue !== null && propDef.validateValue !== undefined) {
221
- // propValue is niot an array, so it should be aa string
222
- propDef.validateValue(propValue as string, context.concat(propDef.property))
223
- }
224
- }
225
- allProperties.push(propDef.property)
226
- })
227
- this.checkStrayProperties(object, allProperties, context)
228
- }
229
-
230
- /**
231
- * Check whether there are extra properties that should not be there.
232
- * @param obj
233
- * @param properties
234
- * @param context
235
- */
236
- checkStrayProperties(obj: UnknownObjectType, properties: string[], context: JsonContext) {
237
- const own = Object.getOwnPropertyNames(obj)
238
- own.forEach(ownProp => {
239
- if (!properties.includes(ownProp)) {
240
- this.validationResult.issue(new Syntax_PropertyUnknownIssue(context, ownProp))
241
- }
242
- })
243
- properties.forEach(prop => {
244
- if (!own.includes(prop)) {
245
- this.validationResult.issue(new Syntax_PropertyMissingIssue(context, prop))
246
- }
247
- })
248
- }
249
-
250
- /**
251
- * Check whether the value of property `prop` of `obj` has type `expectedType`.
252
- * @param obj
253
- * @param prop
254
- * @param expectedType
255
- * @param context
256
- */
257
- checkPropertyType = (
258
- obj: UnknownObjectType,
259
- prop: string,
260
- expectedType: PropertyType,
261
- mayBeNull: boolean,
262
- context: JsonContext,
263
- ): boolean => {
264
- if (prop === "key") {
265
- // console.log(" checking type of key " + JSON.stringify(obj));
266
- }
267
- if (obj[prop] === undefined || obj[prop] === null) {
268
- if (!mayBeNull) {
269
- this.validationResult.issue(new Syntax_PropertyNullIssue(context, prop))
270
- return false
271
- } else {
272
- return true
273
- }
274
- } else {
275
- const actualType = typeof obj[prop]
276
- if (expectedType !== actualType) {
277
- if (expectedType === "array" && actualType === "object") {
278
- // typeof returns an object for an array, so we need to check this separately.
279
- if (!Array.isArray(obj[prop])) {
280
- this.validationResult.issue(new Syntax_PropertyTypeIssue(context, prop, "array", typeof obj[prop]))
281
- return false
282
- } else {
283
- return true
284
- }
285
- } else {
286
- this.validationResult.issue(new Syntax_PropertyTypeIssue(context, prop, expectedType, actualType))
287
- return false
288
- }
289
- } else {
290
- if (expectedType === "object") {
291
- // typeof returns an object for an array, so we need to check this separately.
292
- if (Array.isArray(obj[prop])) {
293
- this.validationResult.issue(new Syntax_PropertyTypeIssue(context, prop, expectedType, "array"))
294
- return false
295
- }
296
- }
297
- }
298
- }
299
- return true
11
+ super(validationResult, expectedTypes)
300
12
  }
301
13
  }
302
14
 
303
- export function SyntaxValidator(jsonChunk: unknown): ValidationResult {
304
- const validationResult = new ValidationResult()
305
- const syntaxValidator = new LionWebSyntaxValidator(validationResult)
306
- syntaxValidator.validate(jsonChunk)
307
- return validationResult
308
- }
@@ -4,7 +4,7 @@ import { LanguageRegistry } from "../languages/index.js"
4
4
  import { LionWebLanguageReferenceValidator } from "./LionWebLanguageReferenceValidator.js"
5
5
  import { LionWebReferenceValidator } from "./LionWebReferenceValidator.js"
6
6
  import { LionWebSyntaxValidator } from "./LionWebSyntaxValidator.js"
7
- import { ValidationResult } from "./ValidationResult.js"
7
+ import { ValidationResult } from "./generic/ValidationResult.js"
8
8
 
9
9
  /**
10
10
  * Combined validator that calls all available validators.
@@ -34,8 +34,7 @@ export class LionWebValidator {
34
34
  }
35
35
 
36
36
  validateSyntax() {
37
- this.syntaxValidator.recursive = true
38
- this.syntaxValidator.validate(this.object)
37
+ this.syntaxValidator.validate(this.object, "LionWebChunk")
39
38
  this.syntaxCorrect = !this.validationResult.hasErrors()
40
39
  if (this.syntaxCorrect) {
41
40
  this.chunk = new LionWebJsonChunkWrapper(this.object as LionWebJsonChunk)
@@ -0,0 +1,135 @@
1
+ /**
2
+ * A list of functions that are used to validate primitive fields for LionWeb conformance.
3
+ * Used in the LionWebSyntaxValidator.
4
+ */
5
+ import { Language_PropertyValue_Issue } from "../issues/LanguageIssues.js"
6
+ import {
7
+ Syntax_IdFormat_Issue,
8
+ Syntax_KeyFormat_Issue,
9
+ Syntax_PropertyNullIssue,
10
+ Syntax_SerializationFormatVersion_Issue,
11
+ Syntax_VersionFormat_Issue
12
+ } from "../issues/SyntaxIssues.js"
13
+ import { JsonContext } from "../json/JsonContext.js"
14
+ import { ValidationResult } from "./generic/ValidationResult.js"
15
+ import { PropertyDefinition } from "./generic/ValidationTypes.js"
16
+
17
+ /**
18
+ * Check whether `id` is a valid LionWeb id.
19
+ * @param value The `value` to be checked.
20
+ * @param result Any validation issues found will be put into this object.
21
+ * @param context The context for the error message in errors.
22
+ */
23
+ // eslint-disable-next-line @typescript-eslint/ban-types
24
+ export function validateId<String>(value: String, result: ValidationResult, context: JsonContext): void {
25
+ const idString: string = "" + value
26
+ const regexp = /^[a-zA-Z0-9_-][a-zA-Z0-9_-]*$/
27
+ if (!regexp.test(idString)) {
28
+ result.issue(new Syntax_IdFormat_Issue(context, idString))
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check whether `key` is a valid LionWeb key.
34
+ * @param value The `key` to be checked.
35
+ * @param result Any validation issues found will be put into this object.
36
+ * @param context The context for the error message in errors.
37
+ */
38
+ // eslint-disable-next-line @typescript-eslint/ban-types
39
+ export function validateKey<String>(value: String, result: ValidationResult, context: JsonContext): void {
40
+ const keyString: string = "" + value
41
+ const regexp = /^[a-zA-Z0-9_-][a-zA-Z0-9_-]*$/
42
+ if (!regexp.test(keyString)) {
43
+ result.issue(new Syntax_KeyFormat_Issue(context, keyString))
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Check whether `version` is a valid LionWeb version.
49
+ * @param value The version to be checked
50
+ * @param result Any validation issues found will be put into this object.
51
+ * @param context The location in the overall JSON.
52
+ */
53
+ // eslint-disable-next-line @typescript-eslint/ban-types
54
+ export function validateVersion<String>(value: String, result: ValidationResult, context: JsonContext): void {
55
+ const versionString: string = "" + value
56
+ if (versionString.length === 0) {
57
+ result.issue(new Syntax_VersionFormat_Issue(context, versionString))
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Check whether the string `value` represents a LionWeb boolean, its value should be "true" or "false".
63
+ * @param value The value to be checked
64
+ * @param result Any validation issues found will be put into this object.
65
+ * @param context The location in the overall JSON.
66
+ * @param propDef The PropertyDefinition for this value
67
+ */
68
+ // eslint-disable-next-line @typescript-eslint/ban-types
69
+ export function validateBoolean<String>(value: String, result: ValidationResult, context: JsonContext, propDef?: PropertyDefinition): void {
70
+ const valueAsPrimitive = "" + value
71
+ if (valueAsPrimitive !== "true" && valueAsPrimitive !== "false") {
72
+ result.issue(
73
+ new Language_PropertyValue_Issue(
74
+ context,
75
+ propDef ? propDef.property : "unknown",
76
+ valueAsPrimitive,
77
+ "boolean " + JSON.stringify(value)
78
+ )
79
+ )
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Check whether the string `value` represents a LionWeb integer
85
+ * @param value The value to be checked
86
+ * @param result Any validation issues found will be put into this object.
87
+ * @param context The location in the overall JSON.
88
+ * @param propDef The PropertyDefinition for this value
89
+ */
90
+ // eslint-disable-next-line @typescript-eslint/ban-types
91
+ export function validateInteger<String>(value: String, result: ValidationResult, context: JsonContext, propDef?: PropertyDefinition): void {
92
+ const valueAsPrimitive = "" + value
93
+ const regexp = /^[+-]?(0|[1-9][0-9]*)$/
94
+ if (valueAsPrimitive === null || !regexp.test(valueAsPrimitive)) {
95
+ result.issue(new Language_PropertyValue_Issue(context, propDef ? propDef.property : "unknown", valueAsPrimitive, "integer"))
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Check whether the string `value` represents a LionWeb Json.
101
+ * @param value The value to be checked
102
+ * @param result Any validation issues found will be put into this object.
103
+ * @param context The location in the overall JSON.
104
+ * @param propDef The PropertyDefinition for this value
105
+ */
106
+ // eslint-disable-next-line @typescript-eslint/ban-types
107
+ export function validateJSON<String>(value: String, result: ValidationResult, context: JsonContext, propDef?: PropertyDefinition): void {
108
+ const valueAsPrimitive = "" + value
109
+ if (value === null) {
110
+ result.issue(new Syntax_PropertyNullIssue(context, propDef!.property!))
111
+ }
112
+ try {
113
+ JSON.parse(valueAsPrimitive)
114
+ } catch (e) {
115
+ result.issue(new Language_PropertyValue_Issue(context, propDef ? propDef.property : "unknown", valueAsPrimitive, "JSON"))
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Check whether the string `value` is a correct LionWeb serializationFormatVersion.
121
+ * @param value
122
+ * @param result
123
+ * @param context
124
+ */
125
+ // eslint-disable-next-line @typescript-eslint/ban-types
126
+ export function validateSerializationFormatVersion<String>(value: String, result: ValidationResult, context: JsonContext): void {
127
+ if (typeof value !== "string") {
128
+ result.issue(new Syntax_SerializationFormatVersion_Issue(context, JSON.stringify(value)))
129
+ return
130
+ }
131
+ if (value.length === 0) {
132
+ result.issue(new Syntax_SerializationFormatVersion_Issue(context, value))
133
+ return
134
+ }
135
+ }