@contember/schema-utils 2.0.0-alpha.9 → 2.0.0-beta.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 (204) hide show
  1. package/dist/development/index.cjs +2 -0
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +2 -0
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/acl/AllowAllPermissionFactory.cjs.map +1 -1
  6. package/dist/development/src/acl/AllowAllPermissionFactory.js.map +1 -1
  7. package/dist/development/src/acl/PredicateDefinitionProcessor.cjs.map +1 -1
  8. package/dist/development/src/acl/PredicateDefinitionProcessor.js.map +1 -1
  9. package/dist/development/src/acl/schemaUtils.cjs.map +1 -1
  10. package/dist/development/src/acl/schemaUtils.js.map +1 -1
  11. package/dist/development/src/dataUtils.cjs.map +1 -1
  12. package/dist/development/src/dataUtils.js.map +1 -1
  13. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.cjs +1 -2
  14. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.cjs.map +1 -1
  15. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.js +1 -2
  16. package/dist/development/src/definition-generator/AclDefinitionCodeGenerator.js.map +1 -1
  17. package/dist/development/src/definition-generator/DefinitionCodeGenerator.cjs +5 -9
  18. package/dist/development/src/definition-generator/DefinitionCodeGenerator.cjs.map +1 -1
  19. package/dist/development/src/definition-generator/DefinitionCodeGenerator.js +5 -9
  20. package/dist/development/src/definition-generator/DefinitionCodeGenerator.js.map +1 -1
  21. package/dist/development/src/definition-generator/DefinitionNamingConventions.cjs.map +1 -1
  22. package/dist/development/src/definition-generator/DefinitionNamingConventions.js.map +1 -1
  23. package/dist/development/src/definition-generator/TsDefinitionGenerator.cjs.map +1 -1
  24. package/dist/development/src/definition-generator/TsDefinitionGenerator.js.map +1 -1
  25. package/dist/development/src/lax/LaxSchemaConverter.cjs.map +1 -1
  26. package/dist/development/src/lax/LaxSchemaConverter.js.map +1 -1
  27. package/dist/development/src/lax/schema.cjs.map +1 -1
  28. package/dist/development/src/lax/schema.js.map +1 -1
  29. package/dist/development/src/model/NamingConventions.cjs.map +1 -1
  30. package/dist/development/src/model/NamingConventions.js.map +1 -1
  31. package/dist/development/src/model/modelUtils.cjs.map +1 -1
  32. package/dist/development/src/model/modelUtils.js.map +1 -1
  33. package/dist/development/src/model/resolveDefaultColumnType.cjs.map +1 -1
  34. package/dist/development/src/model/resolveDefaultColumnType.js.map +1 -1
  35. package/dist/development/src/schemaChecksum.cjs +9 -0
  36. package/dist/development/src/schemaChecksum.cjs.map +1 -0
  37. package/dist/development/src/schemaChecksum.js +9 -0
  38. package/dist/development/src/schemaChecksum.js.map +1 -0
  39. package/dist/development/src/schemaFilter.cjs.map +1 -1
  40. package/dist/development/src/schemaFilter.js.map +1 -1
  41. package/dist/development/src/schemaNormalizer.cjs.map +1 -1
  42. package/dist/development/src/schemaNormalizer.js.map +1 -1
  43. package/dist/development/src/type-schema/acl.cjs.map +1 -1
  44. package/dist/development/src/type-schema/acl.js.map +1 -1
  45. package/dist/development/src/type-schema/actions.cjs.map +1 -1
  46. package/dist/development/src/type-schema/actions.js.map +1 -1
  47. package/dist/development/src/type-schema/condition.cjs.map +1 -1
  48. package/dist/development/src/type-schema/condition.js.map +1 -1
  49. package/dist/development/src/type-schema/model.cjs +6 -1
  50. package/dist/development/src/type-schema/model.cjs.map +1 -1
  51. package/dist/development/src/type-schema/model.js +7 -1
  52. package/dist/development/src/type-schema/model.js.map +1 -1
  53. package/dist/development/src/type-schema/settings.cjs +1 -0
  54. package/dist/development/src/type-schema/settings.cjs.map +1 -1
  55. package/dist/development/src/type-schema/settings.js +1 -0
  56. package/dist/development/src/type-schema/settings.js.map +1 -1
  57. package/dist/development/src/type-schema/validation.cjs.map +1 -1
  58. package/dist/development/src/type-schema/validation.js.map +1 -1
  59. package/dist/development/src/type-schema/where.cjs.map +1 -1
  60. package/dist/development/src/type-schema/where.js.map +1 -1
  61. package/dist/development/src/utils/deepCompare.cjs.map +1 -1
  62. package/dist/development/src/utils/deepCompare.js.map +1 -1
  63. package/dist/development/src/utils/printJsValue.cjs.map +1 -1
  64. package/dist/development/src/utils/printJsValue.js.map +1 -1
  65. package/dist/development/src/validation/AclValidator.cjs.map +1 -1
  66. package/dist/development/src/validation/AclValidator.js.map +1 -1
  67. package/dist/development/src/validation/ActionsValidator.cjs.map +1 -1
  68. package/dist/development/src/validation/ActionsValidator.js.map +1 -1
  69. package/dist/development/src/validation/MembershipResolver.cjs.map +1 -1
  70. package/dist/development/src/validation/MembershipResolver.js.map +1 -1
  71. package/dist/development/src/validation/ModelValidator.cjs.map +1 -1
  72. package/dist/development/src/validation/ModelValidator.js.map +1 -1
  73. package/dist/development/src/validation/SchemaValidator.cjs.map +1 -1
  74. package/dist/development/src/validation/SchemaValidator.js.map +1 -1
  75. package/dist/development/src/validation/ValidationValidator.cjs.map +1 -1
  76. package/dist/development/src/validation/ValidationValidator.js.map +1 -1
  77. package/dist/development/src/validation/errors.cjs.map +1 -1
  78. package/dist/development/src/validation/errors.js.map +1 -1
  79. package/dist/production/index.cjs +2 -0
  80. package/dist/production/index.cjs.map +1 -1
  81. package/dist/production/index.js +2 -0
  82. package/dist/production/index.js.map +1 -1
  83. package/dist/production/src/acl/AllowAllPermissionFactory.cjs.map +1 -1
  84. package/dist/production/src/acl/AllowAllPermissionFactory.js.map +1 -1
  85. package/dist/production/src/acl/PredicateDefinitionProcessor.cjs.map +1 -1
  86. package/dist/production/src/acl/PredicateDefinitionProcessor.js.map +1 -1
  87. package/dist/production/src/acl/schemaUtils.cjs.map +1 -1
  88. package/dist/production/src/acl/schemaUtils.js.map +1 -1
  89. package/dist/production/src/dataUtils.cjs.map +1 -1
  90. package/dist/production/src/dataUtils.js.map +1 -1
  91. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.cjs +1 -2
  92. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.cjs.map +1 -1
  93. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.js +1 -2
  94. package/dist/production/src/definition-generator/AclDefinitionCodeGenerator.js.map +1 -1
  95. package/dist/production/src/definition-generator/DefinitionCodeGenerator.cjs +5 -9
  96. package/dist/production/src/definition-generator/DefinitionCodeGenerator.cjs.map +1 -1
  97. package/dist/production/src/definition-generator/DefinitionCodeGenerator.js +5 -9
  98. package/dist/production/src/definition-generator/DefinitionCodeGenerator.js.map +1 -1
  99. package/dist/production/src/definition-generator/DefinitionNamingConventions.cjs.map +1 -1
  100. package/dist/production/src/definition-generator/DefinitionNamingConventions.js.map +1 -1
  101. package/dist/production/src/definition-generator/TsDefinitionGenerator.cjs.map +1 -1
  102. package/dist/production/src/definition-generator/TsDefinitionGenerator.js.map +1 -1
  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/lax/schema.cjs.map +1 -1
  106. package/dist/production/src/lax/schema.js.map +1 -1
  107. package/dist/production/src/model/NamingConventions.cjs.map +1 -1
  108. package/dist/production/src/model/NamingConventions.js.map +1 -1
  109. package/dist/production/src/model/modelUtils.cjs.map +1 -1
  110. package/dist/production/src/model/modelUtils.js.map +1 -1
  111. package/dist/production/src/model/resolveDefaultColumnType.cjs.map +1 -1
  112. package/dist/production/src/model/resolveDefaultColumnType.js.map +1 -1
  113. package/dist/production/src/schemaChecksum.cjs +9 -0
  114. package/dist/production/src/schemaChecksum.cjs.map +1 -0
  115. package/dist/production/src/schemaChecksum.js +9 -0
  116. package/dist/production/src/schemaChecksum.js.map +1 -0
  117. package/dist/production/src/schemaFilter.cjs.map +1 -1
  118. package/dist/production/src/schemaFilter.js.map +1 -1
  119. package/dist/production/src/schemaNormalizer.cjs.map +1 -1
  120. package/dist/production/src/schemaNormalizer.js.map +1 -1
  121. package/dist/production/src/type-schema/acl.cjs.map +1 -1
  122. package/dist/production/src/type-schema/acl.js.map +1 -1
  123. package/dist/production/src/type-schema/actions.cjs.map +1 -1
  124. package/dist/production/src/type-schema/actions.js.map +1 -1
  125. package/dist/production/src/type-schema/condition.cjs.map +1 -1
  126. package/dist/production/src/type-schema/condition.js.map +1 -1
  127. package/dist/production/src/type-schema/model.cjs +6 -1
  128. package/dist/production/src/type-schema/model.cjs.map +1 -1
  129. package/dist/production/src/type-schema/model.js +7 -1
  130. package/dist/production/src/type-schema/model.js.map +1 -1
  131. package/dist/production/src/type-schema/settings.cjs +1 -0
  132. package/dist/production/src/type-schema/settings.cjs.map +1 -1
  133. package/dist/production/src/type-schema/settings.js +1 -0
  134. package/dist/production/src/type-schema/settings.js.map +1 -1
  135. package/dist/production/src/type-schema/validation.cjs.map +1 -1
  136. package/dist/production/src/type-schema/validation.js.map +1 -1
  137. package/dist/production/src/type-schema/where.cjs.map +1 -1
  138. package/dist/production/src/type-schema/where.js.map +1 -1
  139. package/dist/production/src/utils/deepCompare.cjs.map +1 -1
  140. package/dist/production/src/utils/deepCompare.js.map +1 -1
  141. package/dist/production/src/utils/printJsValue.cjs.map +1 -1
  142. package/dist/production/src/utils/printJsValue.js.map +1 -1
  143. package/dist/production/src/validation/AclValidator.cjs.map +1 -1
  144. package/dist/production/src/validation/AclValidator.js.map +1 -1
  145. package/dist/production/src/validation/ActionsValidator.cjs.map +1 -1
  146. package/dist/production/src/validation/ActionsValidator.js.map +1 -1
  147. package/dist/production/src/validation/MembershipResolver.cjs.map +1 -1
  148. package/dist/production/src/validation/MembershipResolver.js.map +1 -1
  149. package/dist/production/src/validation/ModelValidator.cjs.map +1 -1
  150. package/dist/production/src/validation/ModelValidator.js.map +1 -1
  151. package/dist/production/src/validation/SchemaValidator.cjs.map +1 -1
  152. package/dist/production/src/validation/SchemaValidator.js.map +1 -1
  153. package/dist/production/src/validation/ValidationValidator.cjs.map +1 -1
  154. package/dist/production/src/validation/ValidationValidator.js.map +1 -1
  155. package/dist/production/src/validation/errors.cjs.map +1 -1
  156. package/dist/production/src/validation/errors.js.map +1 -1
  157. package/dist/tests/cases/unit/modelSchema.test.d.ts +2 -0
  158. package/dist/tests/cases/unit/modelSchema.test.d.ts.map +1 -0
  159. package/dist/tests/cases/unit/schemas/acl.d.ts +7 -7
  160. package/dist/tests/cases/unit/schemas/acl.d.ts.map +1 -1
  161. package/dist/tests/cases/unit/schemas/basic.d.ts +1 -1
  162. package/dist/tests/cases/unit/schemas/basic.d.ts.map +1 -1
  163. package/dist/tests/cases/unit/schemas/complex.d.ts +12 -0
  164. package/dist/tests/cases/unit/schemas/complex.d.ts.map +1 -0
  165. package/dist/tests/cases/unit/schemas/enum.d.ts +3 -3
  166. package/dist/tests/cases/unit/schemas/enum.d.ts.map +1 -1
  167. package/dist/tests/cases/unit/schemas/relations.d.ts +7 -7
  168. package/dist/tests/cases/unit/schemas/relations.d.ts.map +1 -1
  169. package/dist/tests/cases/unit/schemas/unique.d.ts +1 -1
  170. package/dist/tests/cases/unit/schemas/unique.d.ts.map +1 -1
  171. package/dist/tests/cases/unit/schemas/view.d.ts +4 -0
  172. package/dist/tests/cases/unit/schemas/view.d.ts.map +1 -0
  173. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  174. package/dist/types/dataUtils.d.ts +1 -1
  175. package/dist/types/dataUtils.d.ts.map +1 -1
  176. package/dist/types/definition-generator/DefinitionCodeGenerator.d.ts.map +1 -1
  177. package/dist/types/index.d.ts +1 -0
  178. package/dist/types/index.d.ts.map +1 -1
  179. package/dist/types/schemaChecksum.d.ts +3 -0
  180. package/dist/types/schemaChecksum.d.ts.map +1 -0
  181. package/dist/types/tsconfig.tsbuildinfo +1 -1
  182. package/dist/types/type-schema/model.d.ts.map +1 -1
  183. package/dist/types/type-schema/settings.d.ts +20 -28
  184. package/dist/types/type-schema/settings.d.ts.map +1 -1
  185. package/package.json +6 -6
  186. package/src/dataUtils.ts +2 -2
  187. package/src/definition-generator/AclDefinitionCodeGenerator.ts +1 -1
  188. package/src/definition-generator/DefinitionCodeGenerator.ts +10 -18
  189. package/src/index.ts +1 -0
  190. package/src/schemaChecksum.ts +12 -0
  191. package/src/type-schema/model.ts +7 -1
  192. package/src/type-schema/settings.ts +1 -0
  193. package/tests/cases/unit/conditionSchema.test.ts +8 -8
  194. package/tests/cases/unit/deepCompare.test.ts +4 -4
  195. package/tests/cases/unit/laxSchemaConverter.test.ts +4 -4
  196. package/tests/cases/unit/membershipResolver.test.ts +17 -17
  197. package/tests/cases/unit/modelSchema.test.ts +88 -0
  198. package/tests/cases/unit/modelValidator.test.ts +3 -3
  199. package/tests/cases/unit/printJsvalue.test.ts +49 -61
  200. package/tests/cases/unit/schemas/acl.ts +7 -9
  201. package/tests/cases/unit/schemas/complex.ts +38 -0
  202. package/tests/cases/unit/schemas/view.ts +6 -0
  203. package/tests/cases/unit/tsDefinitionGenerator.test.ts +5 -1
  204. package/tests/cases/unit/whereSchema.test.ts +10 -10
@@ -0,0 +1,12 @@
1
+ import { Schema } from '@contember/schema'
2
+ import crypto from 'node:crypto'
3
+
4
+
5
+ export const calculateSchemaChecksum = (schema: Schema): string => {
6
+ const jsonSchema = JSON.stringify(schema)
7
+
8
+ return crypto
9
+ .createHash('md5')
10
+ .update(jsonSchema)
11
+ .digest('hex')
12
+ }
@@ -1,5 +1,6 @@
1
1
  import * as Typesafe from '@contember/typesafe'
2
2
  import { Model } from '@contember/schema'
3
+ import { ParseError } from '@contember/typesafe'
3
4
 
4
5
  const orderBySchema = Typesafe.array(Typesafe.object({
5
6
  path: Typesafe.array(Typesafe.string),
@@ -118,7 +119,12 @@ const columnSchema = Typesafe.intersection(
118
119
  Typesafe.object({
119
120
  name: Typesafe.string,
120
121
  columnName: Typesafe.string,
121
- columnType: Typesafe.string,
122
+ columnType: Typesafe.transform(Typesafe.string, (it, raw, path) => {
123
+ if (!it.replaceAll(/\s+/g, '').match(/^[\w_]+(?:\(\w+(?:,\w+)*\))?\w*(?:"[^"]+")?(\[])*$/)) {
124
+ throw ParseError.format(it, path, 'valid column type')
125
+ }
126
+ return it
127
+ }),
122
128
  nullable: Typesafe.boolean,
123
129
  type: Typesafe.enumeration<Model.ColumnType>(...Object.values(Model.ColumnType)),
124
130
  }),
@@ -9,6 +9,7 @@ export const settingsSchema = Typesafe.partial({
9
9
  }),
10
10
  content: Typesafe.partial({
11
11
  useExistsInHasManyFilter: Typesafe.boolean,
12
+ fullDateTimeResponse: Typesafe.boolean,
12
13
  shortDateResponse: Typesafe.boolean,
13
14
  }),
14
15
  })
@@ -1,4 +1,4 @@
1
- import { assert, test, describe } from 'vitest'
1
+ import { expect, test, describe } from 'bun:test'
2
2
  import { conditionSchema } from '../../../src/type-schema'
3
3
  import { Model } from '@contember/schema'
4
4
 
@@ -7,28 +7,28 @@ describe('condition schema', () => {
7
7
  const condition = {
8
8
  and: [{ isNull: true }, { not: { isNull: false } }],
9
9
  }
10
- assert.deepStrictEqual(conditionSchema()(condition), condition)
10
+ expect(conditionSchema()(condition)).toStrictEqual(condition)
11
11
  })
12
12
 
13
13
  test('accept string-only condition for unknown type', () => {
14
14
  const condition = {
15
15
  containsCI: 'foo',
16
16
  }
17
- assert.deepStrictEqual(conditionSchema()(condition), condition)
17
+ expect(conditionSchema()(condition)).toStrictEqual(condition)
18
18
  })
19
19
 
20
20
  test('accept string-only condition for string type', () => {
21
21
  const condition = {
22
22
  containsCI: 'foo',
23
23
  }
24
- assert.deepStrictEqual(conditionSchema(Model.ColumnType.String)(condition), condition)
24
+ expect(conditionSchema(Model.ColumnType.String)(condition)).toStrictEqual(condition)
25
25
  })
26
26
 
27
27
  test('reject string-only condition for int type', () => {
28
28
  const condition = {
29
29
  containsCI: 'foo',
30
30
  }
31
- assert.throw(() => conditionSchema(Model.ColumnType.Int)(condition), 'value at root: extra property containsCI found')
31
+ expect(() => conditionSchema(Model.ColumnType.Int)(condition)).toThrow('value at root: extra property containsCI found')
32
32
  })
33
33
 
34
34
 
@@ -36,20 +36,20 @@ describe('condition schema', () => {
36
36
  const condition = {
37
37
  eq: 'foo',
38
38
  }
39
- assert.deepStrictEqual(conditionSchema()(condition), condition)
39
+ expect(conditionSchema()(condition)).toStrictEqual(condition)
40
40
  })
41
41
 
42
42
  test('accept non-json condition for string type', () => {
43
43
  const condition = {
44
44
  eq: 'foo',
45
45
  }
46
- assert.deepStrictEqual(conditionSchema(Model.ColumnType.String)(condition), condition)
46
+ expect(conditionSchema(Model.ColumnType.String)(condition)).toStrictEqual(condition)
47
47
  })
48
48
 
49
49
  test('reject non-json condition for json type', () => {
50
50
  const condition = {
51
51
  eq: 'foo',
52
52
  }
53
- assert.throw(() => conditionSchema(Model.ColumnType.Json)(condition), 'value at root: extra property eq found')
53
+ expect(() => conditionSchema(Model.ColumnType.Json)(condition)).toThrow('value at root: extra property eq found')
54
54
  })
55
55
  })
@@ -1,4 +1,4 @@
1
- import { assert, describe, test } from 'vitest'
1
+ import { expect, describe, test } from 'bun:test'
2
2
  import { compareArraysIgnoreOrder } from '../../../src'
3
3
 
4
4
  describe('deep compare', () => {
@@ -10,7 +10,7 @@ describe('deep compare', () => {
10
10
  { lorem: 'ipsum' },
11
11
  { foo: 'bar' },
12
12
  ], [])
13
- assert.deepStrictEqual(actual, [])
13
+ expect(actual).toStrictEqual([])
14
14
  })
15
15
 
16
16
  test('compare array ignore order - missing in A', () => {
@@ -21,7 +21,7 @@ describe('deep compare', () => {
21
21
  { lorem: 'ipsum' },
22
22
  { foo: 'bar' },
23
23
  ], [])
24
- assert.deepStrictEqual(actual, [{
24
+ expect(actual).toStrictEqual([{
25
25
  path: [],
26
26
  message: 'Array item: {"lorem":"ipsum"} not found in [{"foo":"bar"}]',
27
27
  }])
@@ -35,7 +35,7 @@ describe('deep compare', () => {
35
35
  { lorem: 'ipsum' },
36
36
  { lorem: 'ipsum' },
37
37
  ], [])
38
- assert.deepStrictEqual(actual, [{
38
+ expect(actual).toStrictEqual([{
39
39
  path: [],
40
40
  message: 'Array item: {"foo":"bar"} not found in [{"lorem":"ipsum"},{"lorem":"ipsum"}]',
41
41
  }],
@@ -1,4 +1,4 @@
1
- import { expect, test } from 'vitest'
1
+ import { expect, test } from 'bun:test'
2
2
  import { LaxSchemaConverter } from '../../../src'
3
3
 
4
4
  test('lax schema converter basic', () => {
@@ -54,7 +54,7 @@ test('lax schema converter one-has-many', () => {
54
54
  },
55
55
  },
56
56
  )
57
- expect(converter2.convert()).deep.eq(schema1)
57
+ expect(converter2.convert()).toStrictEqual(schema1)
58
58
  })
59
59
 
60
60
 
@@ -93,7 +93,7 @@ test('lax schema converter many-has-many', () => {
93
93
  },
94
94
  },
95
95
  )
96
- expect(converter2.convert()).deep.eq(schema1)
96
+ expect(converter2.convert()).toStrictEqual(schema1)
97
97
  })
98
98
 
99
99
 
@@ -132,6 +132,6 @@ test('lax schema converter one-has-one', () => {
132
132
  },
133
133
  },
134
134
  )
135
- expect(converter2.convert()).deep.eq(schema1)
135
+ expect(converter2.convert()).toStrictEqual(schema1)
136
136
  })
137
137
 
@@ -1,4 +1,4 @@
1
- import { assert, test } from 'vitest'
1
+ import { expect, test } from 'bun:test'
2
2
  import { MembershipResolver, MembershipValidationErrorType } from '../../../src'
3
3
  import { Acl } from '@contember/schema'
4
4
 
@@ -17,8 +17,8 @@ test('read membership with entity variable', () => {
17
17
  }, [
18
18
  { role: 'editor', variables: [{ name: 'localeID', values: [id1] }] },
19
19
  ], MembershipResolver.UnknownIdentity)
20
- assert.lengthOf(result.errors, 0)
21
- assert.deepStrictEqual(result.memberships, [
20
+ expect(result.errors).toStrictEqual([])
21
+ expect(result.memberships).toStrictEqual([
22
22
  { role: 'editor', variables: [{ name: 'localeID', condition: { in: [id1] } }] },
23
23
  ])
24
24
  })
@@ -37,13 +37,13 @@ test('read fails when variable is not provided', () => {
37
37
  }, [
38
38
  { role: 'editor', variables: [] },
39
39
  ], MembershipResolver.UnknownIdentity)
40
- assert.deepStrictEqual(result.errors, [{
40
+ expect(result.errors).toEqual([{
41
41
  error: MembershipValidationErrorType.VARIABLE_EMPTY,
42
42
  role: 'editor',
43
43
  variable: 'localeID',
44
44
  }])
45
45
 
46
- assert.deepStrictEqual(result.memberships, [
46
+ expect(result.memberships).toStrictEqual([
47
47
  { role: 'editor', variables: [{ name: 'localeID', condition: { never: true } }] },
48
48
  ])
49
49
  })
@@ -64,8 +64,8 @@ test('read membership with predefined variable', () => {
64
64
  ], {
65
65
  identityId: id1,
66
66
  })
67
- assert.lengthOf(result.errors, 0)
68
- assert.deepStrictEqual(result.memberships, [
67
+ expect(result.errors).toStrictEqual([])
68
+ expect(result.memberships).toStrictEqual([
69
69
  { role: 'editor', variables: [{ name: 'self', condition: { in: [id1] } }] },
70
70
  ])
71
71
  })
@@ -84,8 +84,8 @@ test('read membership with condition variable', () => {
84
84
  }, [
85
85
  { role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify({ eq: 'foo' })] }] },
86
86
  ], MembershipResolver.UnknownIdentity)
87
- assert.lengthOf(result.errors, 0)
88
- assert.deepStrictEqual(result.memberships, [
87
+ expect(result.errors).toStrictEqual([])
88
+ expect(result.memberships).toStrictEqual([
89
89
  { role: 'editor', variables: [{ name: 'cond', condition: { eq: 'foo' } }] },
90
90
  ])
91
91
  })
@@ -105,13 +105,13 @@ test('fails on invalid condition', () => {
105
105
  { role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify('abcd')] }] },
106
106
  ], MembershipResolver.UnknownIdentity)
107
107
 
108
- assert.deepStrictEqual(result.errors, [{
108
+ expect(result.errors).toEqual([{
109
109
  error: MembershipValidationErrorType.VARIABLE_INVALID,
110
110
  role: 'editor',
111
111
  variable: 'cond',
112
112
  }])
113
113
 
114
- assert.deepStrictEqual(result.memberships, [
114
+ expect(result.memberships).toStrictEqual([
115
115
  { role: 'editor', variables: [{ name: 'cond', condition: { never: true } }] },
116
116
  ])
117
117
  })
@@ -127,13 +127,13 @@ test('fails on undefined role', () => {
127
127
  identityId: id1,
128
128
  })
129
129
 
130
- assert.deepStrictEqual(result.errors, [{
130
+ expect(result.errors).toEqual([{
131
131
  error: MembershipValidationErrorType.ROLE_NOT_FOUND,
132
132
  role: 'editor',
133
133
  variable: undefined,
134
134
  }])
135
135
 
136
- assert.deepStrictEqual(result.memberships, [])
136
+ expect(result.memberships).toStrictEqual([])
137
137
  })
138
138
 
139
139
  test('fails on undefined variable', () => {
@@ -149,13 +149,13 @@ test('fails on undefined variable', () => {
149
149
  { role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify('abcd')] }] },
150
150
  ], MembershipResolver.UnknownIdentity)
151
151
 
152
- assert.deepStrictEqual(result.errors, [{
152
+ expect(result.errors).toEqual([{
153
153
  error: MembershipValidationErrorType.VARIABLE_NOT_FOUND,
154
154
  role: 'editor',
155
155
  variable: 'cond',
156
156
  }])
157
157
 
158
- assert.deepStrictEqual(result.memberships, [
158
+ expect(result.memberships).toStrictEqual([
159
159
  { role: 'editor', variables: [] },
160
160
  ])
161
161
  })
@@ -175,9 +175,9 @@ test('use fallback value', () => {
175
175
  }, [
176
176
  { role: 'editor', variables: [] },
177
177
  ], MembershipResolver.UnknownIdentity)
178
- assert.deepStrictEqual(result.errors, [])
178
+ expect(result.errors).toStrictEqual([])
179
179
 
180
- assert.deepStrictEqual(result.memberships, [
180
+ expect(result.memberships).toStrictEqual([
181
181
  { role: 'editor', variables: [{ name: 'localeID', condition: { always: true } }] },
182
182
  ])
183
183
  })
@@ -0,0 +1,88 @@
1
+ import { expect, describe, test } from 'bun:test'
2
+ import { modelSchema } from '../../../src/type-schema'
3
+ import { Model } from '@contember/schema'
4
+
5
+ describe('model schema', () => {
6
+ const validDataTypes = [
7
+ 'integer',
8
+ 'double precision',
9
+ 'character varying(255)',
10
+ 'numeric(10, 2)',
11
+ 'timestamp(3) with time zone',
12
+ 'geometry(Point, 4326)',
13
+ 'character(10)[]',
14
+ 'bit varying(5)',
15
+ 'VARCHAR(255) COLLATE "de_DE"',
16
+ ]
17
+
18
+ // Array of invalid PostgreSQL data type examples
19
+ const invalidDataTypes = [
20
+ 'varchar(255', // Missing closing parenthesis
21
+ 'character(10))', // Extra closing parenthesis
22
+ 'numeric(,2)', // Missing first parameter
23
+ 'geometry(Point,4326))', // Extra closing parenthesis
24
+ 'VARCHAR(255) COLLATE "de_DE" (extra text)', // Extra text outside the valid pattern
25
+ 'VARCHAR(255) COLLATE "de_DE', // Missing closing quote
26
+ ]
27
+
28
+ for (const dataType of validDataTypes) {
29
+ test(`accept valid data type ${dataType}`, () => {
30
+ const column: Model.AnyColumn = {
31
+ type: Model.ColumnType.String,
32
+ columnName: 'column',
33
+ name: 'column',
34
+ columnType: dataType,
35
+ nullable: false,
36
+ }
37
+ const model: Model.Schema = {
38
+ entities: {
39
+ Test: {
40
+ tableName: 'test',
41
+ primary: 'id',
42
+ primaryColumn: 'id',
43
+ unique: [],
44
+ indexes: [],
45
+ eventLog: { enabled: false },
46
+ name: 'Test',
47
+ fields: {
48
+ column,
49
+ },
50
+ },
51
+ },
52
+ enums: {},
53
+ }
54
+ expect(modelSchema(model)).toStrictEqual(model)
55
+ })
56
+ }
57
+
58
+ for (const dataType of invalidDataTypes) {
59
+ test(`reject invalid data type ${dataType}`, () => {
60
+ const column: Model.AnyColumn = {
61
+ type: Model.ColumnType.String,
62
+ columnName: 'column',
63
+ name: 'column',
64
+ columnType: dataType,
65
+ nullable: false,
66
+ }
67
+ const model: Model.Schema = {
68
+ entities: {
69
+ Test: {
70
+ tableName: 'test',
71
+ primary: 'id',
72
+ primaryColumn: 'id',
73
+ unique: [],
74
+ indexes: [],
75
+ eventLog: { enabled: false },
76
+ name: 'Test',
77
+ fields: {
78
+ column,
79
+ },
80
+ },
81
+ },
82
+ enums: {},
83
+ }
84
+ expect(() => modelSchema(model)).toThrow(`value at path /entities/Test/fields/column: all variants of union has failed:
85
+ value at path /entities/Test/fields/column/columnType: must be valid column type, "${dataType.replaceAll('"', '\\"')}" given`)
86
+ })
87
+ }
88
+ })
@@ -1,4 +1,4 @@
1
- import { assert, test } from 'vitest'
1
+ import { expect, test } from 'bun:test'
2
2
  import { Model } from '@contember/schema'
3
3
  import { ModelValidator } from '../../../src'
4
4
  import { c, createSchema } from '@contember/schema-definition'
@@ -64,7 +64,7 @@ test('"meta" collision', () => {
64
64
  },
65
65
  }
66
66
  const validator = new ModelValidator(model)
67
- assert.deepStrictEqual(validator.validate(), [
67
+ expect(validator.validate()).toStrictEqual([
68
68
  {
69
69
  code: 'MODEL_NAME_COLLISION',
70
70
  message: 'entity FooMeta collides with entity Foo, because a GraphQL type with "Meta" suffix is created for every entity',
@@ -83,7 +83,7 @@ namespace ColumnNameCollision {
83
83
  test('column name collision', () => {
84
84
  const schema = createSchema(ColumnNameCollision)
85
85
  const validator = new ModelValidator(schema.model)
86
- assert.deepStrictEqual(validator.validate(), [
86
+ expect(validator.validate()).toStrictEqual([
87
87
  {
88
88
  code: 'MODEL_NAME_COLLISION',
89
89
  message: 'Column name "rel_id" on field "relId" collides with a column name on field "rel".',
@@ -1,100 +1,88 @@
1
- import { beforeAll, describe, expect, test } from 'vitest'
1
+ import { beforeAll, describe, expect, test } from 'bun:test'
2
2
  import { printJsValue } from '../../../src/utils/printJsValue'
3
3
 
4
- beforeAll(() => {
5
- expect.addSnapshotSerializer({
6
- test: val => typeof val === 'string',
7
- print: val => String(val),
8
- })
9
- })
10
-
11
4
  describe('printJsValue', () => {
12
5
  test('string', () => {
13
- expect(printJsValue('foobar')).toMatchInlineSnapshot(`'foobar'`)
6
+ expect(printJsValue('foobar')).toEqual(`'foobar'`)
14
7
  })
15
8
 
16
9
  test('string escape', () => {
17
- expect(printJsValue('foo\'bar')).toMatchInlineSnapshot(`'foo\\'bar'`)
10
+ expect(printJsValue('foo\'bar')).toEqual(`'foo\\'bar'`)
18
11
  })
19
12
 
20
13
  test('number', () => {
21
- expect(printJsValue(11)).toMatchInlineSnapshot(`11`)
14
+ expect(printJsValue(11)).toEqual(`11`)
22
15
  })
23
16
 
24
17
  test('boolean', () => {
25
- expect(printJsValue(true)).toMatchInlineSnapshot(`true`)
18
+ expect(printJsValue(true)).toEqual(`true`)
26
19
  })
27
20
 
28
21
  test('null', () => {
29
- expect(printJsValue(null)).toMatchInlineSnapshot(`null`)
22
+ expect(printJsValue(null)).toEqual(`null`)
30
23
  })
31
24
 
32
25
  test('inline array', () => {
33
- expect(printJsValue([1, 2, 3])).toMatchInlineSnapshot(`[1, 2, 3]`)
26
+ expect(printJsValue([1, 2, 3])).toEqual(`[1, 2, 3]`)
34
27
  })
35
28
  test('block array', () => {
36
- expect(printJsValue([1, 2, 3], () => true)).toMatchInlineSnapshot(`
37
- [
38
- 1,
39
- 2,
40
- 3,
41
- ]
42
- `)
29
+ expect(printJsValue([1, 2, 3], () => true)).toEqual(
30
+ `[
31
+ 1,
32
+ 2,
33
+ 3,
34
+ ]`)
43
35
  })
44
36
 
45
37
  test('inline object', () => {
46
- expect(printJsValue({ a: 1, b: 2 })).toMatchInlineSnapshot('{ a: 1, b: 2 }')
38
+ expect(printJsValue({ a: 1, b: 2 })).toEqual('{ a: 1, b: 2 }')
47
39
  })
48
40
 
49
41
  test('block object', () => {
50
- expect(printJsValue({ a: 1, b: 2 }, () => true)).toMatchInlineSnapshot(`
51
- {
52
- a: 1,
53
- b: 2,
54
- }
55
- `)
42
+ expect(printJsValue({ a: 1, b: 2 }, () => true)).toEqual(
43
+ `{
44
+ a: 1,
45
+ b: 2,
46
+ }`)
56
47
  })
57
48
 
58
49
  test('nested block object', () => {
59
- expect(printJsValue({ a: 1, b: { c: { d: { e: 1 } } } }, () => true)).toMatchInlineSnapshot(`
60
- {
61
- a: 1,
62
- b: {
63
- c: {
64
- d: {
65
- e: 1,
66
- },
67
- },
68
- },
69
- }
70
- `)
50
+ expect(printJsValue({ a: 1, b: { c: { d: { e: 1 } } } }, () => true)).toEqual(
51
+ `{
52
+ a: 1,
53
+ b: {
54
+ c: {
55
+ d: {
56
+ e: 1,
57
+ },
58
+ },
59
+ },
60
+ }`)
71
61
  })
72
62
 
73
63
 
74
64
  test('one level nested block object', () => {
75
- expect(printJsValue({ a: 1, b: { c: { d: { e: 1 } } } }, (_, path) => path.length === 0)).toMatchInlineSnapshot(`
76
- {
77
- a: 1,
78
- b: { c: { d: { e: 1 } } },
79
- }
80
- `)
65
+ expect(printJsValue({ a: 1, b: { c: { d: { e: 1 } } } }, (_, path) => path.length === 0)).toEqual(
66
+ `{
67
+ a: 1,
68
+ b: { c: { d: { e: 1 } } },
69
+ }`)
81
70
  })
82
71
 
83
72
  test('nested block object and arr', () => {
84
- expect(printJsValue({ a: 1, b: [2, { c: 4 }, [5, 6]] }, () => true)).toMatchInlineSnapshot(`
85
- {
86
- a: 1,
87
- b: [
88
- 2,
89
- {
90
- c: 4,
91
- },
92
- [
93
- 5,
94
- 6,
95
- ],
96
- ],
97
- }
98
- `)
73
+ expect(printJsValue({ a: 1, b: [2, { c: 4 }, [5, 6]] }, () => true)).toEqual(
74
+ `{
75
+ a: 1,
76
+ b: [
77
+ 2,
78
+ {
79
+ c: 4,
80
+ },
81
+ [
82
+ 5,
83
+ 6,
84
+ ],
85
+ ],
86
+ }`)
99
87
  })
100
88
  })
@@ -1,32 +1,30 @@
1
1
  import { c } from '@contember/schema-definition'
2
2
 
3
- export const readerRole = c.createRole('reader', { stages: '*' })
4
-
5
3
  export const editorRole = c.createRole('editor', { stages: '*' })
6
4
 
7
- export const categoryEditorVariable = c.createEntityVariable('category', 'Category', editorRole)
5
+ export const readerRole = c.createRole('reader', { stages: '*' })
8
6
 
7
+ export const categoryEditorVariable = c.createEntityVariable('category', 'Category', editorRole)
9
8
 
10
- @c.Allow(readerRole, {
11
- read: true,
12
- })
13
9
  @c.Allow(editorRole, {
14
10
  when: { category: { id: categoryEditorVariable } },
15
11
  read: true,
16
12
  create: ['title', 'category'],
17
13
  update: ['title', 'category'],
18
14
  })
15
+ @c.Allow(readerRole, {
16
+ read: true,
17
+ })
19
18
  export class Article {
20
19
  title = c.stringColumn()
21
20
  deletedAt = c.dateTimeColumn()
22
21
  category = c.manyHasOne(Category)
23
22
  }
24
23
 
25
-
26
- @c.Allow(readerRole, {
24
+ @c.Allow(editorRole, {
27
25
  read: true,
28
26
  })
29
- @c.Allow(editorRole, {
27
+ @c.Allow(readerRole, {
30
28
  read: true,
31
29
  })
32
30
  export class Category {
@@ -0,0 +1,38 @@
1
+ import { c } from '@contember/schema-definition'
2
+
3
+ export const editorRole = c.createRole('editor', { stages: '*' })
4
+
5
+ export const readerRole = c.createRole('reader', { stages: '*' })
6
+
7
+ export const categoryEditorVariable = c.createEntityVariable('category', 'Category', editorRole)
8
+
9
+ @c.Unique('title')
10
+ @c.View(`SELECT * FROM article`)
11
+ @c.Allow(editorRole, {
12
+ when: { category: { id: categoryEditorVariable } },
13
+ read: true,
14
+ create: ['title', 'category'],
15
+ update: ['title', 'category'],
16
+ })
17
+ @c.Allow(readerRole, {
18
+ read: true,
19
+ })
20
+ export class Article {
21
+ title = c.stringColumn()
22
+ deletedAt = c.dateTimeColumn()
23
+ category = c.manyHasOne(Category)
24
+ }
25
+
26
+ @c.View(`
27
+ SELECT * FROM article
28
+
29
+ `)
30
+ @c.Allow(editorRole, {
31
+ read: true,
32
+ })
33
+ @c.Allow(readerRole, {
34
+ read: true,
35
+ })
36
+ export class Category {
37
+ name = c.stringColumn()
38
+ }
@@ -0,0 +1,6 @@
1
+ import { c } from '@contember/schema-definition'
2
+
3
+ @c.View(`SELECT * FROM article`)
4
+ export class Article {
5
+ title = c.stringColumn()
6
+ }
@@ -1,10 +1,12 @@
1
1
  import { createSchema } from '@contember/schema-definition'
2
- import { expect, test } from 'vitest'
2
+ import { expect, test } from 'bun:test'
3
3
  import * as basic from './schemas/basic'
4
+ import * as complex from './schemas/complex'
4
5
  import * as relations from './schemas/relations'
5
6
  import * as unique from './schemas/unique'
6
7
  import * as enum_ from './schemas/enum'
7
8
  import * as acl from './schemas/acl'
9
+ import * as view from './schemas/view'
8
10
  import { readFile, writeFile } from 'fs/promises'
9
11
  import { join } from 'path'
10
12
  import { DefinitionCodeGenerator } from '../../../src/definition-generator/DefinitionCodeGenerator'
@@ -13,10 +15,12 @@ import { fileURLToPath } from 'node:url'
13
15
 
14
16
  const tests = [
15
17
  ['basic', basic],
18
+ ['complex', complex],
16
19
  ['relations', relations],
17
20
  ['unique', unique],
18
21
  ['enum', enum_],
19
22
  ['acl', acl],
23
+ ['view', view],
20
24
  ] as const
21
25
  for (const [name, def] of tests) {
22
26
  test(`generate schema: ${name}`, async () => {