@sphereon/ssi-sdk.data-store 0.34.1-feature.SSISDK.57.uni.client.205 → 0.34.1-feature.SSISDK.58.host.nonce.endpoint.145
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/index.cjs +174 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -32
- package/dist/index.d.ts +33 -32
- package/dist/index.js +174 -105
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/pd-manager.entities.test.ts +69 -21
- package/src/__tests__/pd-manager.store.test.ts +194 -111
- package/src/entities/presentationDefinition/{DcqlQueryItemEntity.ts → PresentationDefinitionItemEntity.ts} +12 -8
- package/src/index.ts +3 -3
- package/src/migrations/generic/{13-CreateDcqlQueryItem.ts → 13-UpdatePresentationDefinitionItemNullable.ts} +8 -8
- package/src/migrations/generic/index.ts +5 -2
- package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +1 -1
- package/src/migrations/postgres/1756975509000-UpdatePresentationDefinitionItemNullable.ts +15 -0
- package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +1 -1
- package/src/migrations/sqlite/1756975340000-UpdatePresentationDefinitionItemNullable.ts +77 -0
- package/src/presentationDefinition/AbstractPDStore.ts +5 -5
- package/src/presentationDefinition/PDStore.ts +45 -40
- package/src/types/presentationDefinition/IAbstractPDStore.ts +5 -5
- package/src/types/presentationDefinition/presentationDefinition.ts +9 -8
- package/src/utils/presentationDefinition/MappingUtils.ts +41 -21
- package/src/migrations/postgres/1726588800000-CreateDcqlQueryItem.ts +0 -25
- package/src/migrations/sqlite/1726617600000-CreateDcqlQueryItem.ts +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.data-store",
|
|
3
|
-
"version": "0.34.1-feature.SSISDK.
|
|
3
|
+
"version": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@sphereon/kmp-mdoc-core": "0.2.0-SNAPSHOT.26",
|
|
30
30
|
"@sphereon/pex": "5.0.0-unstable.28",
|
|
31
|
-
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-feature.SSISDK.
|
|
32
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.
|
|
33
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.
|
|
34
|
-
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.
|
|
35
|
-
"@sphereon/ssi-types": "0.34.1-feature.SSISDK.
|
|
31
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
32
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
33
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
34
|
+
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
35
|
+
"@sphereon/ssi-types": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
|
|
36
36
|
"@veramo/core": "4.2.0",
|
|
37
37
|
"@veramo/utils": "4.2.0",
|
|
38
38
|
"blakejs": "^1.2.1",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"PostgreSQL",
|
|
66
66
|
"Contact Store"
|
|
67
67
|
],
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "5bfc0b1229134b5d80279a3baf1fc64c9c6e755e"
|
|
69
69
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
+
import { DcqlQuery } from 'dcql'
|
|
2
3
|
import { DataSource } from 'typeorm'
|
|
3
|
-
import {
|
|
4
|
-
import { DcqlQueryItemEntity } from '../entities/presentationDefinition/DcqlQueryItemEntity'
|
|
5
|
-
import { DataStorePresentationDefinitionEntities } from '../index'
|
|
4
|
+
import { PresentationDefinitionItemEntity } from '../entities/presentationDefinition/PresentationDefinitionItemEntity'
|
|
6
5
|
import { DataStorePresentationDefinitionMigrations } from '../migrations'
|
|
7
|
-
import {
|
|
6
|
+
import { DataStorePresentationDefinitionEntities } from '../index'
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
8
|
+
import { SAMPLE_DCQL_QUERY_PAYLOAD } from './pd-manager.store.test'
|
|
8
9
|
|
|
9
|
-
describe('
|
|
10
|
+
describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
10
11
|
let dbConnection: DataSource
|
|
11
12
|
|
|
12
13
|
beforeEach(async (): Promise<void> => {
|
|
@@ -26,34 +27,34 @@ describe('DcqlQueryItemEntity tests', (): void => {
|
|
|
26
27
|
await dbConnection.destroy()
|
|
27
28
|
})
|
|
28
29
|
|
|
29
|
-
it('should create and retrieve
|
|
30
|
-
const repository = dbConnection.getRepository(
|
|
31
|
-
const entity = new
|
|
32
|
-
entity.
|
|
30
|
+
it('should create and retrieve PresentationDefinitionItemEntity with dcqlPayload', async (): Promise<void> => {
|
|
31
|
+
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
32
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
33
|
+
entity.definitionId = 'ajax-club'
|
|
33
34
|
entity.version = '1.0'
|
|
34
|
-
entity.
|
|
35
|
+
entity.dcqlPayload = JSON.stringify(SAMPLE_DCQL_QUERY_PAYLOAD.dcqlQuery)
|
|
35
36
|
|
|
36
37
|
const savedEntity = await repository.save(entity)
|
|
37
38
|
expect(savedEntity).toBeDefined()
|
|
38
39
|
expect(savedEntity.id).toBeDefined()
|
|
39
|
-
expect(savedEntity.
|
|
40
|
+
expect(savedEntity.dcqlPayload).toBeDefined()
|
|
40
41
|
|
|
41
42
|
const retrievedEntity = await repository.findOneBy({ id: savedEntity.id })
|
|
42
43
|
expect(retrievedEntity).toBeDefined()
|
|
43
|
-
expect(retrievedEntity!.
|
|
44
|
-
const parsedDcql = JSON.parse(retrievedEntity!.
|
|
44
|
+
expect(retrievedEntity!.dcqlPayload).toBeDefined()
|
|
45
|
+
const parsedDcql = JSON.parse(retrievedEntity!.dcqlPayload)
|
|
45
46
|
expect(parsedDcql.credentials[0].id).toEqual('clubcard-v1')
|
|
46
47
|
expect(parsedDcql.credentials[0].format).toEqual('dc+sd-jwt')
|
|
47
48
|
expect(parsedDcql.credentials[0].meta.vct_values).toContain('clubcard-v1')
|
|
48
49
|
expect(parsedDcql.credentials[0].claims).toHaveLength(4)
|
|
49
50
|
})
|
|
50
51
|
|
|
51
|
-
it('should update
|
|
52
|
-
const repository = dbConnection.getRepository(
|
|
53
|
-
const entity = new
|
|
54
|
-
entity.
|
|
52
|
+
it('should update PresentationDefinitionItemEntity dcqlPayload', async (): Promise<void> => {
|
|
53
|
+
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
54
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
55
|
+
entity.definitionId = 'ajax-club'
|
|
55
56
|
entity.version = '1.0'
|
|
56
|
-
entity.
|
|
57
|
+
entity.dcqlPayload = JSON.stringify(SAMPLE_DCQL_QUERY_PAYLOAD.dcqlQuery)
|
|
57
58
|
|
|
58
59
|
const savedEntity = await repository.save(entity)
|
|
59
60
|
expect(savedEntity).toBeDefined()
|
|
@@ -71,10 +72,57 @@ describe('DcqlQueryItemEntity tests', (): void => {
|
|
|
71
72
|
},
|
|
72
73
|
],
|
|
73
74
|
}
|
|
74
|
-
savedEntity.
|
|
75
|
+
savedEntity.dcqlPayload = JSON.stringify(updatedDcql)
|
|
75
76
|
const updatedEntity = await repository.save(savedEntity)
|
|
76
77
|
expect(updatedEntity).toBeDefined()
|
|
77
|
-
expect(JSON.parse(updatedEntity.
|
|
78
|
-
expect(JSON.parse(updatedEntity.
|
|
78
|
+
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].id).toEqual('updated-clubcard')
|
|
79
|
+
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].format).toEqual('jwt_vc')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should create and retrieve PresentationDefinitionItemEntity', async (): Promise<void> => {
|
|
83
|
+
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
84
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
85
|
+
entity.definitionId = 'definition1'
|
|
86
|
+
entity.version = '1.0'
|
|
87
|
+
entity.definitionPayload = JSON.stringify({ id: 'definition1', input_descriptors: [] })
|
|
88
|
+
|
|
89
|
+
const savedEntity = await repository.save(entity)
|
|
90
|
+
expect(savedEntity).toBeDefined()
|
|
91
|
+
expect(savedEntity.id).toBeDefined()
|
|
92
|
+
|
|
93
|
+
const retrievedEntity = await repository.findOneBy({ id: savedEntity.id })
|
|
94
|
+
expect(retrievedEntity).toBeDefined()
|
|
95
|
+
expect(retrievedEntity!.definitionId).toEqual('definition1')
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should update PresentationDefinitionItemEntity', async (): Promise<void> => {
|
|
99
|
+
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
100
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
101
|
+
entity.definitionId = 'definition1'
|
|
102
|
+
entity.version = '1.0'
|
|
103
|
+
entity.definitionPayload = JSON.stringify({ id: 'definition1', input_descriptors: [] })
|
|
104
|
+
|
|
105
|
+
const savedEntity = await repository.save(entity)
|
|
106
|
+
expect(savedEntity).toBeDefined()
|
|
107
|
+
|
|
108
|
+
savedEntity.version = '1.1'
|
|
109
|
+
const updatedEntity = await repository.save(savedEntity)
|
|
110
|
+
expect(updatedEntity).toBeDefined()
|
|
111
|
+
expect(updatedEntity.version).toEqual('1.1')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should delete PresentationDefinitionItemEntity', async (): Promise<void> => {
|
|
115
|
+
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
116
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
117
|
+
entity.definitionId = 'definition1'
|
|
118
|
+
entity.version = '1.0'
|
|
119
|
+
entity.definitionPayload = JSON.stringify({ id: 'definition1', input_descriptors: [] })
|
|
120
|
+
|
|
121
|
+
const savedEntity = await repository.save(entity)
|
|
122
|
+
expect(savedEntity).toBeDefined()
|
|
123
|
+
|
|
124
|
+
await repository.delete(savedEntity.id)
|
|
125
|
+
const retrievedEntity = await repository.findOneBy({ id: savedEntity.id })
|
|
126
|
+
expect(retrievedEntity).toBeNull()
|
|
79
127
|
})
|
|
80
128
|
})
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
-
import {
|
|
2
|
+
import { DcqlQueryPayload } from '@sphereon/ssi-types'
|
|
3
3
|
import { DataSource } from 'typeorm'
|
|
4
|
+
import { DataStorePresentationDefinitionEntities, DataStorePresentationDefinitionMigrations, PDStore } from '../index'
|
|
5
|
+
import { GetDefinitionsArgs, NonPersistedPresentationDefinitionItem, PresentationDefinitionItem } from '../types'
|
|
4
6
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
DataStorePresentationDefinitionMigrations,
|
|
8
|
-
type DeleteDefinitionsArgs,
|
|
9
|
-
ImportDcqlQueryItem,
|
|
10
|
-
PDStore,
|
|
11
|
-
} from '../index'
|
|
12
|
-
import { DcqlQueryItem, GetDefinitionsArgs, NonPersistedDcqlQueryItem } from '../types'
|
|
13
|
-
|
|
14
|
-
export const SAMPLE_DCQL_QUERY_IMPORT: ImportDcqlQueryItem = {
|
|
7
|
+
|
|
8
|
+
export const SAMPLE_DCQL_QUERY_PAYLOAD: DcqlQueryPayload = {
|
|
15
9
|
queryId: 'ajax-club',
|
|
16
|
-
|
|
10
|
+
dcqlQuery: {
|
|
17
11
|
credentials: [
|
|
18
12
|
{
|
|
19
13
|
id: 'clubcard-v1',
|
|
@@ -66,148 +60,237 @@ describe('PDStore tests', (): void => {
|
|
|
66
60
|
await dbConnection.destroy()
|
|
67
61
|
})
|
|
68
62
|
|
|
69
|
-
it('should
|
|
63
|
+
it('should check if definition exists', async (): Promise<void> => {
|
|
64
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
65
|
+
definitionId: 'definition1',
|
|
66
|
+
version: '1.0',
|
|
67
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
68
|
+
}
|
|
69
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
70
|
+
expect(savedDefinition).toBeDefined()
|
|
71
|
+
|
|
72
|
+
const exists: boolean = await pdStore.hasDefinition({ itemId: savedDefinition.id })
|
|
73
|
+
|
|
74
|
+
expect(exists).toBeTruthy()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('should check if definitions exist by filter', async (): Promise<void> => {
|
|
78
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
79
|
+
definitionId: 'definition1',
|
|
80
|
+
version: '1.0',
|
|
81
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
82
|
+
}
|
|
83
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
84
|
+
expect(savedDefinition).toBeDefined()
|
|
85
|
+
|
|
86
|
+
const exists: boolean = await pdStore.hasDefinitions({ filter: [{ definitionId: 'definition1' }] })
|
|
87
|
+
|
|
88
|
+
expect(exists).toBeTruthy()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should get definition by id', async (): Promise<void> => {
|
|
92
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
93
|
+
definitionId: 'definition1',
|
|
94
|
+
version: '1.0',
|
|
95
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
99
|
+
expect(savedDefinition).toBeDefined()
|
|
100
|
+
|
|
101
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
102
|
+
|
|
103
|
+
expect(result).toBeDefined()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should throw error when getting definition with unknown id', async (): Promise<void> => {
|
|
70
107
|
const itemId = 'unknownDefinitionId'
|
|
71
108
|
|
|
72
109
|
await expect(pdStore.getDefinition({ itemId })).rejects.toThrow(`No presentation definition item found for id: ${itemId}`)
|
|
73
110
|
})
|
|
74
111
|
|
|
75
|
-
it('should get all
|
|
76
|
-
const definition1:
|
|
77
|
-
|
|
112
|
+
it('should get all definitions', async (): Promise<void> => {
|
|
113
|
+
const definition1: NonPersistedPresentationDefinitionItem = {
|
|
114
|
+
definitionId: 'definition1',
|
|
78
115
|
version: '1.0',
|
|
79
|
-
|
|
80
|
-
credentials: [
|
|
81
|
-
{
|
|
82
|
-
id: 'id-card-v1',
|
|
83
|
-
format: 'dc+sd-jwt',
|
|
84
|
-
require_cryptographic_holder_binding: true,
|
|
85
|
-
multiple: false,
|
|
86
|
-
claims: [
|
|
87
|
-
{
|
|
88
|
-
path: ['name'],
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
},
|
|
116
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
94
117
|
}
|
|
95
|
-
const savedDefinition1:
|
|
118
|
+
const savedDefinition1: PresentationDefinitionItem = await pdStore.addDefinition(definition1)
|
|
96
119
|
expect(savedDefinition1).toBeDefined()
|
|
97
120
|
|
|
98
|
-
const definition2:
|
|
99
|
-
|
|
121
|
+
const definition2: NonPersistedPresentationDefinitionItem = {
|
|
122
|
+
definitionId: 'definition2',
|
|
100
123
|
version: '1.0',
|
|
101
|
-
|
|
102
|
-
credentials: [
|
|
103
|
-
{
|
|
104
|
-
id: 'driver-license-v1',
|
|
105
|
-
format: 'dc+sd-jwt',
|
|
106
|
-
require_cryptographic_holder_binding: true,
|
|
107
|
-
multiple: false,
|
|
108
|
-
claims: [
|
|
109
|
-
{
|
|
110
|
-
path: ['dateOfBirth'],
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
},
|
|
124
|
+
definitionPayload: { id: 'definition2', input_descriptors: [] },
|
|
116
125
|
}
|
|
117
|
-
const savedDefinition2:
|
|
126
|
+
const savedDefinition2: PresentationDefinitionItem = await pdStore.addDefinition(definition2)
|
|
118
127
|
expect(savedDefinition2).toBeDefined()
|
|
119
128
|
|
|
120
|
-
const result: Array<
|
|
129
|
+
const result: Array<PresentationDefinitionItem> = await pdStore.getDefinitions({})
|
|
121
130
|
|
|
122
131
|
expect(result).toBeDefined()
|
|
123
132
|
expect(result.length).toEqual(2)
|
|
124
133
|
})
|
|
125
134
|
|
|
126
|
-
it('should
|
|
127
|
-
const definition:
|
|
128
|
-
|
|
135
|
+
it('should get definitions by filter', async (): Promise<void> => {
|
|
136
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
137
|
+
definitionId: 'definition1',
|
|
129
138
|
version: '1.0',
|
|
130
|
-
|
|
139
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
131
140
|
}
|
|
132
|
-
const savedDefinition:
|
|
141
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
133
142
|
expect(savedDefinition).toBeDefined()
|
|
134
143
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
const args: GetDefinitionsArgs = {
|
|
145
|
+
filter: [{ definitionId: 'definition1' }],
|
|
146
|
+
}
|
|
147
|
+
const result: Array<PresentationDefinitionItem> = await pdStore.getDefinitions(args)
|
|
148
|
+
|
|
149
|
+
expect(result.length).toEqual(1)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should add definition', async (): Promise<void> => {
|
|
153
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
154
|
+
definitionId: 'definition1',
|
|
155
|
+
version: '1.0',
|
|
156
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const result: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
160
|
+
|
|
161
|
+
expect(result).toBeDefined()
|
|
162
|
+
expect(result.definitionId).toEqual(definition.definitionId)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('should add definition with dcqlPayload', async (): Promise<void> => {
|
|
166
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
167
|
+
definitionId: 'ajax-club',
|
|
168
|
+
version: '1.0',
|
|
169
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
170
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const result: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
174
|
+
|
|
175
|
+
expect(result).toBeDefined()
|
|
176
|
+
expect(result.definitionId).toEqual(definition.definitionId)
|
|
177
|
+
expect(result.dcqlPayload).toBeDefined()
|
|
178
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].id).toEqual('clubcard-v1')
|
|
179
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].format).toEqual('dc+sd-jwt')
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should update definition', async (): Promise<void> => {
|
|
183
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
184
|
+
definitionId: 'definition1',
|
|
185
|
+
version: '1.0',
|
|
186
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
187
|
+
}
|
|
188
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
189
|
+
expect(savedDefinition).toBeDefined()
|
|
190
|
+
|
|
191
|
+
const updatedDefinition: PresentationDefinitionItem = {
|
|
192
|
+
...savedDefinition,
|
|
193
|
+
version: '1.1',
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await pdStore.updateDefinition(updatedDefinition)
|
|
197
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
198
|
+
|
|
199
|
+
expect(result).toBeDefined()
|
|
200
|
+
expect(result.version).toEqual('1.1')
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it('should update definition with dcqlPayload', async (): Promise<void> => {
|
|
204
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
205
|
+
definitionId: 'ajax-club',
|
|
206
|
+
version: '1.0',
|
|
207
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
208
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
209
|
+
}
|
|
210
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
211
|
+
expect(savedDefinition).toBeDefined()
|
|
212
|
+
|
|
213
|
+
const updatedDcqlQueryPayload = {
|
|
214
|
+
...SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
215
|
+
dcqlQuery: {
|
|
216
|
+
credentials: [
|
|
217
|
+
{
|
|
218
|
+
id: 'updated-clubcard',
|
|
219
|
+
format: 'dc+sd-jwt',
|
|
220
|
+
claims: [
|
|
221
|
+
{
|
|
222
|
+
path: ['name'],
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
} as unknown as DcqlQueryPayload // FIXME I do not have another solution for this atm, I can do Partial<DcqlQuery> but that does not work for its child entities
|
|
148
229
|
|
|
149
|
-
const updatedDefinition:
|
|
230
|
+
const updatedDefinition: PresentationDefinitionItem = {
|
|
150
231
|
...savedDefinition,
|
|
151
232
|
version: '1.1',
|
|
152
|
-
|
|
233
|
+
dcqlPayload: updatedDcqlQueryPayload,
|
|
153
234
|
}
|
|
154
235
|
|
|
155
236
|
await pdStore.updateDefinition(updatedDefinition)
|
|
156
|
-
const result:
|
|
237
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
157
238
|
|
|
158
239
|
expect(result).toBeDefined()
|
|
159
240
|
expect(result.version).toEqual('1.1')
|
|
160
|
-
expect(result.
|
|
161
|
-
expect(result.
|
|
241
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].id).toEqual('updated-clubcard')
|
|
242
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].format).toEqual('dc+sd-jwt')
|
|
162
243
|
})
|
|
163
244
|
|
|
164
|
-
it('should get
|
|
165
|
-
const definition:
|
|
166
|
-
|
|
245
|
+
it('should get definition with dcqlPayload by id', async (): Promise<void> => {
|
|
246
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
247
|
+
definitionId: 'ajax-club',
|
|
167
248
|
version: '1.0',
|
|
168
|
-
|
|
249
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
250
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
169
251
|
}
|
|
170
252
|
|
|
171
|
-
const savedDefinition:
|
|
253
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
172
254
|
expect(savedDefinition).toBeDefined()
|
|
173
255
|
|
|
174
|
-
const result:
|
|
256
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
175
257
|
|
|
176
258
|
expect(result).toBeDefined()
|
|
177
|
-
expect(result.
|
|
178
|
-
expect(result.
|
|
179
|
-
if (result.
|
|
180
|
-
expect(result.
|
|
259
|
+
expect(result.dcqlPayload).toBeDefined()
|
|
260
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].format).toBe('dc+sd-jwt')
|
|
261
|
+
if (result.dcqlPayload?.dcqlQuery.credentials[0].format === 'dc+sd-jwt') {
|
|
262
|
+
expect(result.dcqlPayload.dcqlQuery.credentials[0].meta?.vct_values).toContain('clubcard-v1')
|
|
181
263
|
}
|
|
182
|
-
expect(result.
|
|
264
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].claims).toHaveLength(4)
|
|
183
265
|
})
|
|
184
266
|
|
|
185
|
-
it('should get
|
|
186
|
-
const definition:
|
|
187
|
-
|
|
267
|
+
it('should get definitions with dcqlPayload by filter', async (): Promise<void> => {
|
|
268
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
269
|
+
definitionId: 'ajax-club',
|
|
188
270
|
version: '1.0',
|
|
189
|
-
|
|
271
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
272
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
190
273
|
}
|
|
191
|
-
const savedDefinition:
|
|
274
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
192
275
|
expect(savedDefinition).toBeDefined()
|
|
193
276
|
|
|
194
277
|
const args: GetDefinitionsArgs = {
|
|
195
|
-
filter: [{
|
|
278
|
+
filter: [{ definitionId: 'ajax-club' }],
|
|
196
279
|
}
|
|
197
|
-
const result: Array<
|
|
280
|
+
const result: Array<PresentationDefinitionItem> = await pdStore.getDefinitions(args)
|
|
198
281
|
|
|
199
282
|
expect(result.length).toEqual(1)
|
|
200
|
-
expect(result[0].
|
|
201
|
-
expect(result[0].
|
|
283
|
+
expect(result[0].dcqlPayload).toBeDefined()
|
|
284
|
+
expect(result[0].dcqlPayload?.dcqlQuery.credentials[0].id).toEqual('clubcard-v1')
|
|
202
285
|
})
|
|
203
286
|
|
|
204
|
-
it('should delete
|
|
205
|
-
const definition:
|
|
206
|
-
|
|
287
|
+
it('should delete definition', async (): Promise<void> => {
|
|
288
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
289
|
+
definitionId: 'definition1',
|
|
207
290
|
version: '1.0',
|
|
208
|
-
|
|
291
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
209
292
|
}
|
|
210
|
-
const savedDefinition:
|
|
293
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
211
294
|
expect(savedDefinition).toBeDefined()
|
|
212
295
|
|
|
213
296
|
await pdStore.deleteDefinition({ itemId: savedDefinition.id })
|
|
@@ -217,28 +300,28 @@ describe('PDStore tests', (): void => {
|
|
|
217
300
|
)
|
|
218
301
|
})
|
|
219
302
|
|
|
220
|
-
it('should delete
|
|
221
|
-
const definition1:
|
|
222
|
-
|
|
303
|
+
it('should delete definitions by filter', async (): Promise<void> => {
|
|
304
|
+
const definition1: NonPersistedPresentationDefinitionItem = {
|
|
305
|
+
definitionId: 'definition1',
|
|
223
306
|
version: '1.0',
|
|
224
|
-
|
|
307
|
+
definitionPayload: { id: 'definition1', input_descriptors: [] },
|
|
225
308
|
}
|
|
226
|
-
const savedDefinition1:
|
|
309
|
+
const savedDefinition1: PresentationDefinitionItem = await pdStore.addDefinition(definition1)
|
|
227
310
|
expect(savedDefinition1).toBeDefined()
|
|
228
311
|
|
|
229
|
-
const definition2:
|
|
230
|
-
|
|
312
|
+
const definition2: NonPersistedPresentationDefinitionItem = {
|
|
313
|
+
definitionId: 'definition2',
|
|
231
314
|
version: '1.0',
|
|
232
|
-
|
|
315
|
+
definitionPayload: { id: 'definition2', input_descriptors: [] },
|
|
233
316
|
}
|
|
234
|
-
const savedDefinition2:
|
|
317
|
+
const savedDefinition2: PresentationDefinitionItem = await pdStore.addDefinition(definition2)
|
|
235
318
|
expect(savedDefinition2).toBeDefined()
|
|
236
319
|
|
|
237
|
-
const filter = { filter: [{
|
|
320
|
+
const filter = { filter: [{ definitionId: 'definition1' }] }
|
|
238
321
|
await pdStore.deleteDefinitions(filter)
|
|
239
322
|
|
|
240
|
-
const remainingDefinitions: Array<
|
|
323
|
+
const remainingDefinitions: Array<PresentationDefinitionItem> = await pdStore.getDefinitions({})
|
|
241
324
|
expect(remainingDefinitions.length).toEqual(1)
|
|
242
|
-
expect(remainingDefinitions[0].
|
|
325
|
+
expect(remainingDefinitions[0].definitionId).toEqual('definition2')
|
|
243
326
|
})
|
|
244
327
|
})
|
|
@@ -2,15 +2,15 @@ import { BaseEntity, BeforeInsert, BeforeUpdate, Column, CreateDateColumn, Entit
|
|
|
2
2
|
import { IsNotEmpty } from 'class-validator'
|
|
3
3
|
import { typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
|
|
4
4
|
|
|
5
|
-
@Entity('
|
|
5
|
+
@Entity('PresentationDefinitionItem')
|
|
6
6
|
@Index(['version'], { unique: false })
|
|
7
|
-
export class
|
|
7
|
+
export class PresentationDefinitionItemEntity extends BaseEntity {
|
|
8
8
|
@PrimaryGeneratedColumn('uuid')
|
|
9
9
|
id!: string
|
|
10
10
|
|
|
11
|
-
@Column({ name: '
|
|
12
|
-
@IsNotEmpty({ message: 'A blank
|
|
13
|
-
|
|
11
|
+
@Column({ name: 'definition_id', length: 255, type: 'varchar', nullable: false, unique: false })
|
|
12
|
+
@IsNotEmpty({ message: 'A blank definition id field is not allowed' })
|
|
13
|
+
definitionId!: string
|
|
14
14
|
|
|
15
15
|
@Column({ name: 'version', length: 255, type: 'varchar', nullable: false, unique: false })
|
|
16
16
|
@IsNotEmpty({ message: 'A blank version field is not allowed' })
|
|
@@ -25,9 +25,13 @@ export class DcqlQueryItemEntity extends BaseEntity {
|
|
|
25
25
|
@Column({ name: 'name', length: 255, type: 'varchar', nullable: true, unique: false })
|
|
26
26
|
name?: string
|
|
27
27
|
|
|
28
|
-
@Column({ name: '
|
|
29
|
-
@IsNotEmpty({ message: 'A blank
|
|
30
|
-
|
|
28
|
+
@Column({ name: 'definition_payload', type: 'text', nullable: true, unique: false })
|
|
29
|
+
@IsNotEmpty({ message: 'A blank PD definition payload field is not allowed' })
|
|
30
|
+
definitionPayload!: string
|
|
31
|
+
|
|
32
|
+
@Column({ name: 'dcql_payload', type: 'text', nullable: true, unique: false })
|
|
33
|
+
@IsNotEmpty({ message: 'A blank dcql definition payload field is not allowed' })
|
|
34
|
+
dcqlPayload!: string
|
|
31
35
|
|
|
32
36
|
@CreateDateColumn({ name: 'created_at', nullable: false, type: typeOrmDateTime() })
|
|
33
37
|
createdAt!: Date
|
package/src/index.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { ElectronicAddressEntity } from './entities/contact/ElectronicAddressEnt
|
|
|
29
29
|
import { PhysicalAddressEntity } from './entities/contact/PhysicalAddressEntity'
|
|
30
30
|
import { AuditEventEntity } from './entities/eventLogger/AuditEventEntity'
|
|
31
31
|
import { DigitalCredentialEntity } from './entities/digitalCredential/DigitalCredentialEntity'
|
|
32
|
-
import {
|
|
32
|
+
import { PresentationDefinitionItemEntity } from './entities/presentationDefinition/PresentationDefinitionItemEntity'
|
|
33
33
|
import { ContactMetadataItemEntity } from './entities/contact/ContactMetadataItemEntity'
|
|
34
34
|
import { CredentialClaimsEntity } from './entities/issuanceBranding/CredentialClaimsEntity'
|
|
35
35
|
|
|
@@ -99,7 +99,7 @@ export const DataStoreIssuanceBrandingEntities = [
|
|
|
99
99
|
CredentialClaimsEntity,
|
|
100
100
|
]
|
|
101
101
|
|
|
102
|
-
export const DataStorePresentationDefinitionEntities = [
|
|
102
|
+
export const DataStorePresentationDefinitionEntities = [PresentationDefinitionItemEntity]
|
|
103
103
|
|
|
104
104
|
export const DataStoreStatusListEntities = [
|
|
105
105
|
StatusListEntity,
|
|
@@ -158,7 +158,7 @@ export {
|
|
|
158
158
|
AuditEventEntity,
|
|
159
159
|
DigitalCredentialEntity,
|
|
160
160
|
MachineStateInfoEntity,
|
|
161
|
-
|
|
161
|
+
PresentationDefinitionItemEntity,
|
|
162
162
|
ContactMetadataItemEntity,
|
|
163
163
|
CredentialClaimsEntity,
|
|
164
164
|
Oid4vcStateEntity,
|