@api-client/core 0.18.58 → 0.18.60
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/build/src/decorators/observed.d.ts.map +1 -1
- package/build/src/decorators/observed.js +15 -1
- package/build/src/decorators/observed.js.map +1 -1
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +2 -2
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
- package/build/src/modeling/ExposedEntity.js +4 -4
- package/build/src/modeling/ExposedEntity.js.map +1 -1
- package/build/src/modeling/actions/Action.d.ts.map +1 -1
- package/build/src/modeling/actions/Action.js +2 -2
- package/build/src/modeling/actions/Action.js.map +1 -1
- package/build/src/modeling/actions/CreateAction.d.ts +2 -0
- package/build/src/modeling/actions/CreateAction.d.ts.map +1 -1
- package/build/src/modeling/actions/CreateAction.js +6 -0
- package/build/src/modeling/actions/CreateAction.js.map +1 -1
- package/build/src/modeling/actions/DeleteAction.d.ts +2 -0
- package/build/src/modeling/actions/DeleteAction.d.ts.map +1 -1
- package/build/src/modeling/actions/DeleteAction.js +6 -0
- package/build/src/modeling/actions/DeleteAction.js.map +1 -1
- package/build/src/modeling/actions/ListAction.d.ts +2 -0
- package/build/src/modeling/actions/ListAction.d.ts.map +1 -1
- package/build/src/modeling/actions/ListAction.js +8 -2
- package/build/src/modeling/actions/ListAction.js.map +1 -1
- package/build/src/modeling/actions/ReadAction.d.ts +2 -0
- package/build/src/modeling/actions/ReadAction.d.ts.map +1 -1
- package/build/src/modeling/actions/ReadAction.js +6 -0
- package/build/src/modeling/actions/ReadAction.js.map +1 -1
- package/build/src/modeling/actions/SearchAction.d.ts +2 -0
- package/build/src/modeling/actions/SearchAction.d.ts.map +1 -1
- package/build/src/modeling/actions/SearchAction.js +6 -0
- package/build/src/modeling/actions/SearchAction.js.map +1 -1
- package/build/src/modeling/actions/UpdateAction.d.ts +2 -0
- package/build/src/modeling/actions/UpdateAction.d.ts.map +1 -1
- package/build/src/modeling/actions/UpdateAction.js +6 -0
- package/build/src/modeling/actions/UpdateAction.js.map +1 -1
- package/build/src/modeling/actions/index.d.ts +10 -0
- package/build/src/modeling/actions/index.d.ts.map +1 -1
- package/build/src/modeling/actions/index.js +30 -0
- package/build/src/modeling/actions/index.js.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.d.ts +2 -2
- package/build/src/modeling/rules/AllowAuthenticated.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.js +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.js.map +1 -1
- package/build/src/modeling/rules/AllowPublic.d.ts +2 -2
- package/build/src/modeling/rules/AllowPublic.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowPublic.js +1 -1
- package/build/src/modeling/rules/AllowPublic.js.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.d.ts +2 -2
- package/build/src/modeling/rules/MatchResourceOwner.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.js +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.js.map +1 -1
- package/build/src/modeling/rules/index.d.ts +14 -2
- package/build/src/modeling/rules/index.d.ts.map +1 -1
- package/build/src/modeling/rules/index.js +32 -1
- package/build/src/modeling/rules/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +25 -25
- package/package.json +1 -1
- package/src/decorators/observed.ts +15 -1
- package/src/modeling/ApiModel.ts +2 -1
- package/src/modeling/ExposedEntity.ts +4 -2
- package/src/modeling/actions/Action.ts +2 -1
- package/src/modeling/actions/CreateAction.ts +8 -0
- package/src/modeling/actions/DeleteAction.ts +8 -0
- package/src/modeling/actions/ListAction.ts +10 -2
- package/src/modeling/actions/ReadAction.ts +8 -0
- package/src/modeling/actions/SearchAction.ts +8 -0
- package/src/modeling/actions/UpdateAction.ts +8 -0
- package/src/modeling/rules/AllowAuthenticated.ts +3 -3
- package/src/modeling/rules/AllowPublic.ts +3 -3
- package/src/modeling/rules/MatchResourceOwner.ts +3 -3
- package/tests/unit/decorators/observed.spec.ts +42 -0
- package/tests/unit/modeling/actions/Action.spec.ts +10 -10
- package/tests/unit/modeling/actions/CreateAction.spec.ts +8 -8
- package/tests/unit/modeling/actions/DeleteAction.spec.ts +5 -5
- package/tests/unit/modeling/actions/ReadAction.spec.ts +9 -9
- package/tests/unit/modeling/api_model.spec.ts +3 -3
- package/tests/unit/modeling/exposed_entity.spec.ts +8 -8
- package/tests/unit/modeling/exposed_entity_actions.spec.ts +182 -0
- package/tests/unit/modeling/rules/AllowAuthenticated.spec.ts +2 -2
- package/tests/unit/modeling/rules/AllowPublic.spec.ts +2 -2
- package/tests/unit/modeling/rules/MatchResourceOwner.spec.ts +3 -3
- package/tests/unit/modeling/rules/restoring_rules.spec.ts +121 -0
|
@@ -14,29 +14,29 @@ test.group('DeleteAction', () => {
|
|
|
14
14
|
const action = new DeleteAction({
|
|
15
15
|
strategy: 'hard',
|
|
16
16
|
retentionPeriod: 0,
|
|
17
|
-
accessRule: [{ type: '
|
|
17
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
18
18
|
})
|
|
19
19
|
|
|
20
20
|
assert.equal(action.kind, 'delete')
|
|
21
21
|
assert.equal(action.strategy, 'hard')
|
|
22
22
|
assert.equal(action.retentionPeriod, 0)
|
|
23
23
|
assert.lengthOf(action.accessRule, 1)
|
|
24
|
-
assert.equal(action.accessRule[0].type, '
|
|
24
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
25
25
|
}).tags(['@modeling', '@action', '@delete-action'])
|
|
26
26
|
|
|
27
27
|
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
28
|
-
const rules = [{ type: '
|
|
28
|
+
const rules = [{ type: 'allowPublic' }]
|
|
29
29
|
|
|
30
30
|
const action = new DeleteAction({
|
|
31
31
|
accessRule: rules,
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
// Modify original source
|
|
35
|
-
rules.push({ type: '
|
|
35
|
+
rules.push({ type: 'other' })
|
|
36
36
|
rules[0].type = 'changed'
|
|
37
37
|
|
|
38
38
|
assert.lengthOf(action.accessRule, 1)
|
|
39
|
-
assert.equal(action.accessRule[0].type, '
|
|
39
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
40
40
|
}).tags(['@modeling', '@action', '@delete-action', '@immutability'])
|
|
41
41
|
|
|
42
42
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
@@ -11,32 +11,32 @@ test.group('ReadAction', () => {
|
|
|
11
11
|
|
|
12
12
|
test('initializes with inherited values', ({ assert }) => {
|
|
13
13
|
const action = new ReadAction({
|
|
14
|
-
accessRule: [{ type: '
|
|
14
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
assert.equal(action.kind, 'read')
|
|
18
18
|
assert.lengthOf(action.accessRule, 1)
|
|
19
|
-
assert.equal(action.accessRule[0].type, '
|
|
19
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
20
20
|
}).tags(['@modeling', '@action', '@read-action'])
|
|
21
21
|
|
|
22
22
|
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
23
|
-
const rules = [{ type: '
|
|
23
|
+
const rules = [{ type: 'allowPublic' }]
|
|
24
24
|
|
|
25
25
|
const action = new ReadAction({
|
|
26
26
|
accessRule: rules,
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
// Modify original source
|
|
30
|
-
rules.push({ type: '
|
|
30
|
+
rules.push({ type: 'other' })
|
|
31
31
|
rules[0].type = 'changed'
|
|
32
32
|
|
|
33
33
|
assert.lengthOf(action.accessRule, 1)
|
|
34
|
-
assert.equal(action.accessRule[0].type, '
|
|
34
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
35
35
|
}).tags(['@modeling', '@action', '@read-action', '@immutability'])
|
|
36
36
|
|
|
37
37
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
38
38
|
const action = new ReadAction({
|
|
39
|
-
accessRule: [{ type: '
|
|
39
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
const json = action.toJSON()
|
|
@@ -44,7 +44,7 @@ test.group('ReadAction', () => {
|
|
|
44
44
|
assert.equal(json.kind, 'read')
|
|
45
45
|
if (json.accessRule) {
|
|
46
46
|
assert.lengthOf(json.accessRule, 1)
|
|
47
|
-
assert.equal(json.accessRule[0].type, '
|
|
47
|
+
assert.equal(json.accessRule[0].type, 'allowPublic')
|
|
48
48
|
} else {
|
|
49
49
|
assert.fail('accessRule should be present in JSON')
|
|
50
50
|
}
|
|
@@ -58,7 +58,7 @@ test.group('ReadAction', () => {
|
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
// Modify inherited property
|
|
61
|
-
action.accessRule = [new AccessRule({ type: '
|
|
61
|
+
action.accessRule = [new AccessRule({ type: 'allowPublic' })]
|
|
62
62
|
await Promise.resolve()
|
|
63
63
|
assert.isTrue(notified)
|
|
64
64
|
}).tags(['@modeling', '@action', '@read-action', '@observed'])
|
|
@@ -70,7 +70,7 @@ test.group('ReadAction', () => {
|
|
|
70
70
|
notified = true
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
action.accessRule.push(new AccessRule({ type: '
|
|
73
|
+
action.accessRule.push(new AccessRule({ type: 'allowPublic' }))
|
|
74
74
|
await Promise.resolve()
|
|
75
75
|
assert.isTrue(notified)
|
|
76
76
|
}).tags(['@modeling', '@action', '@read-action', '@observed'])
|
|
@@ -130,7 +130,7 @@ test.group('ApiModel.constructor()', () => {
|
|
|
130
130
|
authentication: { strategy: 'UsernamePassword' },
|
|
131
131
|
authorization: { strategy: 'RBAC', roleKey: 'role' } as RolesBasedAccessControl,
|
|
132
132
|
session: { secret: 'secret', properties: ['email'] },
|
|
133
|
-
accessRule: [{ type: '
|
|
133
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
134
134
|
rateLimiting: { rules: [] },
|
|
135
135
|
termsOfService: 'https://example.com/terms',
|
|
136
136
|
contact: { name: 'John Doe', email: 'john.doe@example.com' },
|
|
@@ -263,7 +263,7 @@ test.group('ApiModel.toJSON()', () => {
|
|
|
263
263
|
authentication: { strategy: 'UsernamePassword' },
|
|
264
264
|
authorization: { strategy: 'RBAC', roleKey: 'role' } as RolesBasedAccessControl,
|
|
265
265
|
session: { secret: 'secret', properties: ['email'] },
|
|
266
|
-
accessRule: [{ type: '
|
|
266
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
267
267
|
rateLimiting: { rules: [] },
|
|
268
268
|
termsOfService: 'https://example.com/terms',
|
|
269
269
|
contact: { name: 'John Doe', email: 'john.doe@example.com' },
|
|
@@ -281,7 +281,7 @@ test.group('ApiModel.toJSON()', () => {
|
|
|
281
281
|
assert.deepEqual(json.authentication, { strategy: 'UsernamePassword' })
|
|
282
282
|
assert.deepEqual(json.authorization, { strategy: 'RBAC', roleKey: 'role' })
|
|
283
283
|
assert.deepEqual(json.session, { secret: 'secret', properties: ['email'] })
|
|
284
|
-
assert.deepEqual(json.accessRule, [{ type: '
|
|
284
|
+
assert.deepEqual(json.accessRule, [{ type: 'allowPublic' }])
|
|
285
285
|
assert.deepEqual(json.rateLimiting, { rules: [] })
|
|
286
286
|
assert.equal(json.termsOfService, 'https://example.com/terms')
|
|
287
287
|
assert.deepEqual(json.contact, { name: 'John Doe', email: 'john.doe@example.com' })
|
|
@@ -156,29 +156,29 @@ test.group('ExposedEntity', () => {
|
|
|
156
156
|
test('restores actions and rules from schema', ({ assert }) => {
|
|
157
157
|
const model = new ApiModel()
|
|
158
158
|
const ex = new ExposedEntity(model, {
|
|
159
|
-
actions: [{ kind: 'read', accessRule: [{ type: '
|
|
160
|
-
accessRule: [{ type: '
|
|
159
|
+
actions: [{ kind: 'read', accessRule: [{ type: 'allowPublic' }] }],
|
|
160
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
161
161
|
})
|
|
162
162
|
|
|
163
163
|
assert.lengthOf(ex.actions, 1)
|
|
164
164
|
assert.equal(ex.actions[0].kind, 'read')
|
|
165
165
|
assert.lengthOf(ex.actions[0].accessRule, 1)
|
|
166
|
-
assert.equal(ex.actions[0].accessRule[0].type, '
|
|
166
|
+
assert.equal(ex.actions[0].accessRule[0].type, 'allowPublic')
|
|
167
167
|
|
|
168
168
|
assert.lengthOf(ex.accessRule!, 1)
|
|
169
|
-
assert.equal(ex.accessRule![0].type, '
|
|
169
|
+
assert.equal(ex.accessRule![0].type, 'allowPublic')
|
|
170
170
|
}).tags(['@modeling', '@exposed-entity'])
|
|
171
171
|
|
|
172
172
|
test('serializes actions and rules', ({ assert }) => {
|
|
173
173
|
const model = new ApiModel()
|
|
174
174
|
const ex = new ExposedEntity(model, {
|
|
175
175
|
actions: [{ kind: 'read' }],
|
|
176
|
-
accessRule: [{ type: '
|
|
176
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
177
177
|
})
|
|
178
178
|
|
|
179
179
|
const json = ex.toJSON()
|
|
180
180
|
assert.deepInclude(json.actions[0], { kind: 'read' })
|
|
181
|
-
assert.deepInclude(json.accessRule![0], { type: '
|
|
181
|
+
assert.deepInclude(json.accessRule![0], { type: 'allowPublic' })
|
|
182
182
|
}).tags(['@modeling', '@exposed-entity'])
|
|
183
183
|
|
|
184
184
|
test('notifies change when action property changes', async ({ assert }) => {
|
|
@@ -212,7 +212,7 @@ test.group('ExposedEntity', () => {
|
|
|
212
212
|
|
|
213
213
|
test('constructor copies accessRule array (immutability)', ({ assert }) => {
|
|
214
214
|
const model = new ApiModel()
|
|
215
|
-
const rules = [{ type: '
|
|
215
|
+
const rules = [{ type: 'allowPublic' }]
|
|
216
216
|
const ex = new ExposedEntity(model, {
|
|
217
217
|
actions: [],
|
|
218
218
|
accessRule: rules,
|
|
@@ -223,6 +223,6 @@ test.group('ExposedEntity', () => {
|
|
|
223
223
|
rules[0].type = 'changed'
|
|
224
224
|
|
|
225
225
|
assert.lengthOf(ex.accessRule!, 1)
|
|
226
|
-
assert.equal(ex.accessRule![0].type, '
|
|
226
|
+
assert.equal(ex.accessRule![0].type, 'allowPublic')
|
|
227
227
|
}).tags(['@modeling', '@exposed-entity', '@immutability'])
|
|
228
228
|
})
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import {
|
|
3
|
+
ApiModel,
|
|
4
|
+
CreateAction,
|
|
5
|
+
DataDomain,
|
|
6
|
+
DeleteAction,
|
|
7
|
+
DomainEntity,
|
|
8
|
+
ListAction,
|
|
9
|
+
ReadAction,
|
|
10
|
+
SearchAction,
|
|
11
|
+
UpdateAction,
|
|
12
|
+
} from '../../../src/modeling/index.js'
|
|
13
|
+
import { ExposedEntityKind } from '../../../src/models/kinds.js'
|
|
14
|
+
import { nanoid } from '../../../src/nanoid.js'
|
|
15
|
+
|
|
16
|
+
test.group('ExposedEntity::actions', (group) => {
|
|
17
|
+
let domain: DataDomain
|
|
18
|
+
let entity: DomainEntity
|
|
19
|
+
|
|
20
|
+
group.each.setup(() => {
|
|
21
|
+
domain = new DataDomain()
|
|
22
|
+
const m1 = domain.addModel()
|
|
23
|
+
entity = m1.addEntity()
|
|
24
|
+
domain.info.version = '1.0.0'
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('restores a list acton', ({ assert }) => {
|
|
28
|
+
const action = new ListAction()
|
|
29
|
+
const model = new ApiModel(
|
|
30
|
+
{
|
|
31
|
+
exposes: [
|
|
32
|
+
{
|
|
33
|
+
kind: ExposedEntityKind,
|
|
34
|
+
key: nanoid(),
|
|
35
|
+
entity: { key: entity.key },
|
|
36
|
+
hasCollection: true,
|
|
37
|
+
collectionPath: '/things',
|
|
38
|
+
resourcePath: '/things/{id}',
|
|
39
|
+
isRoot: true,
|
|
40
|
+
actions: [action.toJSON()],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
domain
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
48
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
49
|
+
assert.equal(restoredAction.kind, 'list', 'Action kind should be list')
|
|
50
|
+
assert.instanceOf(restoredAction, ListAction, 'Action should be an instance of ListAction')
|
|
51
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
52
|
+
|
|
53
|
+
test('restores a create acton', ({ assert }) => {
|
|
54
|
+
const action = new CreateAction()
|
|
55
|
+
const model = new ApiModel(
|
|
56
|
+
{
|
|
57
|
+
exposes: [
|
|
58
|
+
{
|
|
59
|
+
kind: ExposedEntityKind,
|
|
60
|
+
key: nanoid(),
|
|
61
|
+
entity: { key: entity.key },
|
|
62
|
+
hasCollection: true,
|
|
63
|
+
collectionPath: '/things',
|
|
64
|
+
resourcePath: '/things/{id}',
|
|
65
|
+
isRoot: true,
|
|
66
|
+
actions: [action.toJSON()],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
domain
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
74
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
75
|
+
assert.equal(restoredAction.kind, 'create', 'Action kind should be create')
|
|
76
|
+
assert.instanceOf(restoredAction, CreateAction, 'Action should be an instance of CreateAction')
|
|
77
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
78
|
+
|
|
79
|
+
test('restores a read acton', ({ assert }) => {
|
|
80
|
+
const action = new ReadAction()
|
|
81
|
+
const model = new ApiModel(
|
|
82
|
+
{
|
|
83
|
+
exposes: [
|
|
84
|
+
{
|
|
85
|
+
kind: ExposedEntityKind,
|
|
86
|
+
key: nanoid(),
|
|
87
|
+
entity: { key: entity.key },
|
|
88
|
+
hasCollection: true,
|
|
89
|
+
collectionPath: '/things',
|
|
90
|
+
resourcePath: '/things/{id}',
|
|
91
|
+
isRoot: true,
|
|
92
|
+
actions: [action.toJSON()],
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
domain
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
100
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
101
|
+
assert.equal(restoredAction.kind, 'read', 'Action kind should be read')
|
|
102
|
+
assert.instanceOf(restoredAction, ReadAction, 'Action should be an instance of ReadAction')
|
|
103
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
104
|
+
|
|
105
|
+
test('restores a update acton', ({ assert }) => {
|
|
106
|
+
const action = new UpdateAction()
|
|
107
|
+
const model = new ApiModel(
|
|
108
|
+
{
|
|
109
|
+
exposes: [
|
|
110
|
+
{
|
|
111
|
+
kind: ExposedEntityKind,
|
|
112
|
+
key: nanoid(),
|
|
113
|
+
entity: { key: entity.key },
|
|
114
|
+
hasCollection: true,
|
|
115
|
+
collectionPath: '/things',
|
|
116
|
+
resourcePath: '/things/{id}',
|
|
117
|
+
isRoot: true,
|
|
118
|
+
actions: [action.toJSON()],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
domain
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
126
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
127
|
+
assert.equal(restoredAction.kind, 'update', 'Action kind should be update')
|
|
128
|
+
assert.instanceOf(restoredAction, UpdateAction, 'Action should be an instance of UpdateAction')
|
|
129
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
130
|
+
|
|
131
|
+
test('restores a delete acton', ({ assert }) => {
|
|
132
|
+
const action = new DeleteAction()
|
|
133
|
+
const model = new ApiModel(
|
|
134
|
+
{
|
|
135
|
+
exposes: [
|
|
136
|
+
{
|
|
137
|
+
kind: ExposedEntityKind,
|
|
138
|
+
key: nanoid(),
|
|
139
|
+
entity: { key: entity.key },
|
|
140
|
+
hasCollection: true,
|
|
141
|
+
collectionPath: '/things',
|
|
142
|
+
resourcePath: '/things/{id}',
|
|
143
|
+
isRoot: true,
|
|
144
|
+
actions: [action.toJSON()],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
domain
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
152
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
153
|
+
assert.equal(restoredAction.kind, 'delete', 'Action kind should be delete')
|
|
154
|
+
assert.instanceOf(restoredAction, DeleteAction, 'Action should be an instance of DeleteAction')
|
|
155
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
156
|
+
|
|
157
|
+
test('restores a search acton', ({ assert }) => {
|
|
158
|
+
const action = new SearchAction()
|
|
159
|
+
const model = new ApiModel(
|
|
160
|
+
{
|
|
161
|
+
exposes: [
|
|
162
|
+
{
|
|
163
|
+
kind: ExposedEntityKind,
|
|
164
|
+
key: nanoid(),
|
|
165
|
+
entity: { key: entity.key },
|
|
166
|
+
hasCollection: true,
|
|
167
|
+
collectionPath: '/things',
|
|
168
|
+
resourcePath: '/things/{id}',
|
|
169
|
+
isRoot: true,
|
|
170
|
+
actions: [action.toJSON()],
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
domain
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
const restoredAction = model.exposes[0].actions[0]
|
|
178
|
+
assert.ok(restoredAction, 'Action should be restored')
|
|
179
|
+
assert.equal(restoredAction.kind, 'search', 'Action kind should be search')
|
|
180
|
+
assert.instanceOf(restoredAction, SearchAction, 'Action should be an instance of SearchAction')
|
|
181
|
+
}).tags(['@modeling', '@action', '@restoring'])
|
|
182
|
+
})
|
|
@@ -4,14 +4,14 @@ import { AllowAuthenticatedAccessRule } from '../../../../src/modeling/rules/All
|
|
|
4
4
|
test.group('AllowAuthenticatedAccessRule', () => {
|
|
5
5
|
test('initializes with correct type', ({ assert }) => {
|
|
6
6
|
const rule = new AllowAuthenticatedAccessRule()
|
|
7
|
-
assert.equal(rule.type, '
|
|
7
|
+
assert.equal(rule.type, 'allowAuthenticated')
|
|
8
8
|
}).tags(['@modeling', '@rule', '@allow-authenticated'])
|
|
9
9
|
|
|
10
10
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
11
11
|
const rule = new AllowAuthenticatedAccessRule()
|
|
12
12
|
const json = rule.toJSON()
|
|
13
13
|
|
|
14
|
-
assert.equal(json.type, '
|
|
14
|
+
assert.equal(json.type, 'allowAuthenticated')
|
|
15
15
|
}).tags(['@modeling', '@rule', '@allow-authenticated', '@serialization'])
|
|
16
16
|
|
|
17
17
|
test('notifies change', async ({ assert }) => {
|
|
@@ -4,14 +4,14 @@ import { AllowPublicAccessRule } from '../../../../src/modeling/rules/AllowPubli
|
|
|
4
4
|
test.group('AllowPublicAccessRule', () => {
|
|
5
5
|
test('initializes with correct type', ({ assert }) => {
|
|
6
6
|
const rule = new AllowPublicAccessRule()
|
|
7
|
-
assert.equal(rule.type, '
|
|
7
|
+
assert.equal(rule.type, 'allowPublic')
|
|
8
8
|
}).tags(['@modeling', '@rule', '@allow-public'])
|
|
9
9
|
|
|
10
10
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
11
11
|
const rule = new AllowPublicAccessRule()
|
|
12
12
|
const json = rule.toJSON()
|
|
13
13
|
|
|
14
|
-
assert.equal(json.type, '
|
|
14
|
+
assert.equal(json.type, 'allowPublic')
|
|
15
15
|
}).tags(['@modeling', '@rule', '@allow-public', '@serialization'])
|
|
16
16
|
|
|
17
17
|
test('notifies change', async ({ assert }) => {
|
|
@@ -4,14 +4,14 @@ import { MatchResourceOwnerAccessRule } from '../../../../src/modeling/rules/Mat
|
|
|
4
4
|
test.group('MatchResourceOwnerAccessRule', () => {
|
|
5
5
|
test('initializes with default values', ({ assert }) => {
|
|
6
6
|
const rule = new MatchResourceOwnerAccessRule()
|
|
7
|
-
assert.equal(rule.type, '
|
|
7
|
+
assert.equal(rule.type, 'matchResourceOwner')
|
|
8
8
|
assert.equal(rule.property, '')
|
|
9
9
|
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
10
10
|
|
|
11
11
|
test('initializes with provided values', ({ assert }) => {
|
|
12
12
|
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
13
13
|
|
|
14
|
-
assert.equal(rule.type, '
|
|
14
|
+
assert.equal(rule.type, 'matchResourceOwner')
|
|
15
15
|
assert.equal(rule.property, 'creatorId')
|
|
16
16
|
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@ test.group('MatchResourceOwnerAccessRule', () => {
|
|
|
19
19
|
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
20
20
|
const json = rule.toJSON()
|
|
21
21
|
|
|
22
|
-
assert.equal(json.type, '
|
|
22
|
+
assert.equal(json.type, 'matchResourceOwner')
|
|
23
23
|
assert.equal(json.property, 'creatorId')
|
|
24
24
|
}).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])
|
|
25
25
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { ApiModel, DataDomain, DomainEntity, ListAction } from '../../../../src/modeling/index.js'
|
|
3
|
+
import {
|
|
4
|
+
AllowAuthenticatedAccessRule,
|
|
5
|
+
AllowPublicAccessRule,
|
|
6
|
+
MatchEmailDomainAccessRule,
|
|
7
|
+
MatchResourceOwnerAccessRule,
|
|
8
|
+
MatchUserPropertyAccessRule,
|
|
9
|
+
MatchUserRoleAccessRule,
|
|
10
|
+
} from '../../../../src/modeling/index.js'
|
|
11
|
+
import { nanoid } from '../../../../src/nanoid.js'
|
|
12
|
+
import { ExposedEntityKind } from '../../../../src/models/kinds.js'
|
|
13
|
+
|
|
14
|
+
test.group('restoring actions', (group) => {
|
|
15
|
+
let domain: DataDomain
|
|
16
|
+
let entity: DomainEntity
|
|
17
|
+
|
|
18
|
+
group.each.setup(() => {
|
|
19
|
+
domain = new DataDomain()
|
|
20
|
+
const m1 = domain.addModel()
|
|
21
|
+
entity = m1.addEntity()
|
|
22
|
+
domain.info.version = '1.0.0'
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('restores rules on the API model', ({ assert }) => {
|
|
26
|
+
const r1 = new AllowAuthenticatedAccessRule()
|
|
27
|
+
const r2 = new AllowPublicAccessRule()
|
|
28
|
+
const r3 = new MatchEmailDomainAccessRule()
|
|
29
|
+
const r4 = new MatchResourceOwnerAccessRule()
|
|
30
|
+
const r5 = new MatchUserPropertyAccessRule()
|
|
31
|
+
const r6 = new MatchUserRoleAccessRule()
|
|
32
|
+
const model = new ApiModel(
|
|
33
|
+
{
|
|
34
|
+
accessRule: [r1.toJSON(), r2.toJSON(), r3.toJSON(), r4.toJSON(), r5.toJSON(), r6.toJSON()],
|
|
35
|
+
},
|
|
36
|
+
domain
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
assert.lengthOf(model.accessRule, 6)
|
|
40
|
+
assert.instanceOf(model.accessRule[0], AllowAuthenticatedAccessRule)
|
|
41
|
+
assert.instanceOf(model.accessRule[1], AllowPublicAccessRule)
|
|
42
|
+
assert.instanceOf(model.accessRule[2], MatchEmailDomainAccessRule)
|
|
43
|
+
assert.instanceOf(model.accessRule[3], MatchResourceOwnerAccessRule)
|
|
44
|
+
assert.instanceOf(model.accessRule[4], MatchUserPropertyAccessRule)
|
|
45
|
+
assert.instanceOf(model.accessRule[5], MatchUserRoleAccessRule)
|
|
46
|
+
}).tags(['@modeling', '@rule', '@restoring'])
|
|
47
|
+
|
|
48
|
+
test('restores rules on the exposed entity', ({ assert }) => {
|
|
49
|
+
const r1 = new AllowAuthenticatedAccessRule()
|
|
50
|
+
const r2 = new AllowPublicAccessRule()
|
|
51
|
+
const r3 = new MatchEmailDomainAccessRule()
|
|
52
|
+
const r4 = new MatchResourceOwnerAccessRule()
|
|
53
|
+
const r5 = new MatchUserPropertyAccessRule()
|
|
54
|
+
const r6 = new MatchUserRoleAccessRule()
|
|
55
|
+
const model = new ApiModel(
|
|
56
|
+
{
|
|
57
|
+
exposes: [
|
|
58
|
+
{
|
|
59
|
+
kind: ExposedEntityKind,
|
|
60
|
+
key: nanoid(),
|
|
61
|
+
entity: { key: entity.key },
|
|
62
|
+
hasCollection: true,
|
|
63
|
+
collectionPath: '/things',
|
|
64
|
+
resourcePath: '/things/{id}',
|
|
65
|
+
isRoot: true,
|
|
66
|
+
actions: [],
|
|
67
|
+
accessRule: [r1.toJSON(), r2.toJSON(), r3.toJSON(), r4.toJSON(), r5.toJSON(), r6.toJSON()],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
domain
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
const ex = model.exposes[0]!
|
|
75
|
+
assert.lengthOf(ex.accessRule!, 6)
|
|
76
|
+
assert.instanceOf(ex.accessRule![0], AllowAuthenticatedAccessRule)
|
|
77
|
+
assert.instanceOf(ex.accessRule![1], AllowPublicAccessRule)
|
|
78
|
+
assert.instanceOf(ex.accessRule![2], MatchEmailDomainAccessRule)
|
|
79
|
+
assert.instanceOf(ex.accessRule![3], MatchResourceOwnerAccessRule)
|
|
80
|
+
assert.instanceOf(ex.accessRule![4], MatchUserPropertyAccessRule)
|
|
81
|
+
assert.instanceOf(ex.accessRule![5], MatchUserRoleAccessRule)
|
|
82
|
+
}).tags(['@modeling', '@rule', '@restoring'])
|
|
83
|
+
|
|
84
|
+
test('restores rules on the action', ({ assert }) => {
|
|
85
|
+
const r1 = new AllowAuthenticatedAccessRule()
|
|
86
|
+
const r2 = new AllowPublicAccessRule()
|
|
87
|
+
const r3 = new MatchEmailDomainAccessRule()
|
|
88
|
+
const r4 = new MatchResourceOwnerAccessRule()
|
|
89
|
+
const r5 = new MatchUserPropertyAccessRule()
|
|
90
|
+
const r6 = new MatchUserRoleAccessRule()
|
|
91
|
+
const action = new ListAction({
|
|
92
|
+
accessRule: [r1.toJSON(), r2.toJSON(), r3.toJSON(), r4.toJSON(), r5.toJSON(), r6.toJSON()],
|
|
93
|
+
}).toJSON()
|
|
94
|
+
const model = new ApiModel(
|
|
95
|
+
{
|
|
96
|
+
exposes: [
|
|
97
|
+
{
|
|
98
|
+
kind: ExposedEntityKind,
|
|
99
|
+
key: nanoid(),
|
|
100
|
+
entity: { key: entity.key },
|
|
101
|
+
hasCollection: true,
|
|
102
|
+
collectionPath: '/things',
|
|
103
|
+
resourcePath: '/things/{id}',
|
|
104
|
+
isRoot: true,
|
|
105
|
+
actions: [action],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
domain
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const ex = model.exposes[0]!.actions[0]!
|
|
113
|
+
assert.lengthOf(ex.accessRule!, 6)
|
|
114
|
+
assert.instanceOf(ex.accessRule![0], AllowAuthenticatedAccessRule)
|
|
115
|
+
assert.instanceOf(ex.accessRule![1], AllowPublicAccessRule)
|
|
116
|
+
assert.instanceOf(ex.accessRule![2], MatchEmailDomainAccessRule)
|
|
117
|
+
assert.instanceOf(ex.accessRule![3], MatchResourceOwnerAccessRule)
|
|
118
|
+
assert.instanceOf(ex.accessRule![4], MatchUserPropertyAccessRule)
|
|
119
|
+
assert.instanceOf(ex.accessRule![5], MatchUserRoleAccessRule)
|
|
120
|
+
}).tags(['@modeling', '@rule', '@restoring'])
|
|
121
|
+
})
|