@contember/schema-utils 1.2.1 → 1.3.0-alpha.13
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.
- package/dist/src/SchemaDatabaseMetadata.d.ts +40 -0
- package/dist/src/SchemaDatabaseMetadata.d.ts.map +1 -0
- package/dist/src/SchemaDatabaseMetadata.js +20 -0
- package/dist/src/SchemaDatabaseMetadata.js.map +1 -0
- package/dist/src/acl/PredicateDefinitionProcessor.d.ts.map +1 -1
- package/dist/src/acl/PredicateDefinitionProcessor.js +49 -44
- package/dist/src/acl/PredicateDefinitionProcessor.js.map +1 -1
- package/dist/src/definition-generator/AclDefinitionCodeGenerator.d.ts +19 -0
- package/dist/src/definition-generator/AclDefinitionCodeGenerator.d.ts.map +1 -0
- package/dist/src/definition-generator/AclDefinitionCodeGenerator.js +116 -0
- package/dist/src/definition-generator/AclDefinitionCodeGenerator.js.map +1 -0
- package/dist/src/definition-generator/DefinitionCodeGenerator.d.ts +27 -0
- package/dist/src/definition-generator/DefinitionCodeGenerator.d.ts.map +1 -0
- package/dist/src/definition-generator/DefinitionCodeGenerator.js +216 -0
- package/dist/src/definition-generator/DefinitionCodeGenerator.js.map +1 -0
- package/dist/src/definition-generator/DefinitionNamingConventions.d.ts +7 -0
- package/dist/src/definition-generator/DefinitionNamingConventions.d.ts.map +1 -0
- package/dist/src/definition-generator/DefinitionNamingConventions.js +18 -0
- package/dist/src/definition-generator/DefinitionNamingConventions.js.map +1 -0
- package/dist/src/definition-generator/TsDefinitionGenerator.d.ts +4 -18
- package/dist/src/definition-generator/TsDefinitionGenerator.d.ts.map +1 -1
- package/dist/src/definition-generator/TsDefinitionGenerator.js +6 -232
- package/dist/src/definition-generator/TsDefinitionGenerator.js.map +1 -1
- package/dist/src/definition-generator/index.d.ts +3 -0
- package/dist/src/definition-generator/index.d.ts.map +1 -1
- package/dist/src/definition-generator/index.js +3 -0
- package/dist/src/definition-generator/index.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lax/LaxSchemaConverter.d.ts.map +1 -1
- package/dist/src/lax/LaxSchemaConverter.js +4 -5
- package/dist/src/lax/LaxSchemaConverter.js.map +1 -1
- package/dist/src/model/index.d.ts +0 -1
- package/dist/src/model/index.d.ts.map +1 -1
- package/dist/src/model/index.js +0 -1
- package/dist/src/model/index.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/type-schema/actions.d.ts +31 -0
- package/dist/src/type-schema/actions.d.ts.map +1 -0
- package/dist/src/type-schema/actions.js +75 -0
- package/dist/src/type-schema/actions.js.map +1 -0
- package/dist/src/type-schema/model.d.ts +8 -6
- package/dist/src/type-schema/model.d.ts.map +1 -1
- package/dist/src/type-schema/model.js +6 -6
- package/dist/src/type-schema/model.js.map +1 -1
- package/dist/src/type-schema/where.d.ts +7 -0
- package/dist/src/type-schema/where.d.ts.map +1 -0
- package/dist/src/type-schema/where.js +50 -0
- package/dist/src/type-schema/where.js.map +1 -0
- package/dist/src/utils/deepCompare.d.ts +8 -2
- package/dist/src/utils/deepCompare.d.ts.map +1 -1
- package/dist/src/utils/deepCompare.js +32 -4
- package/dist/src/utils/deepCompare.js.map +1 -1
- package/dist/src/utils/printJsValue.d.ts +13 -0
- package/dist/src/utils/printJsValue.d.ts.map +1 -0
- package/dist/src/utils/printJsValue.js +57 -0
- package/dist/src/utils/printJsValue.js.map +1 -0
- package/dist/src/validation/ActionsValidator.d.ts +13 -0
- package/dist/src/validation/ActionsValidator.d.ts.map +1 -0
- package/dist/src/validation/ActionsValidator.js +134 -0
- package/dist/src/validation/ActionsValidator.js.map +1 -0
- package/dist/src/validation/ModelValidator.d.ts.map +1 -1
- package/dist/src/validation/ModelValidator.js +5 -31
- package/dist/src/validation/ModelValidator.js.map +1 -1
- package/dist/src/validation/SchemaValidator.d.ts.map +1 -1
- package/dist/src/validation/SchemaValidator.js +4 -1
- package/dist/src/validation/SchemaValidator.js.map +1 -1
- package/dist/src/validation/errors.d.ts +1 -1
- package/dist/src/validation/errors.d.ts.map +1 -1
- package/dist/src/validation/errors.js.map +1 -1
- package/dist/tests/cases/unit/deepCompare.test.d.ts +2 -0
- package/dist/tests/cases/unit/deepCompare.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/deepCompare.test.js +43 -0
- package/dist/tests/cases/unit/deepCompare.test.js.map +1 -0
- package/dist/tests/cases/unit/modelValidator.test.js +6 -72
- package/dist/tests/cases/unit/modelValidator.test.js.map +1 -1
- package/dist/tests/cases/unit/printJsvalue.test.d.ts +2 -0
- package/dist/tests/cases/unit/printJsvalue.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/printJsvalue.test.js +90 -0
- package/dist/tests/cases/unit/printJsvalue.test.js.map +1 -0
- package/dist/tests/cases/unit/schemas/acl.d.ts +13 -0
- package/dist/tests/cases/unit/schemas/acl.d.ts.map +1 -0
- package/dist/tests/cases/unit/schemas/acl.js +47 -0
- package/dist/tests/cases/unit/schemas/acl.js.map +1 -0
- package/dist/tests/cases/unit/schemas/basic.d.ts.map +1 -1
- package/dist/tests/cases/unit/schemas/basic.js.map +1 -1
- package/dist/tests/cases/unit/schemas/enum.d.ts.map +1 -1
- package/dist/tests/cases/unit/schemas/enum.js.map +1 -1
- package/dist/tests/cases/unit/schemas/relations.d.ts.map +1 -1
- package/dist/tests/cases/unit/schemas/relations.js.map +1 -1
- package/dist/tests/cases/unit/schemas/unique.d.ts.map +1 -1
- package/dist/tests/cases/unit/schemas/unique.js.map +1 -1
- package/dist/tests/cases/unit/tsDefinitionGenerator.test.js +5 -3
- package/dist/tests/cases/unit/tsDefinitionGenerator.test.js.map +1 -1
- package/dist/tests/cases/unit/whereSchema.test.d.ts +2 -0
- package/dist/tests/cases/unit/whereSchema.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/whereSchema.test.js +85 -0
- package/dist/tests/cases/unit/whereSchema.test.js.map +1 -0
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -4
- package/src/SchemaDatabaseMetadata.ts +66 -0
- package/src/acl/PredicateDefinitionProcessor.ts +59 -60
- package/src/definition-generator/AclDefinitionCodeGenerator.ts +126 -0
- package/src/definition-generator/DefinitionCodeGenerator.ts +250 -0
- package/src/definition-generator/DefinitionNamingConventions.ts +16 -0
- package/src/definition-generator/TsDefinitionGenerator.ts +8 -264
- package/src/definition-generator/index.ts +3 -0
- package/src/index.ts +5 -1
- package/src/lax/LaxSchemaConverter.ts +4 -5
- package/src/model/index.ts +0 -1
- package/src/tsconfig.json +2 -6
- package/src/type-schema/actions.ts +79 -0
- package/src/type-schema/model.ts +21 -8
- package/src/type-schema/where.ts +28 -0
- package/src/utils/deepCompare.ts +37 -4
- package/src/utils/printJsValue.ts +62 -0
- package/src/validation/ActionsValidator.ts +119 -0
- package/src/validation/ModelValidator.ts +12 -36
- package/src/validation/SchemaValidator.ts +6 -1
- package/src/validation/errors.ts +7 -0
- package/tests/cases/unit/__snapshots__/laxSchemaConverter.test.ts.snap +30 -14
- package/tests/cases/unit/deepCompare.test.ts +44 -0
- package/tests/cases/unit/modelValidator.test.ts +6 -73
- package/tests/cases/unit/printJsvalue.test.ts +100 -0
- package/tests/cases/unit/schemas/acl.ts +34 -0
- package/tests/cases/unit/schemas/basic.ts +1 -1
- package/tests/cases/unit/schemas/enum.ts +1 -1
- package/tests/cases/unit/schemas/relations.ts +1 -1
- package/tests/cases/unit/schemas/unique.ts +1 -1
- package/tests/cases/unit/tsDefinitionGenerator.test.ts +6 -4
- package/tests/cases/unit/whereSchema.test.ts +89 -0
- package/tests/tsconfig.json +1 -3
- package/tsconfig.json +2 -6
- package/dist/src/model/NamingHelper.d.ts +0 -9
- package/dist/src/model/NamingHelper.d.ts.map +0 -1
- package/dist/src/model/NamingHelper.js +0 -46
- package/dist/src/model/NamingHelper.js.map +0 -1
- package/src/model/NamingHelper.ts +0 -42
|
@@ -5,6 +5,10 @@ exports[`lax schema converter basic 1`] = `
|
|
|
5
5
|
"acl": {
|
|
6
6
|
"roles": {},
|
|
7
7
|
},
|
|
8
|
+
"actions": {
|
|
9
|
+
"targets": {},
|
|
10
|
+
"triggers": {},
|
|
11
|
+
},
|
|
8
12
|
"model": {
|
|
9
13
|
"entities": {
|
|
10
14
|
"Article": {
|
|
@@ -41,12 +45,12 @@ exports[`lax schema converter basic 1`] = `
|
|
|
41
45
|
"type": "String",
|
|
42
46
|
},
|
|
43
47
|
},
|
|
44
|
-
"indexes":
|
|
48
|
+
"indexes": [],
|
|
45
49
|
"name": "Article",
|
|
46
50
|
"primary": "id",
|
|
47
51
|
"primaryColumn": "id",
|
|
48
52
|
"tableName": "article",
|
|
49
|
-
"unique":
|
|
53
|
+
"unique": [],
|
|
50
54
|
},
|
|
51
55
|
},
|
|
52
56
|
"enums": {
|
|
@@ -67,6 +71,10 @@ exports[`lax schema converter many-has-many 1`] = `
|
|
|
67
71
|
"acl": {
|
|
68
72
|
"roles": {},
|
|
69
73
|
},
|
|
74
|
+
"actions": {
|
|
75
|
+
"targets": {},
|
|
76
|
+
"triggers": {},
|
|
77
|
+
},
|
|
70
78
|
"model": {
|
|
71
79
|
"entities": {
|
|
72
80
|
"Article": {
|
|
@@ -109,12 +117,12 @@ exports[`lax schema converter many-has-many 1`] = `
|
|
|
109
117
|
"type": "String",
|
|
110
118
|
},
|
|
111
119
|
},
|
|
112
|
-
"indexes":
|
|
120
|
+
"indexes": [],
|
|
113
121
|
"name": "Article",
|
|
114
122
|
"primary": "id",
|
|
115
123
|
"primaryColumn": "id",
|
|
116
124
|
"tableName": "article",
|
|
117
|
-
"unique":
|
|
125
|
+
"unique": [],
|
|
118
126
|
},
|
|
119
127
|
"Tag": {
|
|
120
128
|
"eventLog": {
|
|
@@ -135,12 +143,12 @@ exports[`lax schema converter many-has-many 1`] = `
|
|
|
135
143
|
"type": "Uuid",
|
|
136
144
|
},
|
|
137
145
|
},
|
|
138
|
-
"indexes":
|
|
146
|
+
"indexes": [],
|
|
139
147
|
"name": "Tag",
|
|
140
148
|
"primary": "id",
|
|
141
149
|
"primaryColumn": "id",
|
|
142
150
|
"tableName": "tag",
|
|
143
|
-
"unique":
|
|
151
|
+
"unique": [],
|
|
144
152
|
},
|
|
145
153
|
},
|
|
146
154
|
"enums": {},
|
|
@@ -155,6 +163,10 @@ exports[`lax schema converter one-has-many 1`] = `
|
|
|
155
163
|
"acl": {
|
|
156
164
|
"roles": {},
|
|
157
165
|
},
|
|
166
|
+
"actions": {
|
|
167
|
+
"targets": {},
|
|
168
|
+
"triggers": {},
|
|
169
|
+
},
|
|
158
170
|
"model": {
|
|
159
171
|
"entities": {
|
|
160
172
|
"Article": {
|
|
@@ -188,12 +200,12 @@ exports[`lax schema converter one-has-many 1`] = `
|
|
|
188
200
|
"type": "String",
|
|
189
201
|
},
|
|
190
202
|
},
|
|
191
|
-
"indexes":
|
|
203
|
+
"indexes": [],
|
|
192
204
|
"name": "Article",
|
|
193
205
|
"primary": "id",
|
|
194
206
|
"primaryColumn": "id",
|
|
195
207
|
"tableName": "article",
|
|
196
|
-
"unique":
|
|
208
|
+
"unique": [],
|
|
197
209
|
},
|
|
198
210
|
"Category": {
|
|
199
211
|
"eventLog": {
|
|
@@ -214,12 +226,12 @@ exports[`lax schema converter one-has-many 1`] = `
|
|
|
214
226
|
"type": "Uuid",
|
|
215
227
|
},
|
|
216
228
|
},
|
|
217
|
-
"indexes":
|
|
229
|
+
"indexes": [],
|
|
218
230
|
"name": "Category",
|
|
219
231
|
"primary": "id",
|
|
220
232
|
"primaryColumn": "id",
|
|
221
233
|
"tableName": "category",
|
|
222
|
-
"unique":
|
|
234
|
+
"unique": [],
|
|
223
235
|
},
|
|
224
236
|
},
|
|
225
237
|
"enums": {},
|
|
@@ -234,6 +246,10 @@ exports[`lax schema converter one-has-one 1`] = `
|
|
|
234
246
|
"acl": {
|
|
235
247
|
"roles": {},
|
|
236
248
|
},
|
|
249
|
+
"actions": {
|
|
250
|
+
"targets": {},
|
|
251
|
+
"triggers": {},
|
|
252
|
+
},
|
|
237
253
|
"model": {
|
|
238
254
|
"entities": {
|
|
239
255
|
"Article": {
|
|
@@ -267,12 +283,12 @@ exports[`lax schema converter one-has-one 1`] = `
|
|
|
267
283
|
"type": "String",
|
|
268
284
|
},
|
|
269
285
|
},
|
|
270
|
-
"indexes":
|
|
286
|
+
"indexes": [],
|
|
271
287
|
"name": "Article",
|
|
272
288
|
"primary": "id",
|
|
273
289
|
"primaryColumn": "id",
|
|
274
290
|
"tableName": "article",
|
|
275
|
-
"unique":
|
|
291
|
+
"unique": [],
|
|
276
292
|
},
|
|
277
293
|
"Content": {
|
|
278
294
|
"eventLog": {
|
|
@@ -294,12 +310,12 @@ exports[`lax schema converter one-has-one 1`] = `
|
|
|
294
310
|
"type": "Uuid",
|
|
295
311
|
},
|
|
296
312
|
},
|
|
297
|
-
"indexes":
|
|
313
|
+
"indexes": [],
|
|
298
314
|
"name": "Content",
|
|
299
315
|
"primary": "id",
|
|
300
316
|
"primaryColumn": "id",
|
|
301
317
|
"tableName": "content",
|
|
302
|
-
"unique":
|
|
318
|
+
"unique": [],
|
|
303
319
|
},
|
|
304
320
|
},
|
|
305
321
|
"enums": {},
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { assert, describe, test } from 'vitest'
|
|
2
|
+
import { compareArraysIgnoreOrder } from '../../../src'
|
|
3
|
+
|
|
4
|
+
describe('deep compare', () => {
|
|
5
|
+
test('compare array ignore order - success', () => {
|
|
6
|
+
const actual = compareArraysIgnoreOrder([
|
|
7
|
+
{ foo: 'bar' },
|
|
8
|
+
{ lorem: 'ipsum' },
|
|
9
|
+
], [
|
|
10
|
+
{ lorem: 'ipsum' },
|
|
11
|
+
{ foo: 'bar' },
|
|
12
|
+
], [])
|
|
13
|
+
assert.deepStrictEqual(actual, [])
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('compare array ignore order - missing in A', () => {
|
|
17
|
+
const actual = compareArraysIgnoreOrder([
|
|
18
|
+
{ lorem: 'ipsum' },
|
|
19
|
+
{ lorem: 'ipsum' },
|
|
20
|
+
], [
|
|
21
|
+
{ lorem: 'ipsum' },
|
|
22
|
+
{ foo: 'bar' },
|
|
23
|
+
], [])
|
|
24
|
+
assert.deepStrictEqual(actual, [{
|
|
25
|
+
path: [],
|
|
26
|
+
message: 'Array item: {"lorem":"ipsum"} not found in [{"foo":"bar"}]',
|
|
27
|
+
}])
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('compare array ignore order - missing in B', () => {
|
|
31
|
+
const actual = compareArraysIgnoreOrder([
|
|
32
|
+
{ foo: 'bar' },
|
|
33
|
+
{ lorem: 'ipsum' },
|
|
34
|
+
], [
|
|
35
|
+
{ lorem: 'ipsum' },
|
|
36
|
+
{ lorem: 'ipsum' },
|
|
37
|
+
], [])
|
|
38
|
+
assert.deepStrictEqual(actual, [{
|
|
39
|
+
path: [],
|
|
40
|
+
message: 'Array item: {"foo":"bar"} not found in [{"lorem":"ipsum"},{"lorem":"ipsum"}]',
|
|
41
|
+
}],
|
|
42
|
+
)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -4,73 +4,6 @@ import { ModelValidator } from '../../../src'
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
test('index name collision', () => {
|
|
8
|
-
const model: Model.Schema = {
|
|
9
|
-
enums: {},
|
|
10
|
-
entities: {
|
|
11
|
-
Foo: {
|
|
12
|
-
fields: {
|
|
13
|
-
id: {
|
|
14
|
-
columnName: 'id',
|
|
15
|
-
name: 'id',
|
|
16
|
-
nullable: false,
|
|
17
|
-
type: Model.ColumnType.Uuid,
|
|
18
|
-
columnType: 'uuid',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
name: 'Foo',
|
|
22
|
-
primary: 'id',
|
|
23
|
-
primaryColumn: 'id',
|
|
24
|
-
tableName: 'foo',
|
|
25
|
-
unique: {},
|
|
26
|
-
eventLog: {
|
|
27
|
-
enabled: true,
|
|
28
|
-
},
|
|
29
|
-
indexes: {
|
|
30
|
-
test: { fields: ['id'], name: 'test' },
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
Bar: {
|
|
34
|
-
fields: {
|
|
35
|
-
id: {
|
|
36
|
-
columnName: 'id',
|
|
37
|
-
name: 'id',
|
|
38
|
-
nullable: false,
|
|
39
|
-
type: Model.ColumnType.Uuid,
|
|
40
|
-
columnType: 'uuid',
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
name: 'Bar',
|
|
44
|
-
primary: 'id',
|
|
45
|
-
primaryColumn: 'id',
|
|
46
|
-
tableName: 'bar',
|
|
47
|
-
unique: {
|
|
48
|
-
test: { fields: ['id'], name: 'test' },
|
|
49
|
-
},
|
|
50
|
-
eventLog: {
|
|
51
|
-
enabled: true,
|
|
52
|
-
},
|
|
53
|
-
indexes: {
|
|
54
|
-
foo: { fields: ['id'], name: 'foo' },
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
}
|
|
59
|
-
const validator = new ModelValidator(model)
|
|
60
|
-
assert.deepStrictEqual(validator.validate(), [
|
|
61
|
-
{
|
|
62
|
-
code: 'MODEL_NAME_COLLISION',
|
|
63
|
-
message: 'index name foo of entity Bar collides with table name foo of entity Foo',
|
|
64
|
-
path: ['entities', 'Bar'],
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
code: 'MODEL_NAME_COLLISION',
|
|
68
|
-
message: 'unique index name test of entity Bar collides with index name test of entity Foo',
|
|
69
|
-
path: ['entities', 'Bar'],
|
|
70
|
-
},
|
|
71
|
-
])
|
|
72
|
-
})
|
|
73
|
-
|
|
74
7
|
|
|
75
8
|
test('"meta" collision', () => {
|
|
76
9
|
const model: Model.Schema = {
|
|
@@ -90,9 +23,9 @@ test('"meta" collision', () => {
|
|
|
90
23
|
primary: 'id',
|
|
91
24
|
primaryColumn: 'id',
|
|
92
25
|
tableName: 'foo',
|
|
93
|
-
unique:
|
|
26
|
+
unique: [],
|
|
94
27
|
eventLog: { enabled: true },
|
|
95
|
-
indexes:
|
|
28
|
+
indexes: [],
|
|
96
29
|
},
|
|
97
30
|
FooMeta: {
|
|
98
31
|
fields: {
|
|
@@ -108,9 +41,9 @@ test('"meta" collision', () => {
|
|
|
108
41
|
primary: 'id',
|
|
109
42
|
primaryColumn: 'id',
|
|
110
43
|
tableName: 'foo_meta',
|
|
111
|
-
unique:
|
|
44
|
+
unique: [],
|
|
112
45
|
eventLog: { enabled: true },
|
|
113
|
-
indexes:
|
|
46
|
+
indexes: [],
|
|
114
47
|
},
|
|
115
48
|
BarMeta: {
|
|
116
49
|
fields: {
|
|
@@ -126,9 +59,9 @@ test('"meta" collision', () => {
|
|
|
126
59
|
primary: 'id',
|
|
127
60
|
primaryColumn: 'id',
|
|
128
61
|
tableName: 'bar',
|
|
129
|
-
unique:
|
|
62
|
+
unique: [],
|
|
130
63
|
eventLog: { enabled: true },
|
|
131
|
-
indexes:
|
|
64
|
+
indexes: [],
|
|
132
65
|
},
|
|
133
66
|
},
|
|
134
67
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { beforeAll, describe, expect, test } from 'vitest'
|
|
2
|
+
import { printJsValue } from '../../../src/utils/printJsValue'
|
|
3
|
+
|
|
4
|
+
beforeAll(() => {
|
|
5
|
+
expect.addSnapshotSerializer({
|
|
6
|
+
test: val => typeof val === 'string',
|
|
7
|
+
print: val => String(val),
|
|
8
|
+
})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
describe('printJsValue', () => {
|
|
12
|
+
test('string', () => {
|
|
13
|
+
expect(printJsValue('foobar')).toMatchInlineSnapshot(`'foobar'`)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('string escape', () => {
|
|
17
|
+
expect(printJsValue('foo\'bar')).toMatchInlineSnapshot(`'foo\\'bar'`)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('number', () => {
|
|
21
|
+
expect(printJsValue(11)).toMatchInlineSnapshot(`11`)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('boolean', () => {
|
|
25
|
+
expect(printJsValue(true)).toMatchInlineSnapshot(`true`)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('null', () => {
|
|
29
|
+
expect(printJsValue(null)).toMatchInlineSnapshot(`null`)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('inline array', () => {
|
|
33
|
+
expect(printJsValue([1, 2, 3])).toMatchInlineSnapshot(`[1, 2, 3]`)
|
|
34
|
+
})
|
|
35
|
+
test('block array', () => {
|
|
36
|
+
expect(printJsValue([1, 2, 3], () => true)).toMatchInlineSnapshot(`
|
|
37
|
+
[
|
|
38
|
+
1,
|
|
39
|
+
2,
|
|
40
|
+
3,
|
|
41
|
+
]
|
|
42
|
+
`)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('inline object', () => {
|
|
46
|
+
expect(printJsValue({ a: 1, b: 2 })).toMatchInlineSnapshot('{ a: 1, b: 2 }')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('block object', () => {
|
|
50
|
+
expect(printJsValue({ a: 1, b: 2 }, () => true)).toMatchInlineSnapshot(`
|
|
51
|
+
{
|
|
52
|
+
a: 1,
|
|
53
|
+
b: 2,
|
|
54
|
+
}
|
|
55
|
+
`)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
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
|
+
`)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
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
|
+
`)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
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
|
+
`)
|
|
99
|
+
})
|
|
100
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SchemaDefinition as def, AclDefinition as acl } from '@contember/schema-definition'
|
|
2
|
+
|
|
3
|
+
export const readerRole = acl.createRole('reader', { stages: '*' })
|
|
4
|
+
|
|
5
|
+
export const editorRole = acl.createRole('editor', { stages: '*' })
|
|
6
|
+
|
|
7
|
+
export const categoryEditorVariable = acl.createEntityVariable('category', 'Category', editorRole)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@acl.allow(readerRole, {
|
|
11
|
+
read: true,
|
|
12
|
+
})
|
|
13
|
+
@acl.allow(editorRole, {
|
|
14
|
+
when: { category: { id: categoryEditorVariable } },
|
|
15
|
+
read: true,
|
|
16
|
+
create: ['title', 'category'],
|
|
17
|
+
update: ['title', 'category'],
|
|
18
|
+
})
|
|
19
|
+
export class Article {
|
|
20
|
+
title = def.stringColumn()
|
|
21
|
+
deletedAt = def.dateTimeColumn()
|
|
22
|
+
category = def.manyHasOne(Category)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@acl.allow(readerRole, {
|
|
27
|
+
read: true,
|
|
28
|
+
})
|
|
29
|
+
@acl.allow(editorRole, {
|
|
30
|
+
read: true,
|
|
31
|
+
})
|
|
32
|
+
export class Category {
|
|
33
|
+
name = def.stringColumn()
|
|
34
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createSchema } from '@contember/schema-definition'
|
|
2
|
-
import {
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
3
|
import * as basic from './schemas/basic'
|
|
4
4
|
import * as relations from './schemas/relations'
|
|
5
5
|
import * as unique from './schemas/unique'
|
|
6
6
|
import * as enum_ from './schemas/enum'
|
|
7
|
+
import * as acl from './schemas/acl'
|
|
7
8
|
import { readFile, writeFile } from 'fs/promises'
|
|
8
9
|
import { join } from 'path'
|
|
9
|
-
import {
|
|
10
|
+
import { DefinitionCodeGenerator } from '../../../src/definition-generator/DefinitionCodeGenerator'
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
const tests = [
|
|
@@ -14,13 +15,14 @@ const tests = [
|
|
|
14
15
|
['relations', relations],
|
|
15
16
|
['unique', unique],
|
|
16
17
|
['enum', enum_],
|
|
18
|
+
['acl', acl],
|
|
17
19
|
] as const
|
|
18
20
|
for (const [name, def] of tests) {
|
|
19
21
|
test(`generate schema: ${name}`, async () => {
|
|
20
22
|
const schema = createSchema(def)
|
|
21
|
-
const generator = new
|
|
23
|
+
const generator = new DefinitionCodeGenerator()
|
|
22
24
|
const content = await readFile(join(__dirname, `schemas/${name}.ts`), 'utf-8')
|
|
23
|
-
const generated = generator.generate()
|
|
25
|
+
const generated = generator.generate(schema)
|
|
24
26
|
try {
|
|
25
27
|
expect(generated).toBe(content)
|
|
26
28
|
} catch (e) {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { assert, test, describe } from 'vitest'
|
|
2
|
+
import { conditionSchema } from '../../../src/type-schema'
|
|
3
|
+
import { Model } from '@contember/schema'
|
|
4
|
+
import { createSchema, SchemaDefinition as def } from '@contember/schema-definition'
|
|
5
|
+
import { whereSchema } from '../../../src/type-schema/where'
|
|
6
|
+
|
|
7
|
+
namespace MyModel {
|
|
8
|
+
export class Article {
|
|
9
|
+
title = def.stringColumn()
|
|
10
|
+
category = def.manyHasOne(Category)
|
|
11
|
+
tags = def.manyHasMany(Tag)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class Category {
|
|
15
|
+
name = def.stringColumn()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Tag {
|
|
19
|
+
name = def.stringColumn()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const schema = createSchema(MyModel).model
|
|
24
|
+
|
|
25
|
+
describe('where schema', () => {
|
|
26
|
+
test('simple scalar where', () => {
|
|
27
|
+
const where = {
|
|
28
|
+
title: { eq: 'foo' },
|
|
29
|
+
}
|
|
30
|
+
assert.deepStrictEqual(whereSchema({ schema, entity: schema.entities.Article })(where), where)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('where with and / or /not', () => {
|
|
34
|
+
const where = {
|
|
35
|
+
and: [
|
|
36
|
+
{
|
|
37
|
+
or: [
|
|
38
|
+
{ not: { title: { eq: 'bar' } } },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
}
|
|
43
|
+
assert.deepStrictEqual(whereSchema({ schema, entity: schema.entities.Article })(where), where)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
test('where with relation', () => {
|
|
48
|
+
const where = {
|
|
49
|
+
tags: { name: { eq: 'xx' } },
|
|
50
|
+
}
|
|
51
|
+
assert.deepStrictEqual(whereSchema({ schema, entity: schema.entities.Article })(where), where)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('undefined field', () => {
|
|
55
|
+
const where = {
|
|
56
|
+
name: { eq: 'foo' },
|
|
57
|
+
}
|
|
58
|
+
assert.throw(() => whereSchema({
|
|
59
|
+
schema,
|
|
60
|
+
entity: schema.entities.Article,
|
|
61
|
+
})(where), 'value at root: extra property name found')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
test('undefined field in relation', () => {
|
|
66
|
+
const where = {
|
|
67
|
+
tags: {
|
|
68
|
+
caption: { eq: 'foo' },
|
|
69
|
+
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
assert.throw(() => whereSchema({
|
|
73
|
+
schema,
|
|
74
|
+
entity: schema.entities.Article,
|
|
75
|
+
})(where), 'value at path /tags: extra property caption found')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
test('invalid condition', () => {
|
|
80
|
+
const where = {
|
|
81
|
+
title: { xx: 'foo' },
|
|
82
|
+
}
|
|
83
|
+
assert.throw(() => whereSchema({
|
|
84
|
+
schema,
|
|
85
|
+
entity: schema.entities.Article,
|
|
86
|
+
})(where), 'value at path /title: extra property xx found')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
})
|
package/tests/tsconfig.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare class NamingHelper {
|
|
2
|
-
static createForeignKeyIndexName(tableName: string, column: string): string;
|
|
3
|
-
static createJunctionTablePrimaryConstraintName(tableName: string): string;
|
|
4
|
-
static createForeignKeyName(fromTable: string, fromColumn: string, toTable: string, toColumn: string): string;
|
|
5
|
-
static createIndexName: (entityName: string, fields: readonly string[]) => string;
|
|
6
|
-
static createUniqueConstraintName: (entityName: string, fields: readonly string[]) => string;
|
|
7
|
-
private static createUniqueSuffix;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=NamingHelper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NamingHelper.d.ts","sourceRoot":"","sources":["../../../src/model/NamingHelper.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;WACV,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;WAK3D,wCAAwC,CAAC,SAAS,EAAE,MAAM;WAK1D,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAOpH,OAAc,eAAe,eAAgB,MAAM,UAAU,SAAS,MAAM,EAAE,KAAG,MAAM,CAKtF;IAED,OAAc,0BAA0B,eAAgB,MAAM,UAAU,SAAS,MAAM,EAAE,KAAG,MAAM,CAKjG;IAED,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAMhC;CACD"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
var _a;
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.NamingHelper = void 0;
|
|
8
|
-
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
-
class NamingHelper {
|
|
10
|
-
static createForeignKeyIndexName(tableName, column) {
|
|
11
|
-
// format matches https://github.com/salsita/node-pg-migrate/blob/9331f6fda98795e3f3733461f9b71345168b99d8/src/operations/indexes.ts#L21
|
|
12
|
-
return `${tableName}_${column}_index`;
|
|
13
|
-
}
|
|
14
|
-
static createJunctionTablePrimaryConstraintName(tableName) {
|
|
15
|
-
// format matches https://github.com/salsita/node-pg-migrate/blob/9331f6fda98795e3f3733461f9b71345168b99d8/src/operations/tables.ts#L204
|
|
16
|
-
return `${tableName}_pkey`;
|
|
17
|
-
}
|
|
18
|
-
static createForeignKeyName(fromTable, fromColumn, toTable, toColumn) {
|
|
19
|
-
return 'fk_'
|
|
20
|
-
+ fromTable + '_'
|
|
21
|
-
+ fromColumn + '_'
|
|
22
|
-
+ this.createUniqueSuffix([fromTable, fromColumn, toTable, toColumn]);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
exports.NamingHelper = NamingHelper;
|
|
26
|
-
_a = NamingHelper;
|
|
27
|
-
NamingHelper.createIndexName = (entityName, fields) => {
|
|
28
|
-
return 'idx_'
|
|
29
|
-
+ entityName + '_'
|
|
30
|
-
+ fields.join('_') + '_'
|
|
31
|
-
+ _a.createUniqueSuffix([entityName, ...fields]);
|
|
32
|
-
};
|
|
33
|
-
NamingHelper.createUniqueConstraintName = (entityName, fields) => {
|
|
34
|
-
return 'unique_'
|
|
35
|
-
+ entityName + '_'
|
|
36
|
-
+ fields.join('_') + '_'
|
|
37
|
-
+ _a.createUniqueSuffix([entityName, ...fields]);
|
|
38
|
-
};
|
|
39
|
-
NamingHelper.createUniqueSuffix = (values) => {
|
|
40
|
-
const uniqueSuffix = node_crypto_1.default
|
|
41
|
-
.createHash('sha256')
|
|
42
|
-
.update(JSON.stringify(values), 'ascii')
|
|
43
|
-
.digest('hex');
|
|
44
|
-
return uniqueSuffix.slice(0, 6);
|
|
45
|
-
};
|
|
46
|
-
//# sourceMappingURL=NamingHelper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NamingHelper.js","sourceRoot":"","sources":["../../../src/model/NamingHelper.ts"],"names":[],"mappings":";;;;;;;AAAA,8DAAgC;AAEhC,MAAa,YAAY;IACjB,MAAM,CAAC,yBAAyB,CAAC,SAAiB,EAAE,MAAc;QACxE,wIAAwI;QACxI,OAAO,GAAG,SAAS,IAAI,MAAM,QAAQ,CAAA;IACtC,CAAC;IAEM,MAAM,CAAC,wCAAwC,CAAC,SAAiB;QACvE,wIAAwI;QACxI,OAAO,GAAG,SAAS,OAAO,CAAA;IAC3B,CAAC;IAEM,MAAM,CAAC,oBAAoB,CAAC,SAAiB,EAAE,UAAkB,EAAE,OAAe,EAAE,QAAgB;QAC1G,OAAO,KAAK;cACT,SAAS,GAAG,GAAG;cACf,UAAU,GAAG,GAAG;cAChB,IAAI,CAAC,kBAAkB,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;IACvE,CAAC;;AAhBF,oCAuCC;;AArBc,4BAAe,GAAG,CAAC,UAAkB,EAAE,MAAyB,EAAU,EAAE;IACzF,OAAO,MAAM;UACV,UAAU,GAAG,GAAG;UAChB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;UACtB,EAAI,CAAC,kBAAkB,CAAC,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,CAAC,CAAA;AACpD,CAAC,CAAA;AAEa,uCAA0B,GAAG,CAAC,UAAkB,EAAE,MAAyB,EAAU,EAAE;IACpG,OAAO,SAAS;UACb,UAAU,GAAG,GAAG;UAChB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;UACtB,EAAI,CAAC,kBAAkB,CAAC,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,CAAC,CAAA;AACpD,CAAC,CAAA;AAEc,+BAAkB,GAAG,CAAC,MAAgB,EAAU,EAAE;IAChE,MAAM,YAAY,GAAG,qBAAM;SACzB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;SACvC,MAAM,CAAC,KAAK,CAAC,CAAA;IACf,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAChC,CAAC,CAAA"}
|