@contember/schema-utils 2.1.0-beta.2 → 2.2.0-alpha.2

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 (247) hide show
  1. package/dist/development/index.cjs +11 -0
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +11 -0
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/acl/PredicateDefinitionProcessor.cjs.map +1 -1
  6. package/dist/development/src/acl/PredicateDefinitionProcessor.js.map +1 -1
  7. package/dist/development/src/dataUtils.cjs +1 -0
  8. package/dist/development/src/dataUtils.cjs.map +1 -1
  9. package/dist/development/src/dataUtils.js +1 -0
  10. package/dist/development/src/dataUtils.js.map +1 -1
  11. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.cjs.map +1 -1
  12. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.js.map +1 -1
  13. package/dist/development/src/definition-generator/DefinitionCodeGenerator.cjs +37 -2
  14. package/dist/development/src/definition-generator/DefinitionCodeGenerator.cjs.map +1 -1
  15. package/dist/development/src/definition-generator/DefinitionCodeGenerator.js +37 -2
  16. package/dist/development/src/definition-generator/DefinitionCodeGenerator.js.map +1 -1
  17. package/dist/development/src/definition-generator/TsDefinitionGenerator.cjs.map +1 -1
  18. package/dist/development/src/definition-generator/TsDefinitionGenerator.js.map +1 -1
  19. package/dist/development/src/json-schema/collectUnsupportedKeywords.cjs +45 -0
  20. package/dist/development/src/json-schema/collectUnsupportedKeywords.cjs.map +1 -0
  21. package/dist/development/src/json-schema/collectUnsupportedKeywords.js +45 -0
  22. package/dist/development/src/json-schema/collectUnsupportedKeywords.js.map +1 -0
  23. package/dist/development/src/json-schema/jsonSchemaToTsType.cjs +138 -0
  24. package/dist/development/src/json-schema/jsonSchemaToTsType.cjs.map +1 -0
  25. package/dist/development/src/json-schema/jsonSchemaToTsType.js +138 -0
  26. package/dist/development/src/json-schema/jsonSchemaToTsType.js.map +1 -0
  27. package/dist/development/src/json-schema/keywords.cjs +57 -0
  28. package/dist/development/src/json-schema/keywords.cjs.map +1 -0
  29. package/dist/development/src/json-schema/keywords.js +57 -0
  30. package/dist/development/src/json-schema/keywords.js.map +1 -0
  31. package/dist/development/src/lax/LaxSchemaConverter.cjs.map +1 -1
  32. package/dist/development/src/lax/LaxSchemaConverter.js.map +1 -1
  33. package/dist/development/src/model/modelUtils.cjs.map +1 -1
  34. package/dist/development/src/model/modelUtils.js.map +1 -1
  35. package/dist/development/src/model/resolveDefaultColumnType.cjs +2 -0
  36. package/dist/development/src/model/resolveDefaultColumnType.cjs.map +1 -1
  37. package/dist/development/src/model/resolveDefaultColumnType.js +2 -0
  38. package/dist/development/src/model/resolveDefaultColumnType.js.map +1 -1
  39. package/dist/development/src/schemaNormalizer.cjs.map +1 -1
  40. package/dist/development/src/schemaNormalizer.js.map +1 -1
  41. package/dist/development/src/type-schema/acl.cjs.map +1 -1
  42. package/dist/development/src/type-schema/acl.js.map +1 -1
  43. package/dist/development/src/type-schema/condition.cjs +6 -1
  44. package/dist/development/src/type-schema/condition.cjs.map +1 -1
  45. package/dist/development/src/type-schema/condition.js +6 -1
  46. package/dist/development/src/type-schema/condition.js.map +1 -1
  47. package/dist/development/src/type-schema/model.cjs +14 -2
  48. package/dist/development/src/type-schema/model.cjs.map +1 -1
  49. package/dist/development/src/type-schema/model.js +14 -2
  50. package/dist/development/src/type-schema/model.js.map +1 -1
  51. package/dist/development/src/type-schema/settings.cjs +1 -0
  52. package/dist/development/src/type-schema/settings.cjs.map +1 -1
  53. package/dist/development/src/type-schema/settings.js +1 -0
  54. package/dist/development/src/type-schema/settings.js.map +1 -1
  55. package/dist/development/src/type-schema/where.cjs.map +1 -1
  56. package/dist/development/src/type-schema/where.js.map +1 -1
  57. package/dist/development/src/validation/AclValidator.cjs.map +1 -1
  58. package/dist/development/src/validation/AclValidator.js.map +1 -1
  59. package/dist/development/src/validation/ActionsValidator.cjs.map +1 -1
  60. package/dist/development/src/validation/ActionsValidator.js.map +1 -1
  61. package/dist/development/src/validation/MembershipResolver.cjs.map +1 -1
  62. package/dist/development/src/validation/MembershipResolver.js.map +1 -1
  63. package/dist/development/src/validation/ModelValidator.cjs +66 -0
  64. package/dist/development/src/validation/ModelValidator.cjs.map +1 -1
  65. package/dist/development/src/validation/ModelValidator.js +66 -0
  66. package/dist/development/src/validation/ModelValidator.js.map +1 -1
  67. package/dist/development/src/validation/SchemaValidator.cjs.map +1 -1
  68. package/dist/development/src/validation/SchemaValidator.js.map +1 -1
  69. package/dist/development/src/validation/ValidationValidator.cjs.map +1 -1
  70. package/dist/development/src/validation/ValidationValidator.js.map +1 -1
  71. package/dist/development/src/validation/errors.cjs.map +1 -1
  72. package/dist/development/src/validation/errors.js.map +1 -1
  73. package/dist/production/index.cjs +11 -0
  74. package/dist/production/index.cjs.map +1 -1
  75. package/dist/production/index.js +11 -0
  76. package/dist/production/index.js.map +1 -1
  77. package/dist/production/src/acl/PredicateDefinitionProcessor.cjs.map +1 -1
  78. package/dist/production/src/acl/PredicateDefinitionProcessor.js.map +1 -1
  79. package/dist/production/src/dataUtils.cjs +1 -0
  80. package/dist/production/src/dataUtils.cjs.map +1 -1
  81. package/dist/production/src/dataUtils.js +1 -0
  82. package/dist/production/src/dataUtils.js.map +1 -1
  83. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.cjs.map +1 -1
  84. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.js.map +1 -1
  85. package/dist/production/src/definition-generator/DefinitionCodeGenerator.cjs +37 -2
  86. package/dist/production/src/definition-generator/DefinitionCodeGenerator.cjs.map +1 -1
  87. package/dist/production/src/definition-generator/DefinitionCodeGenerator.js +37 -2
  88. package/dist/production/src/definition-generator/DefinitionCodeGenerator.js.map +1 -1
  89. package/dist/production/src/definition-generator/TsDefinitionGenerator.cjs.map +1 -1
  90. package/dist/production/src/definition-generator/TsDefinitionGenerator.js.map +1 -1
  91. package/dist/production/src/json-schema/collectUnsupportedKeywords.cjs +45 -0
  92. package/dist/production/src/json-schema/collectUnsupportedKeywords.cjs.map +1 -0
  93. package/dist/production/src/json-schema/collectUnsupportedKeywords.js +45 -0
  94. package/dist/production/src/json-schema/collectUnsupportedKeywords.js.map +1 -0
  95. package/dist/production/src/json-schema/jsonSchemaToTsType.cjs +138 -0
  96. package/dist/production/src/json-schema/jsonSchemaToTsType.cjs.map +1 -0
  97. package/dist/production/src/json-schema/jsonSchemaToTsType.js +138 -0
  98. package/dist/production/src/json-schema/jsonSchemaToTsType.js.map +1 -0
  99. package/dist/production/src/json-schema/keywords.cjs +57 -0
  100. package/dist/production/src/json-schema/keywords.cjs.map +1 -0
  101. package/dist/production/src/json-schema/keywords.js +57 -0
  102. package/dist/production/src/json-schema/keywords.js.map +1 -0
  103. package/dist/production/src/lax/LaxSchemaConverter.cjs.map +1 -1
  104. package/dist/production/src/lax/LaxSchemaConverter.js.map +1 -1
  105. package/dist/production/src/model/modelUtils.cjs.map +1 -1
  106. package/dist/production/src/model/modelUtils.js.map +1 -1
  107. package/dist/production/src/model/resolveDefaultColumnType.cjs +2 -0
  108. package/dist/production/src/model/resolveDefaultColumnType.cjs.map +1 -1
  109. package/dist/production/src/model/resolveDefaultColumnType.js +2 -0
  110. package/dist/production/src/model/resolveDefaultColumnType.js.map +1 -1
  111. package/dist/production/src/schemaNormalizer.cjs.map +1 -1
  112. package/dist/production/src/schemaNormalizer.js.map +1 -1
  113. package/dist/production/src/type-schema/acl.cjs.map +1 -1
  114. package/dist/production/src/type-schema/acl.js.map +1 -1
  115. package/dist/production/src/type-schema/condition.cjs +6 -1
  116. package/dist/production/src/type-schema/condition.cjs.map +1 -1
  117. package/dist/production/src/type-schema/condition.js +6 -1
  118. package/dist/production/src/type-schema/condition.js.map +1 -1
  119. package/dist/production/src/type-schema/model.cjs +14 -2
  120. package/dist/production/src/type-schema/model.cjs.map +1 -1
  121. package/dist/production/src/type-schema/model.js +14 -2
  122. package/dist/production/src/type-schema/model.js.map +1 -1
  123. package/dist/production/src/type-schema/settings.cjs +1 -0
  124. package/dist/production/src/type-schema/settings.cjs.map +1 -1
  125. package/dist/production/src/type-schema/settings.js +1 -0
  126. package/dist/production/src/type-schema/settings.js.map +1 -1
  127. package/dist/production/src/type-schema/where.cjs.map +1 -1
  128. package/dist/production/src/type-schema/where.js.map +1 -1
  129. package/dist/production/src/validation/AclValidator.cjs.map +1 -1
  130. package/dist/production/src/validation/AclValidator.js.map +1 -1
  131. package/dist/production/src/validation/ActionsValidator.cjs.map +1 -1
  132. package/dist/production/src/validation/ActionsValidator.js.map +1 -1
  133. package/dist/production/src/validation/MembershipResolver.cjs.map +1 -1
  134. package/dist/production/src/validation/MembershipResolver.js.map +1 -1
  135. package/dist/production/src/validation/ModelValidator.cjs +66 -0
  136. package/dist/production/src/validation/ModelValidator.cjs.map +1 -1
  137. package/dist/production/src/validation/ModelValidator.js +66 -0
  138. package/dist/production/src/validation/ModelValidator.js.map +1 -1
  139. package/dist/production/src/validation/SchemaValidator.cjs.map +1 -1
  140. package/dist/production/src/validation/SchemaValidator.js.map +1 -1
  141. package/dist/production/src/validation/ValidationValidator.cjs.map +1 -1
  142. package/dist/production/src/validation/ValidationValidator.js.map +1 -1
  143. package/dist/production/src/validation/errors.cjs.map +1 -1
  144. package/dist/production/src/validation/errors.js.map +1 -1
  145. package/dist/tests/cases/unit/jsonSchemaKeywords.test.d.ts +2 -0
  146. package/dist/tests/cases/unit/jsonSchemaKeywords.test.d.ts.map +1 -0
  147. package/dist/tests/cases/unit/jsonSchemaToTsType.test.d.ts +2 -0
  148. package/dist/tests/cases/unit/jsonSchemaToTsType.test.d.ts.map +1 -0
  149. package/dist/tests/cases/unit/numericColumnCodeGenerator.test.d.ts +2 -0
  150. package/dist/tests/cases/unit/numericColumnCodeGenerator.test.d.ts.map +1 -0
  151. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  152. package/dist/types/acl/index.d.ts +3 -3
  153. package/dist/types/acl/index.d.ts.map +1 -1
  154. package/dist/types/dataUtils.d.ts.map +1 -1
  155. package/dist/types/definition-generator/AclDefinitionCodeGenerator.d.ts +1 -1
  156. package/dist/types/definition-generator/AclDefinitionCodeGenerator.d.ts.map +1 -1
  157. package/dist/types/definition-generator/DefinitionCodeGenerator.d.ts +3 -3
  158. package/dist/types/definition-generator/DefinitionCodeGenerator.d.ts.map +1 -1
  159. package/dist/types/definition-generator/TsDefinitionGenerator.d.ts +1 -1
  160. package/dist/types/definition-generator/TsDefinitionGenerator.d.ts.map +1 -1
  161. package/dist/types/definition-generator/index.d.ts +4 -4
  162. package/dist/types/definition-generator/index.d.ts.map +1 -1
  163. package/dist/types/index.d.ts +11 -10
  164. package/dist/types/index.d.ts.map +1 -1
  165. package/dist/types/json-schema/collectUnsupportedKeywords.d.ts +20 -0
  166. package/dist/types/json-schema/collectUnsupportedKeywords.d.ts.map +1 -0
  167. package/dist/types/json-schema/index.d.ts +4 -0
  168. package/dist/types/json-schema/index.d.ts.map +1 -0
  169. package/dist/types/json-schema/jsonSchemaToTsType.d.ts +24 -0
  170. package/dist/types/json-schema/jsonSchemaToTsType.d.ts.map +1 -0
  171. package/dist/types/json-schema/keywords.d.ts +28 -0
  172. package/dist/types/json-schema/keywords.d.ts.map +1 -0
  173. package/dist/types/lax/LaxSchemaConverter.d.ts +2 -2
  174. package/dist/types/lax/LaxSchemaConverter.d.ts.map +1 -1
  175. package/dist/types/lax/index.d.ts +2 -2
  176. package/dist/types/lax/index.d.ts.map +1 -1
  177. package/dist/types/model/index.d.ts +3 -3
  178. package/dist/types/model/index.d.ts.map +1 -1
  179. package/dist/types/model/resolveDefaultColumnType.d.ts.map +1 -1
  180. package/dist/types/tsconfig.tsbuildinfo +1 -1
  181. package/dist/types/type-schema/index.d.ts +5 -5
  182. package/dist/types/type-schema/index.d.ts.map +1 -1
  183. package/dist/types/type-schema/model.d.ts.map +1 -1
  184. package/dist/types/type-schema/settings.d.ts +3 -0
  185. package/dist/types/type-schema/settings.d.ts.map +1 -1
  186. package/dist/types/utils/index.d.ts +3 -3
  187. package/dist/types/utils/index.d.ts.map +1 -1
  188. package/dist/types/validation/AclValidator.d.ts +1 -1
  189. package/dist/types/validation/AclValidator.d.ts.map +1 -1
  190. package/dist/types/validation/ActionsValidator.d.ts +1 -1
  191. package/dist/types/validation/ActionsValidator.d.ts.map +1 -1
  192. package/dist/types/validation/ModelValidator.d.ts +3 -1
  193. package/dist/types/validation/ModelValidator.d.ts.map +1 -1
  194. package/dist/types/validation/SchemaValidator.d.ts +1 -1
  195. package/dist/types/validation/SchemaValidator.d.ts.map +1 -1
  196. package/dist/types/validation/ValidationValidator.d.ts +1 -1
  197. package/dist/types/validation/ValidationValidator.d.ts.map +1 -1
  198. package/dist/types/validation/errors.d.ts +1 -1
  199. package/dist/types/validation/errors.d.ts.map +1 -1
  200. package/dist/types/validation/index.d.ts +6 -6
  201. package/dist/types/validation/index.d.ts.map +1 -1
  202. package/package.json +4 -4
  203. package/src/acl/PredicateDefinitionProcessor.ts +1 -1
  204. package/src/acl/index.ts +3 -3
  205. package/src/dataUtils.ts +1 -0
  206. package/src/definition-generator/AclDefinitionCodeGenerator.ts +3 -3
  207. package/src/definition-generator/DefinitionCodeGenerator.ts +44 -7
  208. package/src/definition-generator/TsDefinitionGenerator.ts +2 -2
  209. package/src/definition-generator/index.ts +4 -4
  210. package/src/index.ts +14 -13
  211. package/src/json-schema/collectUnsupportedKeywords.ts +74 -0
  212. package/src/json-schema/index.ts +3 -0
  213. package/src/json-schema/jsonSchemaToTsType.ts +188 -0
  214. package/src/json-schema/keywords.ts +79 -0
  215. package/src/lax/LaxSchemaConverter.ts +3 -3
  216. package/src/lax/index.ts +2 -2
  217. package/src/model/index.ts +3 -3
  218. package/src/model/modelUtils.ts +1 -1
  219. package/src/model/resolveDefaultColumnType.ts +3 -1
  220. package/src/schemaNormalizer.ts +1 -1
  221. package/src/type-schema/acl.ts +1 -1
  222. package/src/type-schema/condition.ts +5 -0
  223. package/src/type-schema/index.ts +5 -5
  224. package/src/type-schema/model.ts +12 -0
  225. package/src/type-schema/settings.ts +1 -0
  226. package/src/type-schema/where.ts +2 -2
  227. package/src/utils/index.ts +3 -3
  228. package/src/validation/AclValidator.ts +4 -4
  229. package/src/validation/ActionsValidator.ts +4 -4
  230. package/src/validation/MembershipResolver.ts +3 -3
  231. package/src/validation/ModelValidator.ts +80 -2
  232. package/src/validation/SchemaValidator.ts +5 -5
  233. package/src/validation/ValidationValidator.ts +2 -2
  234. package/src/validation/errors.ts +2 -0
  235. package/src/validation/index.ts +6 -6
  236. package/tests/cases/unit/conditionSchema.test.ts +1 -1
  237. package/tests/cases/unit/deepCompare.test.ts +1 -1
  238. package/tests/cases/unit/jsonSchemaKeywords.test.ts +91 -0
  239. package/tests/cases/unit/jsonSchemaToTsType.test.ts +55 -0
  240. package/tests/cases/unit/laxSchemaConverter.test.ts +1 -1
  241. package/tests/cases/unit/membershipResolver.test.ts +1 -1
  242. package/tests/cases/unit/modelSchema.test.ts +1 -1
  243. package/tests/cases/unit/modelValidator.test.ts +246 -1
  244. package/tests/cases/unit/numericColumnCodeGenerator.test.ts +69 -0
  245. package/tests/cases/unit/printJsvalue.test.ts +1 -1
  246. package/tests/cases/unit/tsDefinitionGenerator.test.ts +46 -9
  247. package/tests/cases/unit/whereSchema.test.ts +2 -2
@@ -3,7 +3,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const schema = require("@contember/schema");
4
4
  const errors = require("./errors.cjs");
5
5
  const modelUtils = require("../model/modelUtils.cjs");
6
+ const keywords = require("../json-schema/keywords.cjs");
7
+ const collectUnsupportedKeywords = require("../json-schema/collectUnsupportedKeywords.cjs");
6
8
  const IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/;
9
+ const INDEX_OPCLASS_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9$]*(\.[_a-zA-Z][_a-zA-Z0-9$]*)?$/;
7
10
  const RESERVED_WORDS = ["and", "or", "not"];
8
11
  class ModelValidator {
9
12
  constructor(model) {
@@ -50,8 +53,58 @@ class ModelValidator {
50
53
  entity,
51
54
  errors2.for("unique")
52
55
  );
56
+ this.validateIndexes(
57
+ entity,
58
+ errors2.for("indexes")
59
+ );
53
60
  this.validateColumnNamesCollision(entity, errors2);
54
61
  }
62
+ validateIndexes(entity, errors2) {
63
+ for (const index of entity.indexes) {
64
+ for (const field of [...index.fields, ...index.include ?? []]) {
65
+ if (!entity.fields[field]) {
66
+ errors2.add("MODEL_UNDEFINED_FIELD", `Referenced field ${field} in an index does not exists`);
67
+ }
68
+ }
69
+ for (const field of index.include ?? []) {
70
+ if (index.fields.includes(field)) {
71
+ errors2.add("MODEL_INVALID_INDEX", `Field ${field} cannot be both an index key and an included (covering) column`);
72
+ }
73
+ }
74
+ for (const field of Object.keys(index.columnOptions ?? {})) {
75
+ if (!index.fields.includes(field)) {
76
+ errors2.add("MODEL_INVALID_INDEX", `Column options reference field ${field}, which is not a key column of the index`);
77
+ }
78
+ }
79
+ const seenFields = /* @__PURE__ */ new Set();
80
+ for (const field of index.fields) {
81
+ if (seenFields.has(field)) {
82
+ errors2.add("MODEL_INVALID_INDEX", `Field ${field} is listed more than once as an index key column`);
83
+ }
84
+ seenFields.add(field);
85
+ }
86
+ if (index.method !== void 0 && index.method !== "btree") {
87
+ for (const [field, options] of Object.entries(index.columnOptions ?? {})) {
88
+ if (options.order !== void 0 || options.nulls !== void 0) {
89
+ errors2.add("MODEL_INVALID_INDEX", `Column options (order/nulls) on field ${field} are only supported for btree indexes, not "${index.method}"`);
90
+ }
91
+ }
92
+ }
93
+ for (const opClass of [index.opClass, ...Object.values(index.columnOptions ?? {}).map((it) => it.opClass)]) {
94
+ if (opClass !== void 0 && !INDEX_OPCLASS_PATTERN.test(opClass)) {
95
+ errors2.add(
96
+ "MODEL_INVALID_INDEX",
97
+ `Invalid index operator class "${opClass}": expected an identifier, optionally schema-qualified (e.g. "public.gin_trgm_ops")`
98
+ );
99
+ }
100
+ }
101
+ if (index.where !== void 0 && index.where.trim() === "") {
102
+ errors2.add("MODEL_INVALID_INDEX", "Index predicate (where) must not be empty.");
103
+ } else if (index.where?.includes(";")) {
104
+ errors2.add("MODEL_INVALID_INDEX", 'Index predicate (where) must not contain ";".');
105
+ }
106
+ }
107
+ }
55
108
  validateUniqueConstraints(entity, errors2) {
56
109
  for (const constraint of entity.unique) {
57
110
  if (entity.view?.materialized && !constraint.index) {
@@ -104,6 +157,19 @@ class ModelValidator {
104
157
  if (field.sequence && field.nullable) {
105
158
  errors2.add("MODEL_INVALID_COLUMN_DEFINITION", "Column with sequence cannot be nullable.");
106
159
  }
160
+ this.validateColumnJsonSchema(field, errors2);
161
+ }
162
+ }
163
+ validateColumnJsonSchema(column, errors2) {
164
+ if (column.type !== schema.Model.ColumnType.Json || column.schema === void 0) {
165
+ return;
166
+ }
167
+ for (const { keyword, path } of collectUnsupportedKeywords.collectUnsupportedJsonSchemaKeywords(column.schema)) {
168
+ const location = path === "" ? "at the schema root" : `at "${path}"`;
169
+ errors2.add(
170
+ "MODEL_INVALID_JSON_SCHEMA",
171
+ `JSON Schema on column "${column.name}" uses unsupported keyword "${keyword}" ${location}. Only the following keywords are supported: ${keywords.SUPPORTED_JSON_SCHEMA_KEYWORDS.join(", ")}.`
172
+ );
107
173
  }
108
174
  }
109
175
  validateRelation(partialEntity, field, errors2) {
@@ -1 +1 @@
1
- {"version":3,"file":"ModelValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/ModelValidator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors'\nimport { acceptEveryFieldVisitor, getTargetEntity, isColumn, isInverseRelation, isOwningRelation } from '../model'\n\nconst IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/\nconst RESERVED_WORDS = ['and', 'or', 'not']\n\nexport class ModelValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], [])\n\t\tthis.validateEnums(this.model.enums, errorBuilder.for('enums'))\n\t\tthis.validateEntities(this.model.entities, errorBuilder.for('entities'))\n\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEnums(enums: Model.Schema['enums'], errors: ErrorBuilder): void {\n\t\tfor (const [enumName, enumValues] of Object.entries(enums)) {\n\t\t\tfor (const value of enumValues) {\n\t\t\t\tconst valueErrors = errors.for(enumName, value)\n\t\t\t\tthis.validateIdentifier(value, valueErrors)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateEntities(entities: Model.Schema['entities'], errors: ErrorBuilder): void {\n\t\tfor (const [entityName, entity] of Object.entries(entities)) {\n\t\t\tconst entityErrors = errors.for(entityName)\n\t\t\tif (entity.name !== entityName) {\n\t\t\t\tentityErrors.add('MODEL_NAME_MISMATCH', `Entity name \"${entity.name}\" does not match the name in a map \"${entityName}\"`)\n\t\t\t}\n\t\t\tthis.validateEntity(entity, entityErrors)\n\t\t}\n\t\tconst entitiesArr = Object.values(this.model.entities)\n\t\tthis.validateMetaSuffixCollisions(entitiesArr, errors)\n\t\tthis.validateTableNameCollisions(entitiesArr, errors)\n\t\tthis.validateAliasedTypesCollision(entitiesArr, errors)\n\t}\n\n\tprivate validateEntity(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(entity.name, errors)\n\t\tthis.validateEntityName(entity.name, errors)\n\n\t\tfor (const [fieldName, field] of Object.entries(entity.fields)) {\n\t\t\tconst fieldErrors = errors.for(fieldName)\n\t\t\tthis.validateField(entity, field, fieldErrors)\n\t\t\tif (field.name !== fieldName) {\n\t\t\t\tfieldErrors.add('MODEL_NAME_MISMATCH', `Field name \"${field.name}\" does not match the name in a map \"${fieldName}\"`)\n\t\t\t}\n\t\t}\n\t\tthis.validateUniqueConstraints(\n\t\t\tentity,\n\t\t\terrors.for('unique'),\n\t\t)\n\t\tthis.validateColumnNamesCollision(entity, errors)\n\t}\n\n\tprivate validateUniqueConstraints(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const constraint of entity.unique) {\n\t\t\tif (entity.view?.materialized && !constraint.index) {\n\t\t\t\terrors.add('MODEL_INVALID_CONSTRAINT', 'For materialized views, Unique must be defined as an index. Please set index: true.')\n\t\t\t}\n\t\t\tfor (const field of constraint.fields) {\n\t\t\t\tconst fieldDef = entity.fields[field]\n\t\t\t\tif (!fieldDef) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in a constraint does not exists`)\n\t\t\t\t} else if (isColumn(fieldDef) && fieldDef.list) {\n\t\t\t\t\terrors.add('MODEL_INVALID_FIELD', `Field ${field} in a unique constraint cannot be an array`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateColumnNamesCollision(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tconst existingColumnNames = new Map<string, string>()\n\t\tconst addColumnName = (fieldName: string, columnName: string) => {\n\t\t\tif (existingColumnNames.has(columnName)) {\n\t\t\t\tconst exitingName = existingColumnNames.get(columnName)\n\t\t\t\terrors\n\t\t\t\t\t.for(fieldName)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Column name \"${columnName}\" on field \"${fieldName}\" collides with a column name on field \"${exitingName}\".`)\n\t\t\t}\n\t\t\texistingColumnNames.set(columnName, fieldName)\n\t\t}\n\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\taddColumnName(column.name, column.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitManyHasOne: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitManyHasManyOwning: () => {},\n\t\t})\n\t}\n\n\tprivate validateField(partialEntity: Model.Entity, field: Model.AnyField, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(field.name, errors)\n\t\tif (isRelation(field)) {\n\t\t\tthis.validateRelation(partialEntity, field, errors)\n\t\t} else {\n\t\t\tif (field.sequence && field.nullable) {\n\t\t\t\terrors.add('MODEL_INVALID_COLUMN_DEFINITION', 'Column with sequence cannot be nullable.')\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateRelation(partialEntity: Model.Entity, field: Model.AnyRelation, errors: ErrorBuilder): void {\n\t\tconst entityName = partialEntity.name\n\t\tconst targetEntityName = field.target\n\t\tconst targetEntity = this.model.entities[targetEntityName] || undefined\n\t\tif (!targetEntity) {\n\t\t\treturn errors.add('MODEL_UNDEFINED_ENTITY', `Target entity ${targetEntityName} not found`)\n\t\t}\n\t\tif (((it: Model.AnyRelation): it is Model.AnyRelation & Model.OrderableRelation => 'orderBy' in it)(field)) {\n\t\t\t;(field as Model.OrderableRelation).orderBy?.forEach(it => {\n\t\t\t\tlet entity = targetEntity\n\n\t\t\t\tfor (let i = 0; i < it.path.length; i++) {\n\t\t\t\t\tconst orderByField = entity.fields[it.path[i]]\n\t\t\t\t\tconst pathStr = it.path.slice(0, i + 1).join('.')\n\t\t\t\t\tif (!orderByField) {\n\t\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not defined`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (i + 1 < it.path.length) {\n\t\t\t\t\t\tconst targetEntity = getTargetEntity(this.model, entity, orderByField.name)\n\t\t\t\t\t\tif (!targetEntity) {\n\t\t\t\t\t\t\terrors.add('MODEL_RELATION_REQUIRED', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not a relation`)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentity = targetEntity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (partialEntity.view) {\n\t\t\tif (field.type === Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'Many-has-many relation is not allowed on a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasMany\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-many relation fields on views must point to a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasOne\n\t\t\t\t&& !('joiningColumn' in field)\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-one relation fields on views must be owning or point to a view entity.')\n\t\t\t}\n\t\t}\n\t\tif (isInverseRelation(field)) {\n\t\t\tconst ownedBy = field.ownedBy\n\t\t\tconst targetField = targetEntity.fields[ownedBy]\n\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${ownedBy}:`\n\t\t\tif (!targetField) {\n\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t}\n\n\t\t\tif (!isRelation(targetField)) {\n\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t}\n\t\t\tif (targetField.target !== entityName) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!isOwningRelation(targetField)) {\n\t\t\t\terrors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an owning relation`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!targetField.inversedBy) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} inverse relation is not set`)\n\t\t\t}\n\t\t\tif (targetField.inversedBy !== field.name) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.inversedBy} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasMany && targetField.type !== Model.RelationType.ManyHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t} else {\n\t\t\tconst inversedBy = field.inversedBy\n\t\t\tif (inversedBy) {\n\t\t\t\tconst targetField = targetEntity.fields[inversedBy]\n\t\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${inversedBy}:`\n\t\t\t\tif (!targetField) {\n\t\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t\t}\n\t\t\t\tif (!isRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t\t}\n\t\t\t\tif (targetField.target !== entityName) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (!isInverseRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an inverse relation`)\n\t\t\t\t}\n\t\t\t\tif (!targetField.ownedBy) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} owning relation is not set`)\n\t\t\t\t}\n\t\t\t\tif (targetField.ownedBy !== field.name) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.ownedBy} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasOne && targetField.type !== Model.RelationType.OneHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateIdentifier(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (!value.match(IDENTIFIER_PATTERN)) {\n\t\t\treturn errorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} must match pattern ${IDENTIFIER_PATTERN.source}`)\n\t\t}\n\t\tif (RESERVED_WORDS.includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateEntityName(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (['Query', 'Mutation'].includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_ENTITY_NAME', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateMetaSuffixCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst entityNames = new Set(entities.map(it => it.name))\n\t\tfor (const entity of entities) {\n\t\t\tif (entity.name.endsWith('Meta')) {\n\t\t\t\tconst baseName = entity.name.substring(0, entity.name.length - 4)\n\t\t\t\tif (entityNames.has(baseName)) {\n\t\t\t\t\terrorBuilder.for(entity.name)\n\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t`entity ${entity.name} collides with entity ${baseName}, because a GraphQL type with \"Meta\" suffix is created for every entity`,\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateTableNameCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst relationNames: Record<string, string> = {}\n\t\tfor (const entity of entities) {\n\t\t\tconst description = `table name ${entity.tableName} of entity ${entity.name}`\n\t\t\tif (relationNames[entity.tableName]) {\n\t\t\t\terrorBuilder\n\t\t\t\t\t.for(entity.name)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `${description} collides with a ${relationNames[entity.tableName]}`)\n\t\t\t} else {\n\t\t\t\trelationNames[entity.tableName] = description\n\t\t\t}\n\t\t}\n\t\tfor (const entity of entities) {\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entity.name)\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitManyHasManyOwning: ({ entity, relation }) => {\n\t\t\t\t\tconst joiningTable = relation.joiningTable\n\t\t\t\t\tconst description = `joining table name ${joiningTable.tableName} of relation ${entity.name}::${relation.name}`\n\t\t\t\t\tif (relationNames[joiningTable.tableName]) {\n\t\t\t\t\t\tentityErrorBuilder\n\t\t\t\t\t\t\t.for(relation.name)\n\t\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t\t`${description} collides with a ${relationNames[joiningTable.tableName]}.`\n\t\t\t\t\t\t\t\t\t+ 'Consider using plural for a relation name or change the joining table name using .joiningTable(...) in schema definition.',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trelationNames[joiningTable.tableName] = description\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tvisitColumn: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate validateAliasedTypesCollision(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst aliasedTypes = new Map<string, Model.ColumnType>()\n\t\tfor (const entity of entities) {\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\t\tif (!column.typeAlias) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (aliasedTypes.has(column.typeAlias) && aliasedTypes.get(column.typeAlias) !== column.type) {\n\t\t\t\t\t\terrorBuilder\n\t\t\t\t\t\t\t.for(column.name)\n\t\t\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Type alias ${column.typeAlias} already exists for base type ${column.type}`)\n\t\t\t\t\t}\n\t\t\t\t\taliasedTypes.set(column.typeAlias, column.type)\n\t\t\t\t},\n\t\t\t\tvisitManyHasManyOwning: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n}\n\nconst isRelation = (field: Model.AnyField): field is Model.AnyRelation => Object.values(Model.RelationType).includes(field.type as Model.RelationType)\n"],"names":["ErrorBuilder","errors","isColumn","acceptEveryFieldVisitor","targetEntity","getTargetEntity","Model","isInverseRelation","isOwningRelation","entity"],"mappings":"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"}
1
+ {"version":3,"file":"ModelValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/ModelValidator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors.js'\nimport { acceptEveryFieldVisitor, getTargetEntity, isColumn, isInverseRelation, isOwningRelation } from '../model/index.js'\nimport { collectUnsupportedJsonSchemaKeywords, SUPPORTED_JSON_SCHEMA_KEYWORDS } from '../json-schema/index.js'\n\nconst IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/\n// An index operator class is an identifier, optionally schema-qualified (e.g. \"public.gin_trgm_ops\").\nconst INDEX_OPCLASS_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9$]*(\\.[_a-zA-Z][_a-zA-Z0-9$]*)?$/\nconst RESERVED_WORDS = ['and', 'or', 'not']\n\nexport class ModelValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], [])\n\t\tthis.validateEnums(this.model.enums, errorBuilder.for('enums'))\n\t\tthis.validateEntities(this.model.entities, errorBuilder.for('entities'))\n\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEnums(enums: Model.Schema['enums'], errors: ErrorBuilder): void {\n\t\tfor (const [enumName, enumValues] of Object.entries(enums)) {\n\t\t\tfor (const value of enumValues) {\n\t\t\t\tconst valueErrors = errors.for(enumName, value)\n\t\t\t\tthis.validateIdentifier(value, valueErrors)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateEntities(entities: Model.Schema['entities'], errors: ErrorBuilder): void {\n\t\tfor (const [entityName, entity] of Object.entries(entities)) {\n\t\t\tconst entityErrors = errors.for(entityName)\n\t\t\tif (entity.name !== entityName) {\n\t\t\t\tentityErrors.add('MODEL_NAME_MISMATCH', `Entity name \"${entity.name}\" does not match the name in a map \"${entityName}\"`)\n\t\t\t}\n\t\t\tthis.validateEntity(entity, entityErrors)\n\t\t}\n\t\tconst entitiesArr = Object.values(this.model.entities)\n\t\tthis.validateMetaSuffixCollisions(entitiesArr, errors)\n\t\tthis.validateTableNameCollisions(entitiesArr, errors)\n\t\tthis.validateAliasedTypesCollision(entitiesArr, errors)\n\t}\n\n\tprivate validateEntity(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(entity.name, errors)\n\t\tthis.validateEntityName(entity.name, errors)\n\n\t\tfor (const [fieldName, field] of Object.entries(entity.fields)) {\n\t\t\tconst fieldErrors = errors.for(fieldName)\n\t\t\tthis.validateField(entity, field, fieldErrors)\n\t\t\tif (field.name !== fieldName) {\n\t\t\t\tfieldErrors.add('MODEL_NAME_MISMATCH', `Field name \"${field.name}\" does not match the name in a map \"${fieldName}\"`)\n\t\t\t}\n\t\t}\n\t\tthis.validateUniqueConstraints(\n\t\t\tentity,\n\t\t\terrors.for('unique'),\n\t\t)\n\t\tthis.validateIndexes(\n\t\t\tentity,\n\t\t\terrors.for('indexes'),\n\t\t)\n\t\tthis.validateColumnNamesCollision(entity, errors)\n\t}\n\n\tprivate validateIndexes(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const index of entity.indexes) {\n\t\t\tfor (const field of [...index.fields, ...index.include ?? []]) {\n\t\t\t\tif (!entity.fields[field]) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in an index does not exists`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Postgres rejects an INCLUDE column that is already a key column.\n\t\t\tfor (const field of index.include ?? []) {\n\t\t\t\tif (index.fields.includes(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Field ${field} cannot be both an index key and an included (covering) column`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Per-column options (order/nulls/opClass) only apply to key columns.\n\t\t\tfor (const field of Object.keys(index.columnOptions ?? {})) {\n\t\t\t\tif (!index.fields.includes(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Column options reference field ${field}, which is not a key column of the index`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// columnOptions is keyed by field name, so a key column appearing twice cannot carry distinct\n\t\t\t// per-position options (the duplicate collapses to one entry) — reject the ambiguous shape.\n\t\t\tconst seenFields = new Set<string>()\n\t\t\tfor (const field of index.fields) {\n\t\t\t\tif (seenFields.has(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Field ${field} is listed more than once as an index key column`)\n\t\t\t\t}\n\t\t\t\tseenFields.add(field)\n\t\t\t}\n\t\t\t// Sort order and NULLS placement are btree-only; Postgres rejects them on other methods at apply time.\n\t\t\tif (index.method !== undefined && index.method !== 'btree') {\n\t\t\t\tfor (const [field, options] of Object.entries(index.columnOptions ?? {})) {\n\t\t\t\t\tif (options.order !== undefined || options.nulls !== undefined) {\n\t\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Column options (order/nulls) on field ${field} are only supported for btree indexes, not \"${index.method}\"`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// opClass is emitted verbatim into CREATE INDEX, so constrain it to an identifier (optionally\n\t\t\t// schema-qualified) — both to block SQL injection and to catch typos early with a clear message.\n\t\t\tfor (const opClass of [index.opClass, ...Object.values(index.columnOptions ?? {}).map(it => it.opClass)]) {\n\t\t\t\tif (opClass !== undefined && !INDEX_OPCLASS_PATTERN.test(opClass)) {\n\t\t\t\t\terrors.add(\n\t\t\t\t\t\t'MODEL_INVALID_INDEX',\n\t\t\t\t\t\t`Invalid index operator class \"${opClass}\": expected an identifier, optionally schema-qualified (e.g. \"public.gin_trgm_ops\")`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `where` is a raw SQL predicate embedded verbatim into CREATE INDEX. We don't parse SQL,\n\t\t\t// but a couple of basic checks catch the common footguns early with a clear message:\n\t\t\tif (index.where !== undefined && index.where.trim() === '') {\n\t\t\t\terrors.add('MODEL_INVALID_INDEX', 'Index predicate (where) must not be empty.')\n\t\t\t} else if (index.where?.includes(';')) {\n\t\t\t\terrors.add('MODEL_INVALID_INDEX', 'Index predicate (where) must not contain \";\".')\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateUniqueConstraints(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const constraint of entity.unique) {\n\t\t\tif (entity.view?.materialized && !constraint.index) {\n\t\t\t\terrors.add('MODEL_INVALID_CONSTRAINT', 'For materialized views, Unique must be defined as an index. Please set index: true.')\n\t\t\t}\n\t\t\tfor (const field of constraint.fields) {\n\t\t\t\tconst fieldDef = entity.fields[field]\n\t\t\t\tif (!fieldDef) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in a constraint does not exists`)\n\t\t\t\t} else if (isColumn(fieldDef) && fieldDef.list) {\n\t\t\t\t\terrors.add('MODEL_INVALID_FIELD', `Field ${field} in a unique constraint cannot be an array`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateColumnNamesCollision(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tconst existingColumnNames = new Map<string, string>()\n\t\tconst addColumnName = (fieldName: string, columnName: string) => {\n\t\t\tif (existingColumnNames.has(columnName)) {\n\t\t\t\tconst exitingName = existingColumnNames.get(columnName)\n\t\t\t\terrors\n\t\t\t\t\t.for(fieldName)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Column name \"${columnName}\" on field \"${fieldName}\" collides with a column name on field \"${exitingName}\".`)\n\t\t\t}\n\t\t\texistingColumnNames.set(columnName, fieldName)\n\t\t}\n\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\taddColumnName(column.name, column.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitManyHasOne: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitManyHasManyOwning: () => {},\n\t\t})\n\t}\n\n\tprivate validateField(partialEntity: Model.Entity, field: Model.AnyField, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(field.name, errors)\n\t\tif (isRelation(field)) {\n\t\t\tthis.validateRelation(partialEntity, field, errors)\n\t\t} else {\n\t\t\tif (field.sequence && field.nullable) {\n\t\t\t\terrors.add('MODEL_INVALID_COLUMN_DEFINITION', 'Column with sequence cannot be nullable.')\n\t\t\t}\n\t\t\tthis.validateColumnJsonSchema(field, errors)\n\t\t}\n\t}\n\n\tprivate validateColumnJsonSchema(column: Model.AnyColumn, errors: ErrorBuilder): void {\n\t\tif (column.type !== Model.ColumnType.Json || column.schema === undefined) {\n\t\t\treturn\n\t\t}\n\t\tfor (const { keyword, path } of collectUnsupportedJsonSchemaKeywords(column.schema)) {\n\t\t\tconst location = path === '' ? 'at the schema root' : `at \"${path}\"`\n\t\t\terrors.add(\n\t\t\t\t'MODEL_INVALID_JSON_SCHEMA',\n\t\t\t\t`JSON Schema on column \"${column.name}\" uses unsupported keyword \"${keyword}\" ${location}. `\n\t\t\t\t\t+ `Only the following keywords are supported: ${SUPPORTED_JSON_SCHEMA_KEYWORDS.join(', ')}.`,\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate validateRelation(partialEntity: Model.Entity, field: Model.AnyRelation, errors: ErrorBuilder): void {\n\t\tconst entityName = partialEntity.name\n\t\tconst targetEntityName = field.target\n\t\tconst targetEntity = this.model.entities[targetEntityName] || undefined\n\t\tif (!targetEntity) {\n\t\t\treturn errors.add('MODEL_UNDEFINED_ENTITY', `Target entity ${targetEntityName} not found`)\n\t\t}\n\t\tif (((it: Model.AnyRelation): it is Model.AnyRelation & Model.OrderableRelation => 'orderBy' in it)(field)) {\n\t\t\t;(field as Model.OrderableRelation).orderBy?.forEach(it => {\n\t\t\t\tlet entity = targetEntity\n\n\t\t\t\tfor (let i = 0; i < it.path.length; i++) {\n\t\t\t\t\tconst orderByField = entity.fields[it.path[i]]\n\t\t\t\t\tconst pathStr = it.path.slice(0, i + 1).join('.')\n\t\t\t\t\tif (!orderByField) {\n\t\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not defined`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (i + 1 < it.path.length) {\n\t\t\t\t\t\tconst targetEntity = getTargetEntity(this.model, entity, orderByField.name)\n\t\t\t\t\t\tif (!targetEntity) {\n\t\t\t\t\t\t\terrors.add('MODEL_RELATION_REQUIRED', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not a relation`)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentity = targetEntity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (partialEntity.view) {\n\t\t\tif (field.type === Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'Many-has-many relation is not allowed on a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasMany\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-many relation fields on views must point to a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasOne\n\t\t\t\t&& !('joiningColumn' in field)\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-one relation fields on views must be owning or point to a view entity.')\n\t\t\t}\n\t\t}\n\t\tif (isInverseRelation(field)) {\n\t\t\tconst ownedBy = field.ownedBy\n\t\t\tconst targetField = targetEntity.fields[ownedBy]\n\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${ownedBy}:`\n\t\t\tif (!targetField) {\n\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t}\n\n\t\t\tif (!isRelation(targetField)) {\n\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t}\n\t\t\tif (targetField.target !== entityName) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!isOwningRelation(targetField)) {\n\t\t\t\terrors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an owning relation`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!targetField.inversedBy) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} inverse relation is not set`)\n\t\t\t}\n\t\t\tif (targetField.inversedBy !== field.name) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.inversedBy} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasMany && targetField.type !== Model.RelationType.ManyHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t} else {\n\t\t\tconst inversedBy = field.inversedBy\n\t\t\tif (inversedBy) {\n\t\t\t\tconst targetField = targetEntity.fields[inversedBy]\n\t\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${inversedBy}:`\n\t\t\t\tif (!targetField) {\n\t\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t\t}\n\t\t\t\tif (!isRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t\t}\n\t\t\t\tif (targetField.target !== entityName) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (!isInverseRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an inverse relation`)\n\t\t\t\t}\n\t\t\t\tif (!targetField.ownedBy) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} owning relation is not set`)\n\t\t\t\t}\n\t\t\t\tif (targetField.ownedBy !== field.name) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.ownedBy} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasOne && targetField.type !== Model.RelationType.OneHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateIdentifier(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (!value.match(IDENTIFIER_PATTERN)) {\n\t\t\treturn errorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} must match pattern ${IDENTIFIER_PATTERN.source}`)\n\t\t}\n\t\tif (RESERVED_WORDS.includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateEntityName(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (['Query', 'Mutation'].includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_ENTITY_NAME', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateMetaSuffixCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst entityNames = new Set(entities.map(it => it.name))\n\t\tfor (const entity of entities) {\n\t\t\tif (entity.name.endsWith('Meta')) {\n\t\t\t\tconst baseName = entity.name.substring(0, entity.name.length - 4)\n\t\t\t\tif (entityNames.has(baseName)) {\n\t\t\t\t\terrorBuilder.for(entity.name)\n\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t`entity ${entity.name} collides with entity ${baseName}, because a GraphQL type with \"Meta\" suffix is created for every entity`,\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateTableNameCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst relationNames: Record<string, string> = {}\n\t\tfor (const entity of entities) {\n\t\t\tconst description = `table name ${entity.tableName} of entity ${entity.name}`\n\t\t\tif (relationNames[entity.tableName]) {\n\t\t\t\terrorBuilder\n\t\t\t\t\t.for(entity.name)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `${description} collides with a ${relationNames[entity.tableName]}`)\n\t\t\t} else {\n\t\t\t\trelationNames[entity.tableName] = description\n\t\t\t}\n\t\t}\n\t\tfor (const entity of entities) {\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entity.name)\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitManyHasManyOwning: ({ entity, relation }) => {\n\t\t\t\t\tconst joiningTable = relation.joiningTable\n\t\t\t\t\tconst description = `joining table name ${joiningTable.tableName} of relation ${entity.name}::${relation.name}`\n\t\t\t\t\tif (relationNames[joiningTable.tableName]) {\n\t\t\t\t\t\tentityErrorBuilder\n\t\t\t\t\t\t\t.for(relation.name)\n\t\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t\t`${description} collides with a ${relationNames[joiningTable.tableName]}.`\n\t\t\t\t\t\t\t\t\t+ 'Consider using plural for a relation name or change the joining table name using .joiningTable(...) in schema definition.',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trelationNames[joiningTable.tableName] = description\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tvisitColumn: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate validateAliasedTypesCollision(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst aliasedTypes = new Map<string, Model.ColumnType>()\n\t\tfor (const entity of entities) {\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\t\tif (!column.typeAlias) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (aliasedTypes.has(column.typeAlias) && aliasedTypes.get(column.typeAlias) !== column.type) {\n\t\t\t\t\t\terrorBuilder\n\t\t\t\t\t\t\t.for(column.name)\n\t\t\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Type alias ${column.typeAlias} already exists for base type ${column.type}`)\n\t\t\t\t\t}\n\t\t\t\t\taliasedTypes.set(column.typeAlias, column.type)\n\t\t\t\t},\n\t\t\t\tvisitManyHasManyOwning: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n}\n\nconst isRelation = (field: Model.AnyField): field is Model.AnyRelation => Object.values(Model.RelationType).includes(field.type as Model.RelationType)\n"],"names":["ErrorBuilder","errors","isColumn","acceptEveryFieldVisitor","Model","collectUnsupportedJsonSchemaKeywords","SUPPORTED_JSON_SCHEMA_KEYWORDS","targetEntity","getTargetEntity","isInverseRelation","isOwningRelation","entity"],"mappings":"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"}
@@ -1,7 +1,10 @@
1
1
  import { Model } from "@contember/schema";
2
2
  import { ErrorBuilder } from "./errors.js";
3
3
  import { isColumn, acceptEveryFieldVisitor, getTargetEntity, isInverseRelation, isOwningRelation } from "../model/modelUtils.js";
4
+ import { SUPPORTED_JSON_SCHEMA_KEYWORDS } from "../json-schema/keywords.js";
5
+ import { collectUnsupportedJsonSchemaKeywords } from "../json-schema/collectUnsupportedKeywords.js";
4
6
  const IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/;
7
+ const INDEX_OPCLASS_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9$]*(\.[_a-zA-Z][_a-zA-Z0-9$]*)?$/;
5
8
  const RESERVED_WORDS = ["and", "or", "not"];
6
9
  class ModelValidator {
7
10
  constructor(model) {
@@ -48,8 +51,58 @@ class ModelValidator {
48
51
  entity,
49
52
  errors.for("unique")
50
53
  );
54
+ this.validateIndexes(
55
+ entity,
56
+ errors.for("indexes")
57
+ );
51
58
  this.validateColumnNamesCollision(entity, errors);
52
59
  }
60
+ validateIndexes(entity, errors) {
61
+ for (const index of entity.indexes) {
62
+ for (const field of [...index.fields, ...index.include ?? []]) {
63
+ if (!entity.fields[field]) {
64
+ errors.add("MODEL_UNDEFINED_FIELD", `Referenced field ${field} in an index does not exists`);
65
+ }
66
+ }
67
+ for (const field of index.include ?? []) {
68
+ if (index.fields.includes(field)) {
69
+ errors.add("MODEL_INVALID_INDEX", `Field ${field} cannot be both an index key and an included (covering) column`);
70
+ }
71
+ }
72
+ for (const field of Object.keys(index.columnOptions ?? {})) {
73
+ if (!index.fields.includes(field)) {
74
+ errors.add("MODEL_INVALID_INDEX", `Column options reference field ${field}, which is not a key column of the index`);
75
+ }
76
+ }
77
+ const seenFields = /* @__PURE__ */ new Set();
78
+ for (const field of index.fields) {
79
+ if (seenFields.has(field)) {
80
+ errors.add("MODEL_INVALID_INDEX", `Field ${field} is listed more than once as an index key column`);
81
+ }
82
+ seenFields.add(field);
83
+ }
84
+ if (index.method !== void 0 && index.method !== "btree") {
85
+ for (const [field, options] of Object.entries(index.columnOptions ?? {})) {
86
+ if (options.order !== void 0 || options.nulls !== void 0) {
87
+ errors.add("MODEL_INVALID_INDEX", `Column options (order/nulls) on field ${field} are only supported for btree indexes, not "${index.method}"`);
88
+ }
89
+ }
90
+ }
91
+ for (const opClass of [index.opClass, ...Object.values(index.columnOptions ?? {}).map((it) => it.opClass)]) {
92
+ if (opClass !== void 0 && !INDEX_OPCLASS_PATTERN.test(opClass)) {
93
+ errors.add(
94
+ "MODEL_INVALID_INDEX",
95
+ `Invalid index operator class "${opClass}": expected an identifier, optionally schema-qualified (e.g. "public.gin_trgm_ops")`
96
+ );
97
+ }
98
+ }
99
+ if (index.where !== void 0 && index.where.trim() === "") {
100
+ errors.add("MODEL_INVALID_INDEX", "Index predicate (where) must not be empty.");
101
+ } else if (index.where?.includes(";")) {
102
+ errors.add("MODEL_INVALID_INDEX", 'Index predicate (where) must not contain ";".');
103
+ }
104
+ }
105
+ }
53
106
  validateUniqueConstraints(entity, errors) {
54
107
  for (const constraint of entity.unique) {
55
108
  if (entity.view?.materialized && !constraint.index) {
@@ -102,6 +155,19 @@ class ModelValidator {
102
155
  if (field.sequence && field.nullable) {
103
156
  errors.add("MODEL_INVALID_COLUMN_DEFINITION", "Column with sequence cannot be nullable.");
104
157
  }
158
+ this.validateColumnJsonSchema(field, errors);
159
+ }
160
+ }
161
+ validateColumnJsonSchema(column, errors) {
162
+ if (column.type !== Model.ColumnType.Json || column.schema === void 0) {
163
+ return;
164
+ }
165
+ for (const { keyword, path } of collectUnsupportedJsonSchemaKeywords(column.schema)) {
166
+ const location = path === "" ? "at the schema root" : `at "${path}"`;
167
+ errors.add(
168
+ "MODEL_INVALID_JSON_SCHEMA",
169
+ `JSON Schema on column "${column.name}" uses unsupported keyword "${keyword}" ${location}. Only the following keywords are supported: ${SUPPORTED_JSON_SCHEMA_KEYWORDS.join(", ")}.`
170
+ );
105
171
  }
106
172
  }
107
173
  validateRelation(partialEntity, field, errors) {
@@ -1 +1 @@
1
- {"version":3,"file":"ModelValidator.js","sources":["../../../../../packages/schema-utils/src/validation/ModelValidator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors'\nimport { acceptEveryFieldVisitor, getTargetEntity, isColumn, isInverseRelation, isOwningRelation } from '../model'\n\nconst IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/\nconst RESERVED_WORDS = ['and', 'or', 'not']\n\nexport class ModelValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], [])\n\t\tthis.validateEnums(this.model.enums, errorBuilder.for('enums'))\n\t\tthis.validateEntities(this.model.entities, errorBuilder.for('entities'))\n\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEnums(enums: Model.Schema['enums'], errors: ErrorBuilder): void {\n\t\tfor (const [enumName, enumValues] of Object.entries(enums)) {\n\t\t\tfor (const value of enumValues) {\n\t\t\t\tconst valueErrors = errors.for(enumName, value)\n\t\t\t\tthis.validateIdentifier(value, valueErrors)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateEntities(entities: Model.Schema['entities'], errors: ErrorBuilder): void {\n\t\tfor (const [entityName, entity] of Object.entries(entities)) {\n\t\t\tconst entityErrors = errors.for(entityName)\n\t\t\tif (entity.name !== entityName) {\n\t\t\t\tentityErrors.add('MODEL_NAME_MISMATCH', `Entity name \"${entity.name}\" does not match the name in a map \"${entityName}\"`)\n\t\t\t}\n\t\t\tthis.validateEntity(entity, entityErrors)\n\t\t}\n\t\tconst entitiesArr = Object.values(this.model.entities)\n\t\tthis.validateMetaSuffixCollisions(entitiesArr, errors)\n\t\tthis.validateTableNameCollisions(entitiesArr, errors)\n\t\tthis.validateAliasedTypesCollision(entitiesArr, errors)\n\t}\n\n\tprivate validateEntity(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(entity.name, errors)\n\t\tthis.validateEntityName(entity.name, errors)\n\n\t\tfor (const [fieldName, field] of Object.entries(entity.fields)) {\n\t\t\tconst fieldErrors = errors.for(fieldName)\n\t\t\tthis.validateField(entity, field, fieldErrors)\n\t\t\tif (field.name !== fieldName) {\n\t\t\t\tfieldErrors.add('MODEL_NAME_MISMATCH', `Field name \"${field.name}\" does not match the name in a map \"${fieldName}\"`)\n\t\t\t}\n\t\t}\n\t\tthis.validateUniqueConstraints(\n\t\t\tentity,\n\t\t\terrors.for('unique'),\n\t\t)\n\t\tthis.validateColumnNamesCollision(entity, errors)\n\t}\n\n\tprivate validateUniqueConstraints(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const constraint of entity.unique) {\n\t\t\tif (entity.view?.materialized && !constraint.index) {\n\t\t\t\terrors.add('MODEL_INVALID_CONSTRAINT', 'For materialized views, Unique must be defined as an index. Please set index: true.')\n\t\t\t}\n\t\t\tfor (const field of constraint.fields) {\n\t\t\t\tconst fieldDef = entity.fields[field]\n\t\t\t\tif (!fieldDef) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in a constraint does not exists`)\n\t\t\t\t} else if (isColumn(fieldDef) && fieldDef.list) {\n\t\t\t\t\terrors.add('MODEL_INVALID_FIELD', `Field ${field} in a unique constraint cannot be an array`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateColumnNamesCollision(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tconst existingColumnNames = new Map<string, string>()\n\t\tconst addColumnName = (fieldName: string, columnName: string) => {\n\t\t\tif (existingColumnNames.has(columnName)) {\n\t\t\t\tconst exitingName = existingColumnNames.get(columnName)\n\t\t\t\terrors\n\t\t\t\t\t.for(fieldName)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Column name \"${columnName}\" on field \"${fieldName}\" collides with a column name on field \"${exitingName}\".`)\n\t\t\t}\n\t\t\texistingColumnNames.set(columnName, fieldName)\n\t\t}\n\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\taddColumnName(column.name, column.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitManyHasOne: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitManyHasManyOwning: () => {},\n\t\t})\n\t}\n\n\tprivate validateField(partialEntity: Model.Entity, field: Model.AnyField, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(field.name, errors)\n\t\tif (isRelation(field)) {\n\t\t\tthis.validateRelation(partialEntity, field, errors)\n\t\t} else {\n\t\t\tif (field.sequence && field.nullable) {\n\t\t\t\terrors.add('MODEL_INVALID_COLUMN_DEFINITION', 'Column with sequence cannot be nullable.')\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateRelation(partialEntity: Model.Entity, field: Model.AnyRelation, errors: ErrorBuilder): void {\n\t\tconst entityName = partialEntity.name\n\t\tconst targetEntityName = field.target\n\t\tconst targetEntity = this.model.entities[targetEntityName] || undefined\n\t\tif (!targetEntity) {\n\t\t\treturn errors.add('MODEL_UNDEFINED_ENTITY', `Target entity ${targetEntityName} not found`)\n\t\t}\n\t\tif (((it: Model.AnyRelation): it is Model.AnyRelation & Model.OrderableRelation => 'orderBy' in it)(field)) {\n\t\t\t;(field as Model.OrderableRelation).orderBy?.forEach(it => {\n\t\t\t\tlet entity = targetEntity\n\n\t\t\t\tfor (let i = 0; i < it.path.length; i++) {\n\t\t\t\t\tconst orderByField = entity.fields[it.path[i]]\n\t\t\t\t\tconst pathStr = it.path.slice(0, i + 1).join('.')\n\t\t\t\t\tif (!orderByField) {\n\t\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not defined`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (i + 1 < it.path.length) {\n\t\t\t\t\t\tconst targetEntity = getTargetEntity(this.model, entity, orderByField.name)\n\t\t\t\t\t\tif (!targetEntity) {\n\t\t\t\t\t\t\terrors.add('MODEL_RELATION_REQUIRED', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not a relation`)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentity = targetEntity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (partialEntity.view) {\n\t\t\tif (field.type === Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'Many-has-many relation is not allowed on a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasMany\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-many relation fields on views must point to a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasOne\n\t\t\t\t&& !('joiningColumn' in field)\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-one relation fields on views must be owning or point to a view entity.')\n\t\t\t}\n\t\t}\n\t\tif (isInverseRelation(field)) {\n\t\t\tconst ownedBy = field.ownedBy\n\t\t\tconst targetField = targetEntity.fields[ownedBy]\n\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${ownedBy}:`\n\t\t\tif (!targetField) {\n\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t}\n\n\t\t\tif (!isRelation(targetField)) {\n\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t}\n\t\t\tif (targetField.target !== entityName) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!isOwningRelation(targetField)) {\n\t\t\t\terrors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an owning relation`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!targetField.inversedBy) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} inverse relation is not set`)\n\t\t\t}\n\t\t\tif (targetField.inversedBy !== field.name) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.inversedBy} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasMany && targetField.type !== Model.RelationType.ManyHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t} else {\n\t\t\tconst inversedBy = field.inversedBy\n\t\t\tif (inversedBy) {\n\t\t\t\tconst targetField = targetEntity.fields[inversedBy]\n\t\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${inversedBy}:`\n\t\t\t\tif (!targetField) {\n\t\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t\t}\n\t\t\t\tif (!isRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t\t}\n\t\t\t\tif (targetField.target !== entityName) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (!isInverseRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an inverse relation`)\n\t\t\t\t}\n\t\t\t\tif (!targetField.ownedBy) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} owning relation is not set`)\n\t\t\t\t}\n\t\t\t\tif (targetField.ownedBy !== field.name) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.ownedBy} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasOne && targetField.type !== Model.RelationType.OneHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateIdentifier(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (!value.match(IDENTIFIER_PATTERN)) {\n\t\t\treturn errorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} must match pattern ${IDENTIFIER_PATTERN.source}`)\n\t\t}\n\t\tif (RESERVED_WORDS.includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateEntityName(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (['Query', 'Mutation'].includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_ENTITY_NAME', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateMetaSuffixCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst entityNames = new Set(entities.map(it => it.name))\n\t\tfor (const entity of entities) {\n\t\t\tif (entity.name.endsWith('Meta')) {\n\t\t\t\tconst baseName = entity.name.substring(0, entity.name.length - 4)\n\t\t\t\tif (entityNames.has(baseName)) {\n\t\t\t\t\terrorBuilder.for(entity.name)\n\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t`entity ${entity.name} collides with entity ${baseName}, because a GraphQL type with \"Meta\" suffix is created for every entity`,\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateTableNameCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst relationNames: Record<string, string> = {}\n\t\tfor (const entity of entities) {\n\t\t\tconst description = `table name ${entity.tableName} of entity ${entity.name}`\n\t\t\tif (relationNames[entity.tableName]) {\n\t\t\t\terrorBuilder\n\t\t\t\t\t.for(entity.name)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `${description} collides with a ${relationNames[entity.tableName]}`)\n\t\t\t} else {\n\t\t\t\trelationNames[entity.tableName] = description\n\t\t\t}\n\t\t}\n\t\tfor (const entity of entities) {\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entity.name)\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitManyHasManyOwning: ({ entity, relation }) => {\n\t\t\t\t\tconst joiningTable = relation.joiningTable\n\t\t\t\t\tconst description = `joining table name ${joiningTable.tableName} of relation ${entity.name}::${relation.name}`\n\t\t\t\t\tif (relationNames[joiningTable.tableName]) {\n\t\t\t\t\t\tentityErrorBuilder\n\t\t\t\t\t\t\t.for(relation.name)\n\t\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t\t`${description} collides with a ${relationNames[joiningTable.tableName]}.`\n\t\t\t\t\t\t\t\t\t+ 'Consider using plural for a relation name or change the joining table name using .joiningTable(...) in schema definition.',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trelationNames[joiningTable.tableName] = description\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tvisitColumn: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate validateAliasedTypesCollision(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst aliasedTypes = new Map<string, Model.ColumnType>()\n\t\tfor (const entity of entities) {\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\t\tif (!column.typeAlias) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (aliasedTypes.has(column.typeAlias) && aliasedTypes.get(column.typeAlias) !== column.type) {\n\t\t\t\t\t\terrorBuilder\n\t\t\t\t\t\t\t.for(column.name)\n\t\t\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Type alias ${column.typeAlias} already exists for base type ${column.type}`)\n\t\t\t\t\t}\n\t\t\t\t\taliasedTypes.set(column.typeAlias, column.type)\n\t\t\t\t},\n\t\t\t\tvisitManyHasManyOwning: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n}\n\nconst isRelation = (field: Model.AnyField): field is Model.AnyRelation => Object.values(Model.RelationType).includes(field.type as Model.RelationType)\n"],"names":["targetEntity","entity"],"mappings":"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"}
1
+ {"version":3,"file":"ModelValidator.js","sources":["../../../../../packages/schema-utils/src/validation/ModelValidator.ts"],"sourcesContent":["import { Model } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors.js'\nimport { acceptEveryFieldVisitor, getTargetEntity, isColumn, isInverseRelation, isOwningRelation } from '../model/index.js'\nimport { collectUnsupportedJsonSchemaKeywords, SUPPORTED_JSON_SCHEMA_KEYWORDS } from '../json-schema/index.js'\n\nconst IDENTIFIER_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9]*$/\n// An index operator class is an identifier, optionally schema-qualified (e.g. \"public.gin_trgm_ops\").\nconst INDEX_OPCLASS_PATTERN = /^[_a-zA-Z][_a-zA-Z0-9$]*(\\.[_a-zA-Z][_a-zA-Z0-9$]*)?$/\nconst RESERVED_WORDS = ['and', 'or', 'not']\n\nexport class ModelValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], [])\n\t\tthis.validateEnums(this.model.enums, errorBuilder.for('enums'))\n\t\tthis.validateEntities(this.model.entities, errorBuilder.for('entities'))\n\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEnums(enums: Model.Schema['enums'], errors: ErrorBuilder): void {\n\t\tfor (const [enumName, enumValues] of Object.entries(enums)) {\n\t\t\tfor (const value of enumValues) {\n\t\t\t\tconst valueErrors = errors.for(enumName, value)\n\t\t\t\tthis.validateIdentifier(value, valueErrors)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateEntities(entities: Model.Schema['entities'], errors: ErrorBuilder): void {\n\t\tfor (const [entityName, entity] of Object.entries(entities)) {\n\t\t\tconst entityErrors = errors.for(entityName)\n\t\t\tif (entity.name !== entityName) {\n\t\t\t\tentityErrors.add('MODEL_NAME_MISMATCH', `Entity name \"${entity.name}\" does not match the name in a map \"${entityName}\"`)\n\t\t\t}\n\t\t\tthis.validateEntity(entity, entityErrors)\n\t\t}\n\t\tconst entitiesArr = Object.values(this.model.entities)\n\t\tthis.validateMetaSuffixCollisions(entitiesArr, errors)\n\t\tthis.validateTableNameCollisions(entitiesArr, errors)\n\t\tthis.validateAliasedTypesCollision(entitiesArr, errors)\n\t}\n\n\tprivate validateEntity(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(entity.name, errors)\n\t\tthis.validateEntityName(entity.name, errors)\n\n\t\tfor (const [fieldName, field] of Object.entries(entity.fields)) {\n\t\t\tconst fieldErrors = errors.for(fieldName)\n\t\t\tthis.validateField(entity, field, fieldErrors)\n\t\t\tif (field.name !== fieldName) {\n\t\t\t\tfieldErrors.add('MODEL_NAME_MISMATCH', `Field name \"${field.name}\" does not match the name in a map \"${fieldName}\"`)\n\t\t\t}\n\t\t}\n\t\tthis.validateUniqueConstraints(\n\t\t\tentity,\n\t\t\terrors.for('unique'),\n\t\t)\n\t\tthis.validateIndexes(\n\t\t\tentity,\n\t\t\terrors.for('indexes'),\n\t\t)\n\t\tthis.validateColumnNamesCollision(entity, errors)\n\t}\n\n\tprivate validateIndexes(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const index of entity.indexes) {\n\t\t\tfor (const field of [...index.fields, ...index.include ?? []]) {\n\t\t\t\tif (!entity.fields[field]) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in an index does not exists`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Postgres rejects an INCLUDE column that is already a key column.\n\t\t\tfor (const field of index.include ?? []) {\n\t\t\t\tif (index.fields.includes(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Field ${field} cannot be both an index key and an included (covering) column`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Per-column options (order/nulls/opClass) only apply to key columns.\n\t\t\tfor (const field of Object.keys(index.columnOptions ?? {})) {\n\t\t\t\tif (!index.fields.includes(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Column options reference field ${field}, which is not a key column of the index`)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// columnOptions is keyed by field name, so a key column appearing twice cannot carry distinct\n\t\t\t// per-position options (the duplicate collapses to one entry) — reject the ambiguous shape.\n\t\t\tconst seenFields = new Set<string>()\n\t\t\tfor (const field of index.fields) {\n\t\t\t\tif (seenFields.has(field)) {\n\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Field ${field} is listed more than once as an index key column`)\n\t\t\t\t}\n\t\t\t\tseenFields.add(field)\n\t\t\t}\n\t\t\t// Sort order and NULLS placement are btree-only; Postgres rejects them on other methods at apply time.\n\t\t\tif (index.method !== undefined && index.method !== 'btree') {\n\t\t\t\tfor (const [field, options] of Object.entries(index.columnOptions ?? {})) {\n\t\t\t\t\tif (options.order !== undefined || options.nulls !== undefined) {\n\t\t\t\t\t\terrors.add('MODEL_INVALID_INDEX', `Column options (order/nulls) on field ${field} are only supported for btree indexes, not \"${index.method}\"`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// opClass is emitted verbatim into CREATE INDEX, so constrain it to an identifier (optionally\n\t\t\t// schema-qualified) — both to block SQL injection and to catch typos early with a clear message.\n\t\t\tfor (const opClass of [index.opClass, ...Object.values(index.columnOptions ?? {}).map(it => it.opClass)]) {\n\t\t\t\tif (opClass !== undefined && !INDEX_OPCLASS_PATTERN.test(opClass)) {\n\t\t\t\t\terrors.add(\n\t\t\t\t\t\t'MODEL_INVALID_INDEX',\n\t\t\t\t\t\t`Invalid index operator class \"${opClass}\": expected an identifier, optionally schema-qualified (e.g. \"public.gin_trgm_ops\")`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `where` is a raw SQL predicate embedded verbatim into CREATE INDEX. We don't parse SQL,\n\t\t\t// but a couple of basic checks catch the common footguns early with a clear message:\n\t\t\tif (index.where !== undefined && index.where.trim() === '') {\n\t\t\t\terrors.add('MODEL_INVALID_INDEX', 'Index predicate (where) must not be empty.')\n\t\t\t} else if (index.where?.includes(';')) {\n\t\t\t\terrors.add('MODEL_INVALID_INDEX', 'Index predicate (where) must not contain \";\".')\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateUniqueConstraints(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tfor (const constraint of entity.unique) {\n\t\t\tif (entity.view?.materialized && !constraint.index) {\n\t\t\t\terrors.add('MODEL_INVALID_CONSTRAINT', 'For materialized views, Unique must be defined as an index. Please set index: true.')\n\t\t\t}\n\t\t\tfor (const field of constraint.fields) {\n\t\t\t\tconst fieldDef = entity.fields[field]\n\t\t\t\tif (!fieldDef) {\n\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Referenced field ${field} in a constraint does not exists`)\n\t\t\t\t} else if (isColumn(fieldDef) && fieldDef.list) {\n\t\t\t\t\terrors.add('MODEL_INVALID_FIELD', `Field ${field} in a unique constraint cannot be an array`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateColumnNamesCollision(entity: Model.Entity, errors: ErrorBuilder): void {\n\t\tconst existingColumnNames = new Map<string, string>()\n\t\tconst addColumnName = (fieldName: string, columnName: string) => {\n\t\t\tif (existingColumnNames.has(columnName)) {\n\t\t\t\tconst exitingName = existingColumnNames.get(columnName)\n\t\t\t\terrors\n\t\t\t\t\t.for(fieldName)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Column name \"${columnName}\" on field \"${fieldName}\" collides with a column name on field \"${exitingName}\".`)\n\t\t\t}\n\t\t\texistingColumnNames.set(columnName, fieldName)\n\t\t}\n\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\taddColumnName(column.name, column.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneOwning: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitManyHasOne: ({ relation }) => {\n\t\t\t\taddColumnName(relation.name, relation.joiningColumn.columnName)\n\t\t\t},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitManyHasManyOwning: () => {},\n\t\t})\n\t}\n\n\tprivate validateField(partialEntity: Model.Entity, field: Model.AnyField, errors: ErrorBuilder): void {\n\t\tthis.validateIdentifier(field.name, errors)\n\t\tif (isRelation(field)) {\n\t\t\tthis.validateRelation(partialEntity, field, errors)\n\t\t} else {\n\t\t\tif (field.sequence && field.nullable) {\n\t\t\t\terrors.add('MODEL_INVALID_COLUMN_DEFINITION', 'Column with sequence cannot be nullable.')\n\t\t\t}\n\t\t\tthis.validateColumnJsonSchema(field, errors)\n\t\t}\n\t}\n\n\tprivate validateColumnJsonSchema(column: Model.AnyColumn, errors: ErrorBuilder): void {\n\t\tif (column.type !== Model.ColumnType.Json || column.schema === undefined) {\n\t\t\treturn\n\t\t}\n\t\tfor (const { keyword, path } of collectUnsupportedJsonSchemaKeywords(column.schema)) {\n\t\t\tconst location = path === '' ? 'at the schema root' : `at \"${path}\"`\n\t\t\terrors.add(\n\t\t\t\t'MODEL_INVALID_JSON_SCHEMA',\n\t\t\t\t`JSON Schema on column \"${column.name}\" uses unsupported keyword \"${keyword}\" ${location}. `\n\t\t\t\t\t+ `Only the following keywords are supported: ${SUPPORTED_JSON_SCHEMA_KEYWORDS.join(', ')}.`,\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate validateRelation(partialEntity: Model.Entity, field: Model.AnyRelation, errors: ErrorBuilder): void {\n\t\tconst entityName = partialEntity.name\n\t\tconst targetEntityName = field.target\n\t\tconst targetEntity = this.model.entities[targetEntityName] || undefined\n\t\tif (!targetEntity) {\n\t\t\treturn errors.add('MODEL_UNDEFINED_ENTITY', `Target entity ${targetEntityName} not found`)\n\t\t}\n\t\tif (((it: Model.AnyRelation): it is Model.AnyRelation & Model.OrderableRelation => 'orderBy' in it)(field)) {\n\t\t\t;(field as Model.OrderableRelation).orderBy?.forEach(it => {\n\t\t\t\tlet entity = targetEntity\n\n\t\t\t\tfor (let i = 0; i < it.path.length; i++) {\n\t\t\t\t\tconst orderByField = entity.fields[it.path[i]]\n\t\t\t\t\tconst pathStr = it.path.slice(0, i + 1).join('.')\n\t\t\t\t\tif (!orderByField) {\n\t\t\t\t\t\terrors.add('MODEL_UNDEFINED_FIELD', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not defined`)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (i + 1 < it.path.length) {\n\t\t\t\t\t\tconst targetEntity = getTargetEntity(this.model, entity, orderByField.name)\n\t\t\t\t\t\tif (!targetEntity) {\n\t\t\t\t\t\t\terrors.add('MODEL_RELATION_REQUIRED', `Invalid orderBy of ${entityName}::${field.name}: field ${pathStr} is not a relation`)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentity = targetEntity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif (partialEntity.view) {\n\t\t\tif (field.type === Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'Many-has-many relation is not allowed on a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasMany\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-many relation fields on views must point to a view entity.')\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetEntity.view\n\t\t\t\t&& field.type === Model.RelationType.OneHasOne\n\t\t\t\t&& !('joiningColumn' in field)\n\t\t\t) {\n\t\t\t\treturn errors.add('MODEL_INVALID_VIEW_USAGE', 'One-has-one relation fields on views must be owning or point to a view entity.')\n\t\t\t}\n\t\t}\n\t\tif (isInverseRelation(field)) {\n\t\t\tconst ownedBy = field.ownedBy\n\t\t\tconst targetField = targetEntity.fields[ownedBy]\n\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${ownedBy}:`\n\t\t\tif (!targetField) {\n\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t}\n\n\t\t\tif (!isRelation(targetField)) {\n\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t}\n\t\t\tif (targetField.target !== entityName) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!isOwningRelation(targetField)) {\n\t\t\t\terrors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an owning relation`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!targetField.inversedBy) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} inverse relation is not set`)\n\t\t\t}\n\t\t\tif (targetField.inversedBy !== field.name) {\n\t\t\t\treturn errors.add(\n\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.inversedBy} given`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.OneHasMany && targetField.type !== Model.RelationType.ManyHasOne) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t}\n\t\t} else {\n\t\t\tconst inversedBy = field.inversedBy\n\t\t\tif (inversedBy) {\n\t\t\t\tconst targetField = targetEntity.fields[inversedBy]\n\t\t\t\tconst relationDescription = `Target relation ${targetEntityName}::${inversedBy}:`\n\t\t\t\tif (!targetField) {\n\t\t\t\t\treturn errors.add('MODEL_UNDEFINED_FIELD', `${relationDescription} not exists`)\n\t\t\t\t}\n\t\t\t\tif (!isRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_RELATION_REQUIRED', `${relationDescription} not a relation`)\n\t\t\t\t}\n\t\t\t\tif (targetField.target !== entityName) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference to entity ${entityName} expected, but ${targetField.target} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (!isInverseRelation(targetField)) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} not an inverse relation`)\n\t\t\t\t}\n\t\t\t\tif (!targetField.ownedBy) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} owning relation is not set`)\n\t\t\t\t}\n\t\t\t\tif (targetField.ownedBy !== field.name) {\n\t\t\t\t\treturn errors.add(\n\t\t\t\t\t\t'MODEL_INVALID_RELATION_DEFINITION',\n\t\t\t\t\t\t`${relationDescription} back reference ${entityName}::${field.name} expected, ${targetField.target}::${targetField.ownedBy} given`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.OneHasOne && targetField.type !== Model.RelationType.OneHasOne) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"OneHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasOne && targetField.type !== Model.RelationType.OneHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasOne\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t\tif (field.type === Model.RelationType.ManyHasMany && targetField.type !== Model.RelationType.ManyHasMany) {\n\t\t\t\t\treturn errors.add('MODEL_INVALID_RELATION_DEFINITION', `${relationDescription} \"ManyHasMany\" type expected, \"${targetField.type}\" given`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateIdentifier(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (!value.match(IDENTIFIER_PATTERN)) {\n\t\t\treturn errorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} must match pattern ${IDENTIFIER_PATTERN.source}`)\n\t\t}\n\t\tif (RESERVED_WORDS.includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_IDENTIFIER', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateEntityName(value: string, errorBuilder: ErrorBuilder) {\n\t\tif (['Query', 'Mutation'].includes(value)) {\n\t\t\terrorBuilder.add('MODEL_INVALID_ENTITY_NAME', `${value} is reserved word`)\n\t\t}\n\t}\n\n\tprivate validateMetaSuffixCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst entityNames = new Set(entities.map(it => it.name))\n\t\tfor (const entity of entities) {\n\t\t\tif (entity.name.endsWith('Meta')) {\n\t\t\t\tconst baseName = entity.name.substring(0, entity.name.length - 4)\n\t\t\t\tif (entityNames.has(baseName)) {\n\t\t\t\t\terrorBuilder.for(entity.name)\n\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t`entity ${entity.name} collides with entity ${baseName}, because a GraphQL type with \"Meta\" suffix is created for every entity`,\n\t\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateTableNameCollisions(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst relationNames: Record<string, string> = {}\n\t\tfor (const entity of entities) {\n\t\t\tconst description = `table name ${entity.tableName} of entity ${entity.name}`\n\t\t\tif (relationNames[entity.tableName]) {\n\t\t\t\terrorBuilder\n\t\t\t\t\t.for(entity.name)\n\t\t\t\t\t.add('MODEL_NAME_COLLISION', `${description} collides with a ${relationNames[entity.tableName]}`)\n\t\t\t} else {\n\t\t\t\trelationNames[entity.tableName] = description\n\t\t\t}\n\t\t}\n\t\tfor (const entity of entities) {\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entity.name)\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitManyHasManyOwning: ({ entity, relation }) => {\n\t\t\t\t\tconst joiningTable = relation.joiningTable\n\t\t\t\t\tconst description = `joining table name ${joiningTable.tableName} of relation ${entity.name}::${relation.name}`\n\t\t\t\t\tif (relationNames[joiningTable.tableName]) {\n\t\t\t\t\t\tentityErrorBuilder\n\t\t\t\t\t\t\t.for(relation.name)\n\t\t\t\t\t\t\t.add(\n\t\t\t\t\t\t\t\t'MODEL_NAME_COLLISION',\n\t\t\t\t\t\t\t\t`${description} collides with a ${relationNames[joiningTable.tableName]}.`\n\t\t\t\t\t\t\t\t\t+ 'Consider using plural for a relation name or change the joining table name using .joiningTable(...) in schema definition.',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trelationNames[joiningTable.tableName] = description\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tvisitColumn: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate validateAliasedTypesCollision(entities: Model.Entity[], errorBuilder: ErrorBuilder) {\n\t\tconst aliasedTypes = new Map<string, Model.ColumnType>()\n\t\tfor (const entity of entities) {\n\t\t\tacceptEveryFieldVisitor(this.model, entity, {\n\t\t\t\tvisitColumn: ({ column }) => {\n\t\t\t\t\tif (!column.typeAlias) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tif (aliasedTypes.has(column.typeAlias) && aliasedTypes.get(column.typeAlias) !== column.type) {\n\t\t\t\t\t\terrorBuilder\n\t\t\t\t\t\t\t.for(column.name)\n\t\t\t\t\t\t\t.add('MODEL_NAME_COLLISION', `Type alias ${column.typeAlias} already exists for base type ${column.type}`)\n\t\t\t\t\t}\n\t\t\t\t\taliasedTypes.set(column.typeAlias, column.type)\n\t\t\t\t},\n\t\t\t\tvisitManyHasManyOwning: () => {},\n\t\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\t\tvisitOneHasMany: () => {},\n\t\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\t\tvisitManyHasOne: () => {},\n\t\t\t})\n\t\t}\n\t}\n}\n\nconst isRelation = (field: Model.AnyField): field is Model.AnyRelation => Object.values(Model.RelationType).includes(field.type as Model.RelationType)\n"],"names":["targetEntity","entity"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/SchemaValidator.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { ValidationError, ValidationErrorCode } from './errors'\nimport { AclValidator } from './AclValidator'\nimport { ModelValidator } from './ModelValidator'\nimport { ValidationValidator } from './ValidationValidator'\nimport { ActionsValidator } from './ActionsValidator'\n\nexport interface SchemaValidatorSkippedErrors {\n\treadonly code: ValidationErrorCode\n\treadonly skipUntil?: string\n\treadonly path?: string\n}\n\nexport class SchemaValidator {\n\tpublic static validate(schema: Schema, skippedErrors: SchemaValidatorSkippedErrors[] = []): ValidationError[] {\n\t\tconst modelValidator = new ModelValidator(schema.model)\n\t\tconst modelErrors = modelValidator.validate()\n\n\t\tconst aclValidator = new AclValidator(schema.model)\n\t\tconst aclErrors = aclValidator.validate(schema.acl)\n\n\t\tconst validationValidator = new ValidationValidator(schema.model)\n\t\tconst validationErrors = validationValidator.validate(schema.validation)\n\n\t\tconst actionsValidator = new ActionsValidator(schema.model)\n\t\tconst actionsErrors = actionsValidator.validate(schema.actions)\n\n\t\tconst allErrors = [...aclErrors, ...modelErrors, ...validationErrors, ...actionsErrors]\n\t\tif (skippedErrors.length === 0) {\n\t\t\treturn allErrors\n\t\t}\n\t\treturn allErrors.filter(\n\t\t\terr =>\n\t\t\t\t!skippedErrors.some(\n\t\t\t\t\trule =>\n\t\t\t\t\t\terr.code === rule.code\n\t\t\t\t\t\t&& (!rule.path || err.path.join('.') === rule.path),\n\t\t\t\t),\n\t\t)\n\t}\n}\n"],"names":["ModelValidator","AclValidator","ValidationValidator","ActionsValidator"],"mappings":";;;;;;AAaO,MAAM,gBAAgB;AAAA,EAC5B,OAAc,SAAS,QAAgB,gBAAgD,IAAuB;AAC7G,UAAM,iBAAiB,IAAIA,8BAAe,OAAO,KAAK;AACtD,UAAM,cAAc,eAAe,SAAA;AAEnC,UAAM,eAAe,IAAIC,0BAAa,OAAO,KAAK;AAClD,UAAM,YAAY,aAAa,SAAS,OAAO,GAAG;AAElD,UAAM,sBAAsB,IAAIC,wCAAoB,OAAO,KAAK;AAChE,UAAM,mBAAmB,oBAAoB,SAAS,OAAO,UAAU;AAEvE,UAAM,mBAAmB,IAAIC,kCAAiB,OAAO,KAAK;AAC1D,UAAM,gBAAgB,iBAAiB,SAAS,OAAO,OAAO;AAE9D,UAAM,YAAY,CAAC,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,aAAa;AACtF,QAAI,cAAc,WAAW,GAAG;AAC/B,aAAO;AAAA,IACR;AACA,WAAO,UAAU;AAAA,MAChB,CAAA,QACC,CAAC,cAAc;AAAA,QACd,CAAA,SACC,IAAI,SAAS,KAAK,SACd,CAAC,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK;AAAA,MAAA;AAAA,IAChD;AAAA,EAEH;AACD;;"}
1
+ {"version":3,"file":"SchemaValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/SchemaValidator.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { ValidationError, ValidationErrorCode } from './errors.js'\nimport { AclValidator } from './AclValidator.js'\nimport { ModelValidator } from './ModelValidator.js'\nimport { ValidationValidator } from './ValidationValidator.js'\nimport { ActionsValidator } from './ActionsValidator.js'\n\nexport interface SchemaValidatorSkippedErrors {\n\treadonly code: ValidationErrorCode\n\treadonly skipUntil?: string\n\treadonly path?: string\n}\n\nexport class SchemaValidator {\n\tpublic static validate(schema: Schema, skippedErrors: SchemaValidatorSkippedErrors[] = []): ValidationError[] {\n\t\tconst modelValidator = new ModelValidator(schema.model)\n\t\tconst modelErrors = modelValidator.validate()\n\n\t\tconst aclValidator = new AclValidator(schema.model)\n\t\tconst aclErrors = aclValidator.validate(schema.acl)\n\n\t\tconst validationValidator = new ValidationValidator(schema.model)\n\t\tconst validationErrors = validationValidator.validate(schema.validation)\n\n\t\tconst actionsValidator = new ActionsValidator(schema.model)\n\t\tconst actionsErrors = actionsValidator.validate(schema.actions)\n\n\t\tconst allErrors = [...aclErrors, ...modelErrors, ...validationErrors, ...actionsErrors]\n\t\tif (skippedErrors.length === 0) {\n\t\t\treturn allErrors\n\t\t}\n\t\treturn allErrors.filter(\n\t\t\terr =>\n\t\t\t\t!skippedErrors.some(\n\t\t\t\t\trule =>\n\t\t\t\t\t\terr.code === rule.code\n\t\t\t\t\t\t&& (!rule.path || err.path.join('.') === rule.path),\n\t\t\t\t),\n\t\t)\n\t}\n}\n"],"names":["ModelValidator","AclValidator","ValidationValidator","ActionsValidator"],"mappings":";;;;;;AAaO,MAAM,gBAAgB;AAAA,EAC5B,OAAc,SAAS,QAAgB,gBAAgD,IAAuB;AAC7G,UAAM,iBAAiB,IAAIA,8BAAe,OAAO,KAAK;AACtD,UAAM,cAAc,eAAe,SAAA;AAEnC,UAAM,eAAe,IAAIC,0BAAa,OAAO,KAAK;AAClD,UAAM,YAAY,aAAa,SAAS,OAAO,GAAG;AAElD,UAAM,sBAAsB,IAAIC,wCAAoB,OAAO,KAAK;AAChE,UAAM,mBAAmB,oBAAoB,SAAS,OAAO,UAAU;AAEvE,UAAM,mBAAmB,IAAIC,kCAAiB,OAAO,KAAK;AAC1D,UAAM,gBAAgB,iBAAiB,SAAS,OAAO,OAAO;AAE9D,UAAM,YAAY,CAAC,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,aAAa;AACtF,QAAI,cAAc,WAAW,GAAG;AAC/B,aAAO;AAAA,IACR;AACA,WAAO,UAAU;AAAA,MAChB,CAAA,QACC,CAAC,cAAc;AAAA,QACd,CAAA,SACC,IAAI,SAAS,KAAK,SACd,CAAC,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK;AAAA,MAAA;AAAA,IAChD;AAAA,EAEH;AACD;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaValidator.js","sources":["../../../../../packages/schema-utils/src/validation/SchemaValidator.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { ValidationError, ValidationErrorCode } from './errors'\nimport { AclValidator } from './AclValidator'\nimport { ModelValidator } from './ModelValidator'\nimport { ValidationValidator } from './ValidationValidator'\nimport { ActionsValidator } from './ActionsValidator'\n\nexport interface SchemaValidatorSkippedErrors {\n\treadonly code: ValidationErrorCode\n\treadonly skipUntil?: string\n\treadonly path?: string\n}\n\nexport class SchemaValidator {\n\tpublic static validate(schema: Schema, skippedErrors: SchemaValidatorSkippedErrors[] = []): ValidationError[] {\n\t\tconst modelValidator = new ModelValidator(schema.model)\n\t\tconst modelErrors = modelValidator.validate()\n\n\t\tconst aclValidator = new AclValidator(schema.model)\n\t\tconst aclErrors = aclValidator.validate(schema.acl)\n\n\t\tconst validationValidator = new ValidationValidator(schema.model)\n\t\tconst validationErrors = validationValidator.validate(schema.validation)\n\n\t\tconst actionsValidator = new ActionsValidator(schema.model)\n\t\tconst actionsErrors = actionsValidator.validate(schema.actions)\n\n\t\tconst allErrors = [...aclErrors, ...modelErrors, ...validationErrors, ...actionsErrors]\n\t\tif (skippedErrors.length === 0) {\n\t\t\treturn allErrors\n\t\t}\n\t\treturn allErrors.filter(\n\t\t\terr =>\n\t\t\t\t!skippedErrors.some(\n\t\t\t\t\trule =>\n\t\t\t\t\t\terr.code === rule.code\n\t\t\t\t\t\t&& (!rule.path || err.path.join('.') === rule.path),\n\t\t\t\t),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;AAaO,MAAM,gBAAgB;AAAA,EAC5B,OAAc,SAAS,QAAgB,gBAAgD,IAAuB;AAC7G,UAAM,iBAAiB,IAAI,eAAe,OAAO,KAAK;AACtD,UAAM,cAAc,eAAe,SAAA;AAEnC,UAAM,eAAe,IAAI,aAAa,OAAO,KAAK;AAClD,UAAM,YAAY,aAAa,SAAS,OAAO,GAAG;AAElD,UAAM,sBAAsB,IAAI,oBAAoB,OAAO,KAAK;AAChE,UAAM,mBAAmB,oBAAoB,SAAS,OAAO,UAAU;AAEvE,UAAM,mBAAmB,IAAI,iBAAiB,OAAO,KAAK;AAC1D,UAAM,gBAAgB,iBAAiB,SAAS,OAAO,OAAO;AAE9D,UAAM,YAAY,CAAC,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,aAAa;AACtF,QAAI,cAAc,WAAW,GAAG;AAC/B,aAAO;AAAA,IACR;AACA,WAAO,UAAU;AAAA,MAChB,CAAA,QACC,CAAC,cAAc;AAAA,QACd,CAAA,SACC,IAAI,SAAS,KAAK,SACd,CAAC,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK;AAAA,MAAA;AAAA,IAChD;AAAA,EAEH;AACD;"}
1
+ {"version":3,"file":"SchemaValidator.js","sources":["../../../../../packages/schema-utils/src/validation/SchemaValidator.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { ValidationError, ValidationErrorCode } from './errors.js'\nimport { AclValidator } from './AclValidator.js'\nimport { ModelValidator } from './ModelValidator.js'\nimport { ValidationValidator } from './ValidationValidator.js'\nimport { ActionsValidator } from './ActionsValidator.js'\n\nexport interface SchemaValidatorSkippedErrors {\n\treadonly code: ValidationErrorCode\n\treadonly skipUntil?: string\n\treadonly path?: string\n}\n\nexport class SchemaValidator {\n\tpublic static validate(schema: Schema, skippedErrors: SchemaValidatorSkippedErrors[] = []): ValidationError[] {\n\t\tconst modelValidator = new ModelValidator(schema.model)\n\t\tconst modelErrors = modelValidator.validate()\n\n\t\tconst aclValidator = new AclValidator(schema.model)\n\t\tconst aclErrors = aclValidator.validate(schema.acl)\n\n\t\tconst validationValidator = new ValidationValidator(schema.model)\n\t\tconst validationErrors = validationValidator.validate(schema.validation)\n\n\t\tconst actionsValidator = new ActionsValidator(schema.model)\n\t\tconst actionsErrors = actionsValidator.validate(schema.actions)\n\n\t\tconst allErrors = [...aclErrors, ...modelErrors, ...validationErrors, ...actionsErrors]\n\t\tif (skippedErrors.length === 0) {\n\t\t\treturn allErrors\n\t\t}\n\t\treturn allErrors.filter(\n\t\t\terr =>\n\t\t\t\t!skippedErrors.some(\n\t\t\t\t\trule =>\n\t\t\t\t\t\terr.code === rule.code\n\t\t\t\t\t\t&& (!rule.path || err.path.join('.') === rule.path),\n\t\t\t\t),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;AAaO,MAAM,gBAAgB;AAAA,EAC5B,OAAc,SAAS,QAAgB,gBAAgD,IAAuB;AAC7G,UAAM,iBAAiB,IAAI,eAAe,OAAO,KAAK;AACtD,UAAM,cAAc,eAAe,SAAA;AAEnC,UAAM,eAAe,IAAI,aAAa,OAAO,KAAK;AAClD,UAAM,YAAY,aAAa,SAAS,OAAO,GAAG;AAElD,UAAM,sBAAsB,IAAI,oBAAoB,OAAO,KAAK;AAChE,UAAM,mBAAmB,oBAAoB,SAAS,OAAO,UAAU;AAEvE,UAAM,mBAAmB,IAAI,iBAAiB,OAAO,KAAK;AAC1D,UAAM,gBAAgB,iBAAiB,SAAS,OAAO,OAAO;AAE9D,UAAM,YAAY,CAAC,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,aAAa;AACtF,QAAI,cAAc,WAAW,GAAG;AAC/B,aAAO;AAAA,IACR;AACA,WAAO,UAAU;AAAA,MAChB,CAAA,QACC,CAAC,cAAc;AAAA,QACd,CAAA,SACC,IAAI,SAAS,KAAK,SACd,CAAC,KAAK,QAAQ,IAAI,KAAK,KAAK,GAAG,MAAM,KAAK;AAAA,MAAA;AAAA,IAChD;AAAA,EAEH;AACD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/ValidationValidator.ts"],"sourcesContent":["import { Model, Validation } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors'\nimport { acceptFieldVisitor } from '../model'\n\nexport class ValidationValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(schema: Validation.Schema): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], ['validation'])\n\t\tfor (const entityName in schema) {\n\t\t\tconst entity = this.model.entities[entityName]\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entityName)\n\t\t\tif (!entity) {\n\t\t\t\tentityErrorBuilder.add('VALIDATION_UNDEFINED_ENTITY', 'Entity not found')\n\t\t\t} else {\n\t\t\t\tthis.validateEntityRules(entityErrorBuilder, schema[entityName], entity)\n\t\t\t}\n\t\t}\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEntityRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tentitySchema: Validation.EntityRules,\n\t\tentity: Model.Entity,\n\t): void {\n\t\tfor (const fieldName in entitySchema) {\n\t\t\tconst field = entity.fields[fieldName]\n\t\t\tconst fieldErrorBuilder = errorBuilder.for(fieldName)\n\t\t\tif (!field) {\n\t\t\t\tfieldErrorBuilder.add('VALIDATION_UNDEFINED_FIELD', 'Field not found')\n\t\t\t} else {\n\t\t\t\tthis.validateFieldRules(fieldErrorBuilder, entitySchema[fieldName], entity, field)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateFieldRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tfieldSchema: readonly Validation.ValidationRule[],\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tfor (const i in fieldSchema) {\n\t\t\tthis.validateFieldRule(errorBuilder.for(i), fieldSchema[i], entity, field)\n\t\t}\n\t}\n\n\tprivate validateFieldRule(\n\t\terrorBuilder: ErrorBuilder,\n\t\trule: Validation.ValidationRule,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst errorMessage = acceptFieldVisitor(this.model, entity, field, {\n\t\t\tvisitColumn: () => null,\n\t\t\tvisitHasOne: () => null,\n\t\t\tvisitHasMany: () => {\n\t\t\t\treturn 'Rules on has-many relations are currently not supported.'\n\t\t\t},\n\t\t})\n\t\tif (errorMessage) {\n\t\t\treturn errorBuilder.add('VALIDATION_NOT_IMPLEMENTED', errorMessage)\n\t\t}\n\t\tthis.validateValidator(errorBuilder.for('validator'), rule.validator, entity, field)\n\t}\n\n\tprivate validateValidator(\n\t\terrorBuilder: ErrorBuilder,\n\t\tvalidator: Validation.Validator,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst validatorCast = validator as Validation.Validator\n\t\tswitch (validatorCast.operation) {\n\t\t\tcase 'and':\n\t\t\tcase 'or':\n\t\t\t\treturn validatorCast.args\n\t\t\t\t\t.forEach((it, index) => this.validateValidatorArgument(errorBuilder.for(String(index)), it, entity, field))\n\t\t\tcase 'conditional':\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('condition'), validatorCast.args[0], entity, field)\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('rule'), validatorCast.args[1], entity, field)\n\t\t\t\treturn\n\t\t\tcase 'pattern':\n\t\t\tcase 'lengthRange':\n\t\t\tcase 'range':\n\t\t\tcase 'equals':\n\t\t\tcase 'empty':\n\t\t\tcase 'defined':\n\t\t\t\treturn\n\t\t\tcase 'not':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'inContext':\n\t\t\t\tconst pathArgResult = this.validatePathArgument(errorBuilder.for('path'), validatorCast.args[0], entity)\n\t\t\t\tif (pathArgResult === undefined) {\n\t\t\t\t\treturn undefined\n\t\t\t\t}\n\t\t\t\treturn this.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tpathArgResult,\n\t\t\t\t)\n\t\t\tcase 'every':\n\t\t\tcase 'any':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'filter':\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('filter'),\n\t\t\t\t\tvalidatorCast.args[0],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\t;((_: never) => {\n\t\t\t\t\terrorBuilder.for('operation', `Operation ${(validatorCast as any).operation} is not an valid option`)\n\t\t\t\t})(validatorCast)\n\t\t}\n\t}\n\n\tprivate validateValidatorArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.ValidatorArgument,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tthis.validateValidator(errorBuilder.for('validator'), argument.validator, entity, field)\n\t}\n\n\tprivate validatePathArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.PathArgument,\n\t\tentity: Model.Entity,\n\t): Model.AnyField | undefined {\n\t\tconst isRelation = acceptFieldVisitor(this.model, entity, argument.path[0], {\n\t\t\tvisitColumn: () => false,\n\t\t\tvisitRelation: () => true,\n\t\t})\n\t\tif (isRelation) {\n\t\t\terrorBuilder.add('VALIDATION_NOT_IMPLEMENTED', 'Rules depending on relations are currently not supported.')\n\t\t\treturn undefined\n\t\t}\n\t\treturn entity.fields[argument.path[0]]\n\t}\n}\n"],"names":["ErrorBuilder","acceptFieldVisitor"],"mappings":"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"}
1
+ {"version":3,"file":"ValidationValidator.cjs","sources":["../../../../../packages/schema-utils/src/validation/ValidationValidator.ts"],"sourcesContent":["import { Model, Validation } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors.js'\nimport { acceptFieldVisitor } from '../model/index.js'\n\nexport class ValidationValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(schema: Validation.Schema): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], ['validation'])\n\t\tfor (const entityName in schema) {\n\t\t\tconst entity = this.model.entities[entityName]\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entityName)\n\t\t\tif (!entity) {\n\t\t\t\tentityErrorBuilder.add('VALIDATION_UNDEFINED_ENTITY', 'Entity not found')\n\t\t\t} else {\n\t\t\t\tthis.validateEntityRules(entityErrorBuilder, schema[entityName], entity)\n\t\t\t}\n\t\t}\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEntityRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tentitySchema: Validation.EntityRules,\n\t\tentity: Model.Entity,\n\t): void {\n\t\tfor (const fieldName in entitySchema) {\n\t\t\tconst field = entity.fields[fieldName]\n\t\t\tconst fieldErrorBuilder = errorBuilder.for(fieldName)\n\t\t\tif (!field) {\n\t\t\t\tfieldErrorBuilder.add('VALIDATION_UNDEFINED_FIELD', 'Field not found')\n\t\t\t} else {\n\t\t\t\tthis.validateFieldRules(fieldErrorBuilder, entitySchema[fieldName], entity, field)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateFieldRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tfieldSchema: readonly Validation.ValidationRule[],\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tfor (const i in fieldSchema) {\n\t\t\tthis.validateFieldRule(errorBuilder.for(i), fieldSchema[i], entity, field)\n\t\t}\n\t}\n\n\tprivate validateFieldRule(\n\t\terrorBuilder: ErrorBuilder,\n\t\trule: Validation.ValidationRule,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst errorMessage = acceptFieldVisitor(this.model, entity, field, {\n\t\t\tvisitColumn: () => null,\n\t\t\tvisitHasOne: () => null,\n\t\t\tvisitHasMany: () => {\n\t\t\t\treturn 'Rules on has-many relations are currently not supported.'\n\t\t\t},\n\t\t})\n\t\tif (errorMessage) {\n\t\t\treturn errorBuilder.add('VALIDATION_NOT_IMPLEMENTED', errorMessage)\n\t\t}\n\t\tthis.validateValidator(errorBuilder.for('validator'), rule.validator, entity, field)\n\t}\n\n\tprivate validateValidator(\n\t\terrorBuilder: ErrorBuilder,\n\t\tvalidator: Validation.Validator,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst validatorCast = validator as Validation.Validator\n\t\tswitch (validatorCast.operation) {\n\t\t\tcase 'and':\n\t\t\tcase 'or':\n\t\t\t\treturn validatorCast.args\n\t\t\t\t\t.forEach((it, index) => this.validateValidatorArgument(errorBuilder.for(String(index)), it, entity, field))\n\t\t\tcase 'conditional':\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('condition'), validatorCast.args[0], entity, field)\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('rule'), validatorCast.args[1], entity, field)\n\t\t\t\treturn\n\t\t\tcase 'pattern':\n\t\t\tcase 'lengthRange':\n\t\t\tcase 'range':\n\t\t\tcase 'equals':\n\t\t\tcase 'empty':\n\t\t\tcase 'defined':\n\t\t\t\treturn\n\t\t\tcase 'not':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'inContext':\n\t\t\t\tconst pathArgResult = this.validatePathArgument(errorBuilder.for('path'), validatorCast.args[0], entity)\n\t\t\t\tif (pathArgResult === undefined) {\n\t\t\t\t\treturn undefined\n\t\t\t\t}\n\t\t\t\treturn this.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tpathArgResult,\n\t\t\t\t)\n\t\t\tcase 'every':\n\t\t\tcase 'any':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'filter':\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('filter'),\n\t\t\t\t\tvalidatorCast.args[0],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\t;((_: never) => {\n\t\t\t\t\terrorBuilder.for('operation', `Operation ${(validatorCast as any).operation} is not an valid option`)\n\t\t\t\t})(validatorCast)\n\t\t}\n\t}\n\n\tprivate validateValidatorArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.ValidatorArgument,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tthis.validateValidator(errorBuilder.for('validator'), argument.validator, entity, field)\n\t}\n\n\tprivate validatePathArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.PathArgument,\n\t\tentity: Model.Entity,\n\t): Model.AnyField | undefined {\n\t\tconst isRelation = acceptFieldVisitor(this.model, entity, argument.path[0], {\n\t\t\tvisitColumn: () => false,\n\t\t\tvisitRelation: () => true,\n\t\t})\n\t\tif (isRelation) {\n\t\t\terrorBuilder.add('VALIDATION_NOT_IMPLEMENTED', 'Rules depending on relations are currently not supported.')\n\t\t\treturn undefined\n\t\t}\n\t\treturn entity.fields[argument.path[0]]\n\t}\n}\n"],"names":["ErrorBuilder","acceptFieldVisitor"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationValidator.js","sources":["../../../../../packages/schema-utils/src/validation/ValidationValidator.ts"],"sourcesContent":["import { Model, Validation } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors'\nimport { acceptFieldVisitor } from '../model'\n\nexport class ValidationValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(schema: Validation.Schema): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], ['validation'])\n\t\tfor (const entityName in schema) {\n\t\t\tconst entity = this.model.entities[entityName]\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entityName)\n\t\t\tif (!entity) {\n\t\t\t\tentityErrorBuilder.add('VALIDATION_UNDEFINED_ENTITY', 'Entity not found')\n\t\t\t} else {\n\t\t\t\tthis.validateEntityRules(entityErrorBuilder, schema[entityName], entity)\n\t\t\t}\n\t\t}\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEntityRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tentitySchema: Validation.EntityRules,\n\t\tentity: Model.Entity,\n\t): void {\n\t\tfor (const fieldName in entitySchema) {\n\t\t\tconst field = entity.fields[fieldName]\n\t\t\tconst fieldErrorBuilder = errorBuilder.for(fieldName)\n\t\t\tif (!field) {\n\t\t\t\tfieldErrorBuilder.add('VALIDATION_UNDEFINED_FIELD', 'Field not found')\n\t\t\t} else {\n\t\t\t\tthis.validateFieldRules(fieldErrorBuilder, entitySchema[fieldName], entity, field)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateFieldRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tfieldSchema: readonly Validation.ValidationRule[],\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tfor (const i in fieldSchema) {\n\t\t\tthis.validateFieldRule(errorBuilder.for(i), fieldSchema[i], entity, field)\n\t\t}\n\t}\n\n\tprivate validateFieldRule(\n\t\terrorBuilder: ErrorBuilder,\n\t\trule: Validation.ValidationRule,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst errorMessage = acceptFieldVisitor(this.model, entity, field, {\n\t\t\tvisitColumn: () => null,\n\t\t\tvisitHasOne: () => null,\n\t\t\tvisitHasMany: () => {\n\t\t\t\treturn 'Rules on has-many relations are currently not supported.'\n\t\t\t},\n\t\t})\n\t\tif (errorMessage) {\n\t\t\treturn errorBuilder.add('VALIDATION_NOT_IMPLEMENTED', errorMessage)\n\t\t}\n\t\tthis.validateValidator(errorBuilder.for('validator'), rule.validator, entity, field)\n\t}\n\n\tprivate validateValidator(\n\t\terrorBuilder: ErrorBuilder,\n\t\tvalidator: Validation.Validator,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst validatorCast = validator as Validation.Validator\n\t\tswitch (validatorCast.operation) {\n\t\t\tcase 'and':\n\t\t\tcase 'or':\n\t\t\t\treturn validatorCast.args\n\t\t\t\t\t.forEach((it, index) => this.validateValidatorArgument(errorBuilder.for(String(index)), it, entity, field))\n\t\t\tcase 'conditional':\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('condition'), validatorCast.args[0], entity, field)\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('rule'), validatorCast.args[1], entity, field)\n\t\t\t\treturn\n\t\t\tcase 'pattern':\n\t\t\tcase 'lengthRange':\n\t\t\tcase 'range':\n\t\t\tcase 'equals':\n\t\t\tcase 'empty':\n\t\t\tcase 'defined':\n\t\t\t\treturn\n\t\t\tcase 'not':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'inContext':\n\t\t\t\tconst pathArgResult = this.validatePathArgument(errorBuilder.for('path'), validatorCast.args[0], entity)\n\t\t\t\tif (pathArgResult === undefined) {\n\t\t\t\t\treturn undefined\n\t\t\t\t}\n\t\t\t\treturn this.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tpathArgResult,\n\t\t\t\t)\n\t\t\tcase 'every':\n\t\t\tcase 'any':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'filter':\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('filter'),\n\t\t\t\t\tvalidatorCast.args[0],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\t;((_: never) => {\n\t\t\t\t\terrorBuilder.for('operation', `Operation ${(validatorCast as any).operation} is not an valid option`)\n\t\t\t\t})(validatorCast)\n\t\t}\n\t}\n\n\tprivate validateValidatorArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.ValidatorArgument,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tthis.validateValidator(errorBuilder.for('validator'), argument.validator, entity, field)\n\t}\n\n\tprivate validatePathArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.PathArgument,\n\t\tentity: Model.Entity,\n\t): Model.AnyField | undefined {\n\t\tconst isRelation = acceptFieldVisitor(this.model, entity, argument.path[0], {\n\t\t\tvisitColumn: () => false,\n\t\t\tvisitRelation: () => true,\n\t\t})\n\t\tif (isRelation) {\n\t\t\terrorBuilder.add('VALIDATION_NOT_IMPLEMENTED', 'Rules depending on relations are currently not supported.')\n\t\t\treturn undefined\n\t\t}\n\t\treturn entity.fields[argument.path[0]]\n\t}\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ValidationValidator.js","sources":["../../../../../packages/schema-utils/src/validation/ValidationValidator.ts"],"sourcesContent":["import { Model, Validation } from '@contember/schema'\nimport { ErrorBuilder, ValidationError } from './errors.js'\nimport { acceptFieldVisitor } from '../model/index.js'\n\nexport class ValidationValidator {\n\tconstructor(private readonly model: Model.Schema) {}\n\n\tpublic validate(schema: Validation.Schema): ValidationError[] {\n\t\tconst errorBuilder = new ErrorBuilder([], ['validation'])\n\t\tfor (const entityName in schema) {\n\t\t\tconst entity = this.model.entities[entityName]\n\t\t\tconst entityErrorBuilder = errorBuilder.for(entityName)\n\t\t\tif (!entity) {\n\t\t\t\tentityErrorBuilder.add('VALIDATION_UNDEFINED_ENTITY', 'Entity not found')\n\t\t\t} else {\n\t\t\t\tthis.validateEntityRules(entityErrorBuilder, schema[entityName], entity)\n\t\t\t}\n\t\t}\n\t\treturn errorBuilder.errors\n\t}\n\n\tprivate validateEntityRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tentitySchema: Validation.EntityRules,\n\t\tentity: Model.Entity,\n\t): void {\n\t\tfor (const fieldName in entitySchema) {\n\t\t\tconst field = entity.fields[fieldName]\n\t\t\tconst fieldErrorBuilder = errorBuilder.for(fieldName)\n\t\t\tif (!field) {\n\t\t\t\tfieldErrorBuilder.add('VALIDATION_UNDEFINED_FIELD', 'Field not found')\n\t\t\t} else {\n\t\t\t\tthis.validateFieldRules(fieldErrorBuilder, entitySchema[fieldName], entity, field)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate validateFieldRules(\n\t\terrorBuilder: ErrorBuilder,\n\t\tfieldSchema: readonly Validation.ValidationRule[],\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tfor (const i in fieldSchema) {\n\t\t\tthis.validateFieldRule(errorBuilder.for(i), fieldSchema[i], entity, field)\n\t\t}\n\t}\n\n\tprivate validateFieldRule(\n\t\terrorBuilder: ErrorBuilder,\n\t\trule: Validation.ValidationRule,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst errorMessage = acceptFieldVisitor(this.model, entity, field, {\n\t\t\tvisitColumn: () => null,\n\t\t\tvisitHasOne: () => null,\n\t\t\tvisitHasMany: () => {\n\t\t\t\treturn 'Rules on has-many relations are currently not supported.'\n\t\t\t},\n\t\t})\n\t\tif (errorMessage) {\n\t\t\treturn errorBuilder.add('VALIDATION_NOT_IMPLEMENTED', errorMessage)\n\t\t}\n\t\tthis.validateValidator(errorBuilder.for('validator'), rule.validator, entity, field)\n\t}\n\n\tprivate validateValidator(\n\t\terrorBuilder: ErrorBuilder,\n\t\tvalidator: Validation.Validator,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tconst validatorCast = validator as Validation.Validator\n\t\tswitch (validatorCast.operation) {\n\t\t\tcase 'and':\n\t\t\tcase 'or':\n\t\t\t\treturn validatorCast.args\n\t\t\t\t\t.forEach((it, index) => this.validateValidatorArgument(errorBuilder.for(String(index)), it, entity, field))\n\t\t\tcase 'conditional':\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('condition'), validatorCast.args[0], entity, field)\n\t\t\t\tthis.validateValidatorArgument(errorBuilder.for('rule'), validatorCast.args[1], entity, field)\n\t\t\t\treturn\n\t\t\tcase 'pattern':\n\t\t\tcase 'lengthRange':\n\t\t\tcase 'range':\n\t\t\tcase 'equals':\n\t\t\tcase 'empty':\n\t\t\tcase 'defined':\n\t\t\t\treturn\n\t\t\tcase 'not':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'inContext':\n\t\t\t\tconst pathArgResult = this.validatePathArgument(errorBuilder.for('path'), validatorCast.args[0], entity)\n\t\t\t\tif (pathArgResult === undefined) {\n\t\t\t\t\treturn undefined\n\t\t\t\t}\n\t\t\t\treturn this.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tpathArgResult,\n\t\t\t\t)\n\t\t\tcase 'every':\n\t\t\tcase 'any':\n\t\t\t\treturn this.validateValidatorArgument(errorBuilder, validatorCast.args[0], entity, field)\n\t\t\tcase 'filter':\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('filter'),\n\t\t\t\t\tvalidatorCast.args[0],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\tthis.validateValidatorArgument(\n\t\t\t\t\terrorBuilder.for('validator'),\n\t\t\t\t\tvalidatorCast.args[1],\n\t\t\t\t\tentity,\n\t\t\t\t\tfield,\n\t\t\t\t)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\t;((_: never) => {\n\t\t\t\t\terrorBuilder.for('operation', `Operation ${(validatorCast as any).operation} is not an valid option`)\n\t\t\t\t})(validatorCast)\n\t\t}\n\t}\n\n\tprivate validateValidatorArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.ValidatorArgument,\n\t\tentity: Model.Entity,\n\t\tfield: Model.AnyField,\n\t): void {\n\t\tthis.validateValidator(errorBuilder.for('validator'), argument.validator, entity, field)\n\t}\n\n\tprivate validatePathArgument(\n\t\terrorBuilder: ErrorBuilder,\n\t\targument: Validation.PathArgument,\n\t\tentity: Model.Entity,\n\t): Model.AnyField | undefined {\n\t\tconst isRelation = acceptFieldVisitor(this.model, entity, argument.path[0], {\n\t\t\tvisitColumn: () => false,\n\t\t\tvisitRelation: () => true,\n\t\t})\n\t\tif (isRelation) {\n\t\t\terrorBuilder.add('VALIDATION_NOT_IMPLEMENTED', 'Rules depending on relations are currently not supported.')\n\t\t\treturn undefined\n\t\t}\n\t\treturn entity.fields[argument.path[0]]\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","sources":["../../../../../packages/schema-utils/src/validation/errors.ts"],"sourcesContent":["export type ValidationErrorCode =\n\t| 'MODEL_NAME_MISMATCH'\n\t| 'MODEL_UNDEFINED_FIELD'\n\t| 'MODEL_INVALID_FIELD'\n\t| 'MODEL_UNDEFINED_ENTITY'\n\t| 'MODEL_RELATION_REQUIRED'\n\t| 'MODEL_INVALID_RELATION_DEFINITION'\n\t| 'MODEL_INVALID_COLUMN_DEFINITION'\n\t| 'MODEL_INVALID_VIEW_USAGE'\n\t| 'MODEL_INVALID_IDENTIFIER'\n\t| 'MODEL_INVALID_ENTITY_NAME'\n\t| 'MODEL_INVALID_CONSTRAINT'\n\t| 'MODEL_NAME_COLLISION'\n\t| 'ACL_INVALID_CONDITION'\n\t| 'ACL_UNDEFINED_VARIABLE'\n\t| 'ACL_UNDEFINED_FIELD'\n\t| 'ACL_UNDEFINED_PREDICATE'\n\t| 'ACL_UNDEFINED_ROLE'\n\t| 'ACL_UNDEFINED_ENTITY'\n\t| 'ACTIONS_NAME_MISMATCH'\n\t| 'ACTIONS_INVALID_CONDITION'\n\t| 'ACTIONS_UNDEFINED_FIELD'\n\t| 'ACTIONS_UNDEFINED_ENTITY'\n\t| 'ACTIONS_UNDEFINED_TRIGGER_TARGET'\n\t| 'ACTIONS_INVALID_SELECTION'\n\t| 'VALIDATION_UNDEFINED_ENTITY'\n\t| 'VALIDATION_UNDEFINED_FIELD'\n\t| 'VALIDATION_NOT_IMPLEMENTED'\n\nexport interface ValidationError {\n\tpath: (string | number)[]\n\tmessage: string\n\tcode: ValidationErrorCode\n}\n\nexport class ErrorBuilder {\n\tconstructor(public readonly errors: ValidationError[], private readonly path: string[] = []) {}\n\n\tfor(...path: string[]): ErrorBuilder {\n\t\treturn new ErrorBuilder(this.errors, [...this.path, ...path])\n\t}\n\n\tadd(code: ValidationErrorCode, message: string): void {\n\t\tthis.errors.push({ path: this.path, message, code })\n\t}\n}\n"],"names":[],"mappings":";;AAmCO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAA4C,OAAiB,IAAI;AAAjE,SAAA,SAAA;AAA4C,SAAA,OAAA;AAAA,EAAsB;AAAA,EAE9F,OAAO,MAA8B;AACpC,WAAO,IAAI,aAAa,KAAK,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,IAAI,MAA2B,SAAuB;AACrD,SAAK,OAAO,KAAK,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM;AAAA,EACpD;AACD;;"}
1
+ {"version":3,"file":"errors.cjs","sources":["../../../../../packages/schema-utils/src/validation/errors.ts"],"sourcesContent":["export type ValidationErrorCode =\n\t| 'MODEL_NAME_MISMATCH'\n\t| 'MODEL_UNDEFINED_FIELD'\n\t| 'MODEL_INVALID_FIELD'\n\t| 'MODEL_UNDEFINED_ENTITY'\n\t| 'MODEL_RELATION_REQUIRED'\n\t| 'MODEL_INVALID_RELATION_DEFINITION'\n\t| 'MODEL_INVALID_COLUMN_DEFINITION'\n\t| 'MODEL_INVALID_JSON_SCHEMA'\n\t| 'MODEL_INVALID_VIEW_USAGE'\n\t| 'MODEL_INVALID_IDENTIFIER'\n\t| 'MODEL_INVALID_ENTITY_NAME'\n\t| 'MODEL_INVALID_CONSTRAINT'\n\t| 'MODEL_INVALID_INDEX'\n\t| 'MODEL_NAME_COLLISION'\n\t| 'ACL_INVALID_CONDITION'\n\t| 'ACL_UNDEFINED_VARIABLE'\n\t| 'ACL_UNDEFINED_FIELD'\n\t| 'ACL_UNDEFINED_PREDICATE'\n\t| 'ACL_UNDEFINED_ROLE'\n\t| 'ACL_UNDEFINED_ENTITY'\n\t| 'ACTIONS_NAME_MISMATCH'\n\t| 'ACTIONS_INVALID_CONDITION'\n\t| 'ACTIONS_UNDEFINED_FIELD'\n\t| 'ACTIONS_UNDEFINED_ENTITY'\n\t| 'ACTIONS_UNDEFINED_TRIGGER_TARGET'\n\t| 'ACTIONS_INVALID_SELECTION'\n\t| 'VALIDATION_UNDEFINED_ENTITY'\n\t| 'VALIDATION_UNDEFINED_FIELD'\n\t| 'VALIDATION_NOT_IMPLEMENTED'\n\nexport interface ValidationError {\n\tpath: (string | number)[]\n\tmessage: string\n\tcode: ValidationErrorCode\n}\n\nexport class ErrorBuilder {\n\tconstructor(public readonly errors: ValidationError[], private readonly path: string[] = []) {}\n\n\tfor(...path: string[]): ErrorBuilder {\n\t\treturn new ErrorBuilder(this.errors, [...this.path, ...path])\n\t}\n\n\tadd(code: ValidationErrorCode, message: string): void {\n\t\tthis.errors.push({ path: this.path, message, code })\n\t}\n}\n"],"names":[],"mappings":";;AAqCO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAA4C,OAAiB,IAAI;AAAjE,SAAA,SAAA;AAA4C,SAAA,OAAA;AAAA,EAAsB;AAAA,EAE9F,OAAO,MAA8B;AACpC,WAAO,IAAI,aAAa,KAAK,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,IAAI,MAA2B,SAAuB;AACrD,SAAK,OAAO,KAAK,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM;AAAA,EACpD;AACD;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sources":["../../../../../packages/schema-utils/src/validation/errors.ts"],"sourcesContent":["export type ValidationErrorCode =\n\t| 'MODEL_NAME_MISMATCH'\n\t| 'MODEL_UNDEFINED_FIELD'\n\t| 'MODEL_INVALID_FIELD'\n\t| 'MODEL_UNDEFINED_ENTITY'\n\t| 'MODEL_RELATION_REQUIRED'\n\t| 'MODEL_INVALID_RELATION_DEFINITION'\n\t| 'MODEL_INVALID_COLUMN_DEFINITION'\n\t| 'MODEL_INVALID_VIEW_USAGE'\n\t| 'MODEL_INVALID_IDENTIFIER'\n\t| 'MODEL_INVALID_ENTITY_NAME'\n\t| 'MODEL_INVALID_CONSTRAINT'\n\t| 'MODEL_NAME_COLLISION'\n\t| 'ACL_INVALID_CONDITION'\n\t| 'ACL_UNDEFINED_VARIABLE'\n\t| 'ACL_UNDEFINED_FIELD'\n\t| 'ACL_UNDEFINED_PREDICATE'\n\t| 'ACL_UNDEFINED_ROLE'\n\t| 'ACL_UNDEFINED_ENTITY'\n\t| 'ACTIONS_NAME_MISMATCH'\n\t| 'ACTIONS_INVALID_CONDITION'\n\t| 'ACTIONS_UNDEFINED_FIELD'\n\t| 'ACTIONS_UNDEFINED_ENTITY'\n\t| 'ACTIONS_UNDEFINED_TRIGGER_TARGET'\n\t| 'ACTIONS_INVALID_SELECTION'\n\t| 'VALIDATION_UNDEFINED_ENTITY'\n\t| 'VALIDATION_UNDEFINED_FIELD'\n\t| 'VALIDATION_NOT_IMPLEMENTED'\n\nexport interface ValidationError {\n\tpath: (string | number)[]\n\tmessage: string\n\tcode: ValidationErrorCode\n}\n\nexport class ErrorBuilder {\n\tconstructor(public readonly errors: ValidationError[], private readonly path: string[] = []) {}\n\n\tfor(...path: string[]): ErrorBuilder {\n\t\treturn new ErrorBuilder(this.errors, [...this.path, ...path])\n\t}\n\n\tadd(code: ValidationErrorCode, message: string): void {\n\t\tthis.errors.push({ path: this.path, message, code })\n\t}\n}\n"],"names":[],"mappings":"AAmCO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAA4C,OAAiB,IAAI;AAAjE,SAAA,SAAA;AAA4C,SAAA,OAAA;AAAA,EAAsB;AAAA,EAE9F,OAAO,MAA8B;AACpC,WAAO,IAAI,aAAa,KAAK,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,IAAI,MAA2B,SAAuB;AACrD,SAAK,OAAO,KAAK,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM;AAAA,EACpD;AACD;"}
1
+ {"version":3,"file":"errors.js","sources":["../../../../../packages/schema-utils/src/validation/errors.ts"],"sourcesContent":["export type ValidationErrorCode =\n\t| 'MODEL_NAME_MISMATCH'\n\t| 'MODEL_UNDEFINED_FIELD'\n\t| 'MODEL_INVALID_FIELD'\n\t| 'MODEL_UNDEFINED_ENTITY'\n\t| 'MODEL_RELATION_REQUIRED'\n\t| 'MODEL_INVALID_RELATION_DEFINITION'\n\t| 'MODEL_INVALID_COLUMN_DEFINITION'\n\t| 'MODEL_INVALID_JSON_SCHEMA'\n\t| 'MODEL_INVALID_VIEW_USAGE'\n\t| 'MODEL_INVALID_IDENTIFIER'\n\t| 'MODEL_INVALID_ENTITY_NAME'\n\t| 'MODEL_INVALID_CONSTRAINT'\n\t| 'MODEL_INVALID_INDEX'\n\t| 'MODEL_NAME_COLLISION'\n\t| 'ACL_INVALID_CONDITION'\n\t| 'ACL_UNDEFINED_VARIABLE'\n\t| 'ACL_UNDEFINED_FIELD'\n\t| 'ACL_UNDEFINED_PREDICATE'\n\t| 'ACL_UNDEFINED_ROLE'\n\t| 'ACL_UNDEFINED_ENTITY'\n\t| 'ACTIONS_NAME_MISMATCH'\n\t| 'ACTIONS_INVALID_CONDITION'\n\t| 'ACTIONS_UNDEFINED_FIELD'\n\t| 'ACTIONS_UNDEFINED_ENTITY'\n\t| 'ACTIONS_UNDEFINED_TRIGGER_TARGET'\n\t| 'ACTIONS_INVALID_SELECTION'\n\t| 'VALIDATION_UNDEFINED_ENTITY'\n\t| 'VALIDATION_UNDEFINED_FIELD'\n\t| 'VALIDATION_NOT_IMPLEMENTED'\n\nexport interface ValidationError {\n\tpath: (string | number)[]\n\tmessage: string\n\tcode: ValidationErrorCode\n}\n\nexport class ErrorBuilder {\n\tconstructor(public readonly errors: ValidationError[], private readonly path: string[] = []) {}\n\n\tfor(...path: string[]): ErrorBuilder {\n\t\treturn new ErrorBuilder(this.errors, [...this.path, ...path])\n\t}\n\n\tadd(code: ValidationErrorCode, message: string): void {\n\t\tthis.errors.push({ path: this.path, message, code })\n\t}\n}\n"],"names":[],"mappings":"AAqCO,MAAM,aAAa;AAAA,EACzB,YAA4B,QAA4C,OAAiB,IAAI;AAAjE,SAAA,SAAA;AAA4C,SAAA,OAAA;AAAA,EAAsB;AAAA,EAE9F,OAAO,MAA8B;AACpC,WAAO,IAAI,aAAa,KAAK,QAAQ,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,IAAI,MAA2B,SAAuB;AACrD,SAAK,OAAO,KAAK,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM;AAAA,EACpD;AACD;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsonSchemaKeywords.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonSchemaKeywords.test.d.ts","sourceRoot":"","sources":["../../../../tests/cases/unit/jsonSchemaKeywords.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsonSchemaToTsType.test.d.ts.map