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