@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.
Files changed (84) hide show
  1. package/build/src/decorators/observed.d.ts.map +1 -1
  2. package/build/src/decorators/observed.js +15 -1
  3. package/build/src/decorators/observed.js.map +1 -1
  4. package/build/src/modeling/ApiModel.d.ts.map +1 -1
  5. package/build/src/modeling/ApiModel.js +2 -2
  6. package/build/src/modeling/ApiModel.js.map +1 -1
  7. package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
  8. package/build/src/modeling/ExposedEntity.js +4 -4
  9. package/build/src/modeling/ExposedEntity.js.map +1 -1
  10. package/build/src/modeling/actions/Action.d.ts.map +1 -1
  11. package/build/src/modeling/actions/Action.js +2 -2
  12. package/build/src/modeling/actions/Action.js.map +1 -1
  13. package/build/src/modeling/actions/CreateAction.d.ts +2 -0
  14. package/build/src/modeling/actions/CreateAction.d.ts.map +1 -1
  15. package/build/src/modeling/actions/CreateAction.js +6 -0
  16. package/build/src/modeling/actions/CreateAction.js.map +1 -1
  17. package/build/src/modeling/actions/DeleteAction.d.ts +2 -0
  18. package/build/src/modeling/actions/DeleteAction.d.ts.map +1 -1
  19. package/build/src/modeling/actions/DeleteAction.js +6 -0
  20. package/build/src/modeling/actions/DeleteAction.js.map +1 -1
  21. package/build/src/modeling/actions/ListAction.d.ts +2 -0
  22. package/build/src/modeling/actions/ListAction.d.ts.map +1 -1
  23. package/build/src/modeling/actions/ListAction.js +8 -2
  24. package/build/src/modeling/actions/ListAction.js.map +1 -1
  25. package/build/src/modeling/actions/ReadAction.d.ts +2 -0
  26. package/build/src/modeling/actions/ReadAction.d.ts.map +1 -1
  27. package/build/src/modeling/actions/ReadAction.js +6 -0
  28. package/build/src/modeling/actions/ReadAction.js.map +1 -1
  29. package/build/src/modeling/actions/SearchAction.d.ts +2 -0
  30. package/build/src/modeling/actions/SearchAction.d.ts.map +1 -1
  31. package/build/src/modeling/actions/SearchAction.js +6 -0
  32. package/build/src/modeling/actions/SearchAction.js.map +1 -1
  33. package/build/src/modeling/actions/UpdateAction.d.ts +2 -0
  34. package/build/src/modeling/actions/UpdateAction.d.ts.map +1 -1
  35. package/build/src/modeling/actions/UpdateAction.js +6 -0
  36. package/build/src/modeling/actions/UpdateAction.js.map +1 -1
  37. package/build/src/modeling/actions/index.d.ts +10 -0
  38. package/build/src/modeling/actions/index.d.ts.map +1 -1
  39. package/build/src/modeling/actions/index.js +30 -0
  40. package/build/src/modeling/actions/index.js.map +1 -1
  41. package/build/src/modeling/rules/AllowAuthenticated.d.ts +2 -2
  42. package/build/src/modeling/rules/AllowAuthenticated.d.ts.map +1 -1
  43. package/build/src/modeling/rules/AllowAuthenticated.js +1 -1
  44. package/build/src/modeling/rules/AllowAuthenticated.js.map +1 -1
  45. package/build/src/modeling/rules/AllowPublic.d.ts +2 -2
  46. package/build/src/modeling/rules/AllowPublic.d.ts.map +1 -1
  47. package/build/src/modeling/rules/AllowPublic.js +1 -1
  48. package/build/src/modeling/rules/AllowPublic.js.map +1 -1
  49. package/build/src/modeling/rules/MatchResourceOwner.d.ts +2 -2
  50. package/build/src/modeling/rules/MatchResourceOwner.d.ts.map +1 -1
  51. package/build/src/modeling/rules/MatchResourceOwner.js +1 -1
  52. package/build/src/modeling/rules/MatchResourceOwner.js.map +1 -1
  53. package/build/src/modeling/rules/index.d.ts +14 -2
  54. package/build/src/modeling/rules/index.d.ts.map +1 -1
  55. package/build/src/modeling/rules/index.js +32 -1
  56. package/build/src/modeling/rules/index.js.map +1 -1
  57. package/build/tsconfig.tsbuildinfo +1 -1
  58. package/data/models/example-generator-api.json +25 -25
  59. package/package.json +1 -1
  60. package/src/decorators/observed.ts +15 -1
  61. package/src/modeling/ApiModel.ts +2 -1
  62. package/src/modeling/ExposedEntity.ts +4 -2
  63. package/src/modeling/actions/Action.ts +2 -1
  64. package/src/modeling/actions/CreateAction.ts +8 -0
  65. package/src/modeling/actions/DeleteAction.ts +8 -0
  66. package/src/modeling/actions/ListAction.ts +10 -2
  67. package/src/modeling/actions/ReadAction.ts +8 -0
  68. package/src/modeling/actions/SearchAction.ts +8 -0
  69. package/src/modeling/actions/UpdateAction.ts +8 -0
  70. package/src/modeling/rules/AllowAuthenticated.ts +3 -3
  71. package/src/modeling/rules/AllowPublic.ts +3 -3
  72. package/src/modeling/rules/MatchResourceOwner.ts +3 -3
  73. package/tests/unit/decorators/observed.spec.ts +42 -0
  74. package/tests/unit/modeling/actions/Action.spec.ts +10 -10
  75. package/tests/unit/modeling/actions/CreateAction.spec.ts +8 -8
  76. package/tests/unit/modeling/actions/DeleteAction.spec.ts +5 -5
  77. package/tests/unit/modeling/actions/ReadAction.spec.ts +9 -9
  78. package/tests/unit/modeling/api_model.spec.ts +3 -3
  79. package/tests/unit/modeling/exposed_entity.spec.ts +8 -8
  80. package/tests/unit/modeling/exposed_entity_actions.spec.ts +182 -0
  81. package/tests/unit/modeling/rules/AllowAuthenticated.spec.ts +2 -2
  82. package/tests/unit/modeling/rules/AllowPublic.spec.ts +2 -2
  83. package/tests/unit/modeling/rules/MatchResourceOwner.spec.ts +3 -3
  84. 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: 'admin' }],
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, 'admin')
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: 'public' }]
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: 'admin' })
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, 'public')
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: 'public' }],
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, 'public')
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: 'public' }]
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: 'admin' })
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, 'public')
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: 'public' }],
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, 'public')
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: 'admin' })]
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: 'admin' }))
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: 'public' }],
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: 'public' }],
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: 'public' }])
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: 'public' }] }],
160
- accessRule: [{ type: 'admin' }],
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, 'public')
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, 'admin')
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: 'admin' }],
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: 'admin' })
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: 'public' }]
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, 'public')
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, 'authenticated')
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, 'authenticated')
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, 'public')
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, 'public')
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, 'resourceOwner')
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, 'resourceOwner')
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, 'resourceOwner')
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
+ })