@api-client/core 0.19.21 → 0.19.23
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/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +37 -13
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/ExposedEntity.d.ts +9 -0
- package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
- package/build/src/modeling/ExposedEntity.js +90 -14
- package/build/src/modeling/ExposedEntity.js.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/rules/AccessRule.d.ts +5 -1
- package/build/src/modeling/rules/AccessRule.d.ts.map +1 -1
- package/build/src/modeling/rules/AccessRule.js +4 -1
- package/build/src/modeling/rules/AccessRule.js.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.d.ts +4 -1
- package/build/src/modeling/rules/AllowAuthenticated.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.js +2 -2
- package/build/src/modeling/rules/AllowAuthenticated.js.map +1 -1
- package/build/src/modeling/rules/AllowPublic.d.ts +4 -1
- package/build/src/modeling/rules/AllowPublic.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowPublic.js +2 -2
- package/build/src/modeling/rules/AllowPublic.js.map +1 -1
- package/build/src/modeling/rules/MatchEmailDomain.d.ts +4 -1
- package/build/src/modeling/rules/MatchEmailDomain.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchEmailDomain.js +2 -2
- package/build/src/modeling/rules/MatchEmailDomain.js.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.d.ts +4 -1
- package/build/src/modeling/rules/MatchResourceOwner.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.js +2 -2
- package/build/src/modeling/rules/MatchResourceOwner.js.map +1 -1
- package/build/src/modeling/rules/MatchUserProperty.d.ts +4 -1
- package/build/src/modeling/rules/MatchUserProperty.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchUserProperty.js +2 -2
- package/build/src/modeling/rules/MatchUserProperty.js.map +1 -1
- package/build/src/modeling/rules/MatchUserRole.d.ts +4 -1
- package/build/src/modeling/rules/MatchUserRole.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchUserRole.js +2 -2
- package/build/src/modeling/rules/MatchUserRole.js.map +1 -1
- package/build/src/modeling/rules/index.d.ts +4 -1
- package/build/src/modeling/rules/index.d.ts.map +1 -1
- package/build/src/modeling/rules/index.js +7 -7
- package/build/src/modeling/rules/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/modeling/ApiModel.ts +37 -13
- package/src/modeling/ExposedEntity.ts +98 -15
- package/src/modeling/actions/Action.ts +2 -2
- package/src/modeling/rules/AccessRule.ts +8 -1
- package/src/modeling/rules/AllowAuthenticated.ts +5 -2
- package/src/modeling/rules/AllowPublic.ts +5 -2
- package/src/modeling/rules/MatchEmailDomain.ts +5 -2
- package/src/modeling/rules/MatchResourceOwner.ts +5 -2
- package/src/modeling/rules/MatchUserProperty.ts +5 -2
- package/src/modeling/rules/MatchUserRole.ts +5 -2
- package/tests/unit/modeling/actions/Action.spec.ts +13 -10
- package/tests/unit/modeling/actions/CreateAction.spec.ts +7 -6
- package/tests/unit/modeling/actions/DeleteAction.spec.ts +7 -6
- package/tests/unit/modeling/actions/ListAction.spec.ts +5 -4
- package/tests/unit/modeling/actions/ReadAction.spec.ts +9 -8
- package/tests/unit/modeling/actions/SearchAction.spec.ts +5 -4
- package/tests/unit/modeling/actions/UpdateAction.spec.ts +7 -6
- package/tests/unit/modeling/actions/helpers.ts +7 -0
- package/tests/unit/modeling/api_model.spec.ts +3 -1
- package/tests/unit/modeling/api_model_expose_entity.spec.ts +5 -17
- package/tests/unit/modeling/exposed_entity.spec.ts +150 -3
- package/tests/unit/modeling/exposed_entity_actions.spec.ts +0 -4
- package/tests/unit/modeling/rules/AccessRule.spec.ts +6 -5
- package/tests/unit/modeling/rules/AllowAuthenticated.spec.ts +4 -3
- package/tests/unit/modeling/rules/AllowPublic.spec.ts +4 -3
- package/tests/unit/modeling/rules/MatchEmailDomain.spec.ts +6 -5
- package/tests/unit/modeling/rules/MatchResourceOwner.spec.ts +7 -6
- package/tests/unit/modeling/rules/MatchUserProperty.spec.ts +6 -5
- package/tests/unit/modeling/rules/MatchUserRole.spec.ts +6 -5
- package/tests/unit/modeling/rules/restoring_rules.spec.ts +19 -21
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { test } from '@japa/runner'
|
|
2
2
|
import { MatchEmailDomainAccessRule } from '../../../../src/modeling/rules/MatchEmailDomain.js'
|
|
3
|
+
import { mockExposedEntity } from '../actions/helpers.js'
|
|
3
4
|
|
|
4
5
|
test.group('MatchEmailDomainAccessRule', () => {
|
|
5
6
|
test('initializes with default values', ({ assert }) => {
|
|
6
|
-
const rule = new MatchEmailDomainAccessRule()
|
|
7
|
+
const rule = new MatchEmailDomainAccessRule(mockExposedEntity())
|
|
7
8
|
assert.equal(rule.type, 'matchEmailDomain')
|
|
8
9
|
assert.deepEqual(rule.domains, [])
|
|
9
10
|
}).tags(['@modeling', '@rule', '@match-email-domain'])
|
|
10
11
|
|
|
11
12
|
test('initializes with provided values', ({ assert }) => {
|
|
12
13
|
const domains = ['example.com', 'test.org']
|
|
13
|
-
const rule = new MatchEmailDomainAccessRule({ domains })
|
|
14
|
+
const rule = new MatchEmailDomainAccessRule(mockExposedEntity(), { domains })
|
|
14
15
|
|
|
15
16
|
assert.equal(rule.type, 'matchEmailDomain')
|
|
16
17
|
assert.deepEqual(rule.domains, domains)
|
|
@@ -18,7 +19,7 @@ test.group('MatchEmailDomainAccessRule', () => {
|
|
|
18
19
|
|
|
19
20
|
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
20
21
|
const domains = ['example.com']
|
|
21
|
-
const rule = new MatchEmailDomainAccessRule({ domains })
|
|
22
|
+
const rule = new MatchEmailDomainAccessRule(mockExposedEntity(), { domains })
|
|
22
23
|
|
|
23
24
|
// Modify original source
|
|
24
25
|
domains.push('hacker.com')
|
|
@@ -27,7 +28,7 @@ test.group('MatchEmailDomainAccessRule', () => {
|
|
|
27
28
|
}).tags(['@modeling', '@rule', '@match-email-domain', '@immutability'])
|
|
28
29
|
|
|
29
30
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
30
|
-
const rule = new MatchEmailDomainAccessRule({ domains: ['example.com'] })
|
|
31
|
+
const rule = new MatchEmailDomainAccessRule(mockExposedEntity(), { domains: ['example.com'] })
|
|
31
32
|
const json = rule.toJSON()
|
|
32
33
|
|
|
33
34
|
// Modify JSON
|
|
@@ -39,7 +40,7 @@ test.group('MatchEmailDomainAccessRule', () => {
|
|
|
39
40
|
}).tags(['@modeling', '@rule', '@match-email-domain', '@serialization', '@immutability'])
|
|
40
41
|
|
|
41
42
|
test('notifies change when domains changes', async ({ assert }) => {
|
|
42
|
-
const rule = new MatchEmailDomainAccessRule()
|
|
43
|
+
const rule = new MatchEmailDomainAccessRule(mockExposedEntity())
|
|
43
44
|
let notified = false
|
|
44
45
|
rule.addEventListener('change', () => {
|
|
45
46
|
notified = true
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { test } from '@japa/runner'
|
|
2
2
|
import { MatchResourceOwnerAccessRule } from '../../../../src/modeling/rules/MatchResourceOwner.js'
|
|
3
|
+
import { mockExposedEntity } from '../actions/helpers.js'
|
|
3
4
|
|
|
4
5
|
test.group('MatchResourceOwnerAccessRule', () => {
|
|
5
6
|
test('initializes with default values', ({ assert }) => {
|
|
6
|
-
const rule = new MatchResourceOwnerAccessRule()
|
|
7
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity())
|
|
7
8
|
assert.equal(rule.type, 'matchResourceOwner')
|
|
8
9
|
assert.isUndefined(rule.property)
|
|
9
10
|
assert.equal(rule.target, 'property')
|
|
10
11
|
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
11
12
|
|
|
12
13
|
test('initializes with provided values', ({ assert }) => {
|
|
13
|
-
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
14
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity(), { property: 'creatorId' })
|
|
14
15
|
|
|
15
16
|
assert.equal(rule.type, 'matchResourceOwner')
|
|
16
17
|
assert.equal(rule.property, 'creatorId')
|
|
@@ -18,7 +19,7 @@ test.group('MatchResourceOwnerAccessRule', () => {
|
|
|
18
19
|
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
19
20
|
|
|
20
21
|
test('initializes with target user-entity', ({ assert }) => {
|
|
21
|
-
const rule = new MatchResourceOwnerAccessRule({ target: 'user-entity' })
|
|
22
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity(), { target: 'user-entity' })
|
|
22
23
|
|
|
23
24
|
assert.equal(rule.type, 'matchResourceOwner')
|
|
24
25
|
assert.isUndefined(rule.property)
|
|
@@ -26,7 +27,7 @@ test.group('MatchResourceOwnerAccessRule', () => {
|
|
|
26
27
|
}).tags(['@modeling', '@rule', '@match-resource-owner'])
|
|
27
28
|
|
|
28
29
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
29
|
-
const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
|
|
30
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity(), { property: 'creatorId' })
|
|
30
31
|
const json = rule.toJSON()
|
|
31
32
|
|
|
32
33
|
assert.equal(json.type, 'matchResourceOwner')
|
|
@@ -35,7 +36,7 @@ test.group('MatchResourceOwnerAccessRule', () => {
|
|
|
35
36
|
}).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])
|
|
36
37
|
|
|
37
38
|
test('toJSON omits property when undefined', ({ assert }) => {
|
|
38
|
-
const rule = new MatchResourceOwnerAccessRule({ target: 'user-entity' })
|
|
39
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity(), { target: 'user-entity' })
|
|
39
40
|
const json = rule.toJSON()
|
|
40
41
|
|
|
41
42
|
assert.equal(json.type, 'matchResourceOwner')
|
|
@@ -44,7 +45,7 @@ test.group('MatchResourceOwnerAccessRule', () => {
|
|
|
44
45
|
}).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])
|
|
45
46
|
|
|
46
47
|
test('notifies change when property changes', async ({ assert }) => {
|
|
47
|
-
const rule = new MatchResourceOwnerAccessRule()
|
|
48
|
+
const rule = new MatchResourceOwnerAccessRule(mockExposedEntity())
|
|
48
49
|
let notified = false
|
|
49
50
|
rule.addEventListener('change', () => {
|
|
50
51
|
notified = true
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { test } from '@japa/runner'
|
|
2
2
|
import { MatchUserPropertyAccessRule } from '../../../../src/modeling/rules/MatchUserProperty.js'
|
|
3
|
+
import { mockExposedEntity } from '../actions/helpers.js'
|
|
3
4
|
|
|
4
5
|
test.group('MatchUserPropertyAccessRule', () => {
|
|
5
6
|
test('initializes with default values', ({ assert }) => {
|
|
6
|
-
const rule = new MatchUserPropertyAccessRule()
|
|
7
|
+
const rule = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
7
8
|
assert.equal(rule.type, 'matchUserProperty')
|
|
8
9
|
assert.equal(rule.property, '')
|
|
9
10
|
assert.equal(rule.value, '')
|
|
10
11
|
}).tags(['@modeling', '@rule', '@match-user-property'])
|
|
11
12
|
|
|
12
13
|
test('initializes with provided values', ({ assert }) => {
|
|
13
|
-
const rule = new MatchUserPropertyAccessRule({
|
|
14
|
+
const rule = new MatchUserPropertyAccessRule(mockExposedEntity(), {
|
|
14
15
|
property: 'department',
|
|
15
16
|
value: 'engineering',
|
|
16
17
|
})
|
|
@@ -21,7 +22,7 @@ test.group('MatchUserPropertyAccessRule', () => {
|
|
|
21
22
|
}).tags(['@modeling', '@rule', '@match-user-property'])
|
|
22
23
|
|
|
23
24
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
24
|
-
const rule = new MatchUserPropertyAccessRule({
|
|
25
|
+
const rule = new MatchUserPropertyAccessRule(mockExposedEntity(), {
|
|
25
26
|
property: 'department',
|
|
26
27
|
value: 'engineering',
|
|
27
28
|
})
|
|
@@ -33,7 +34,7 @@ test.group('MatchUserPropertyAccessRule', () => {
|
|
|
33
34
|
}).tags(['@modeling', '@rule', '@match-user-property', '@serialization'])
|
|
34
35
|
|
|
35
36
|
test('notifies change when property changes', async ({ assert }) => {
|
|
36
|
-
const rule = new MatchUserPropertyAccessRule()
|
|
37
|
+
const rule = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
37
38
|
let notified = false
|
|
38
39
|
rule.addEventListener('change', () => {
|
|
39
40
|
notified = true
|
|
@@ -45,7 +46,7 @@ test.group('MatchUserPropertyAccessRule', () => {
|
|
|
45
46
|
}).tags(['@modeling', '@rule', '@match-user-property', '@observed'])
|
|
46
47
|
|
|
47
48
|
test('notifies change when value changes', async ({ assert }) => {
|
|
48
|
-
const rule = new MatchUserPropertyAccessRule()
|
|
49
|
+
const rule = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
49
50
|
let notified = false
|
|
50
51
|
rule.addEventListener('change', () => {
|
|
51
52
|
notified = true
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { test } from '@japa/runner'
|
|
2
2
|
import { MatchUserRoleAccessRule } from '../../../../src/modeling/rules/MatchUserRole.js'
|
|
3
|
+
import { mockExposedEntity } from '../actions/helpers.js'
|
|
3
4
|
|
|
4
5
|
test.group('MatchUserRoleAccessRule', () => {
|
|
5
6
|
test('initializes with default values', ({ assert }) => {
|
|
6
|
-
const rule = new MatchUserRoleAccessRule()
|
|
7
|
+
const rule = new MatchUserRoleAccessRule(mockExposedEntity())
|
|
7
8
|
assert.equal(rule.type, 'matchUserRole')
|
|
8
9
|
assert.deepEqual(rule.role, [])
|
|
9
10
|
}).tags(['@modeling', '@rule', '@match-user-role'])
|
|
10
11
|
|
|
11
12
|
test('initializes with provided values', ({ assert }) => {
|
|
12
13
|
const role = ['admin', 'manager']
|
|
13
|
-
const rule = new MatchUserRoleAccessRule({ role })
|
|
14
|
+
const rule = new MatchUserRoleAccessRule(mockExposedEntity(), { role })
|
|
14
15
|
|
|
15
16
|
assert.equal(rule.type, 'matchUserRole')
|
|
16
17
|
assert.deepEqual(rule.role, role)
|
|
@@ -18,7 +19,7 @@ test.group('MatchUserRoleAccessRule', () => {
|
|
|
18
19
|
|
|
19
20
|
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
20
21
|
const role = ['admin']
|
|
21
|
-
const rule = new MatchUserRoleAccessRule({ role })
|
|
22
|
+
const rule = new MatchUserRoleAccessRule(mockExposedEntity(), { role })
|
|
22
23
|
|
|
23
24
|
// Modify original source
|
|
24
25
|
role.push('guest')
|
|
@@ -27,7 +28,7 @@ test.group('MatchUserRoleAccessRule', () => {
|
|
|
27
28
|
}).tags(['@modeling', '@rule', '@match-user-role', '@immutability'])
|
|
28
29
|
|
|
29
30
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
30
|
-
const rule = new MatchUserRoleAccessRule({ role: ['admin'] })
|
|
31
|
+
const rule = new MatchUserRoleAccessRule(mockExposedEntity(), { role: ['admin'] })
|
|
31
32
|
const json = rule.toJSON()
|
|
32
33
|
|
|
33
34
|
// Modify JSON
|
|
@@ -39,7 +40,7 @@ test.group('MatchUserRoleAccessRule', () => {
|
|
|
39
40
|
}).tags(['@modeling', '@rule', '@match-user-role', '@serialization', '@immutability'])
|
|
40
41
|
|
|
41
42
|
test('notifies change when role changes', async ({ assert }) => {
|
|
42
|
-
const rule = new MatchUserRoleAccessRule()
|
|
43
|
+
const rule = new MatchUserRoleAccessRule(mockExposedEntity())
|
|
43
44
|
let notified = false
|
|
44
45
|
rule.addEventListener('change', () => {
|
|
45
46
|
notified = true
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from '../../../../src/modeling/index.js'
|
|
11
11
|
import { nanoid } from '../../../../src/nanoid.js'
|
|
12
12
|
import { ExposedEntityKind } from '../../../../src/models/kinds.js'
|
|
13
|
+
import { mockExposedEntity } from '../actions/helpers.js'
|
|
13
14
|
|
|
14
15
|
test.group('restoring actions', (group) => {
|
|
15
16
|
let domain: DataDomain
|
|
@@ -23,12 +24,12 @@ test.group('restoring actions', (group) => {
|
|
|
23
24
|
})
|
|
24
25
|
|
|
25
26
|
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()
|
|
27
|
+
const r1 = new AllowAuthenticatedAccessRule(mockExposedEntity())
|
|
28
|
+
const r2 = new AllowPublicAccessRule(mockExposedEntity())
|
|
29
|
+
const r3 = new MatchEmailDomainAccessRule(mockExposedEntity())
|
|
30
|
+
const r4 = new MatchResourceOwnerAccessRule(mockExposedEntity())
|
|
31
|
+
const r5 = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
32
|
+
const r6 = new MatchUserRoleAccessRule(mockExposedEntity())
|
|
32
33
|
const model = new ApiModel(
|
|
33
34
|
{
|
|
34
35
|
accessRule: [r1.toJSON(), r2.toJSON(), r3.toJSON(), r4.toJSON(), r5.toJSON(), r6.toJSON()],
|
|
@@ -46,12 +47,12 @@ test.group('restoring actions', (group) => {
|
|
|
46
47
|
}).tags(['@modeling', '@rule', '@restoring'])
|
|
47
48
|
|
|
48
49
|
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()
|
|
50
|
+
const r1 = new AllowAuthenticatedAccessRule(mockExposedEntity())
|
|
51
|
+
const r2 = new AllowPublicAccessRule(mockExposedEntity())
|
|
52
|
+
const r3 = new MatchEmailDomainAccessRule(mockExposedEntity())
|
|
53
|
+
const r4 = new MatchResourceOwnerAccessRule(mockExposedEntity())
|
|
54
|
+
const r5 = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
55
|
+
const r6 = new MatchUserRoleAccessRule(mockExposedEntity())
|
|
55
56
|
const model = new ApiModel(
|
|
56
57
|
{
|
|
57
58
|
exposes: [
|
|
@@ -82,17 +83,14 @@ test.group('restoring actions', (group) => {
|
|
|
82
83
|
}).tags(['@modeling', '@rule', '@restoring'])
|
|
83
84
|
|
|
84
85
|
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()
|
|
86
|
+
const r1 = new AllowAuthenticatedAccessRule(mockExposedEntity())
|
|
87
|
+
const r2 = new AllowPublicAccessRule(mockExposedEntity())
|
|
88
|
+
const r3 = new MatchEmailDomainAccessRule(mockExposedEntity())
|
|
89
|
+
const r4 = new MatchResourceOwnerAccessRule(mockExposedEntity())
|
|
90
|
+
const r5 = new MatchUserPropertyAccessRule(mockExposedEntity())
|
|
91
|
+
const r6 = new MatchUserRoleAccessRule(mockExposedEntity())
|
|
91
92
|
const action: ListActionSchema = {
|
|
92
93
|
kind: 'list',
|
|
93
|
-
pagination: { kind: '' },
|
|
94
|
-
sortableFields: [],
|
|
95
|
-
filterableFields: [],
|
|
96
94
|
accessRule: [r1.toJSON(), r2.toJSON(), r3.toJSON(), r4.toJSON(), r5.toJSON(), r6.toJSON()],
|
|
97
95
|
}
|
|
98
96
|
const model = new ApiModel(
|