@sphereon/ssi-sdk.data-store 0.34.1-fix.114 → 0.34.1-fix.141
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 +1606 -1399
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +160 -166
- package/dist/index.d.ts +160 -166
- package/dist/index.js +1562 -1355
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/contact.entities.test.ts +2 -2
- package/src/__tests__/contact.store.test.ts +1 -1
- package/src/__tests__/digitalCredential.entities.test.ts +2 -1
- package/src/__tests__/digitalCredential.store.test.ts +5 -5
- package/src/__tests__/pd-manager.entities.test.ts +14 -37
- package/src/__tests__/pd-manager.store.test.ts +133 -0
- package/src/digitalCredential/DigitalCredentialStore.ts +9 -9
- package/src/entities/contact/IdentityEntity.ts +2 -1
- package/src/entities/digitalCredential/DigitalCredentialEntity.ts +2 -1
- package/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +1 -1
- package/src/migrations/generic/12-CreateBitstringStatusList.ts +32 -2
- package/src/migrations/generic/13-UpdatePresentationDefinitionItemNullable.ts +67 -0
- package/src/migrations/generic/index.ts +13 -5
- package/src/migrations/postgres/1741895823000-CreateBitstringStatusList.ts +13 -2
- package/src/migrations/postgres/1756975509000-UpdatePresentationDefinitionItemNullable.ts +15 -0
- package/src/migrations/sqlite/1756975340000-UpdatePresentationDefinitionItemNullable.ts +77 -0
- package/src/presentationDefinition/PDStore.ts +6 -1
- package/src/types/contact/contact.ts +1 -1
- package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +2 -1
- package/src/types/digitalCredential/enums.ts +0 -7
- package/src/types/digitalCredential/types.ts +2 -1
- package/src/types/presentationDefinition/presentationDefinition.ts +3 -3
- package/src/utils/presentationDefinition/MappingUtils.ts +39 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.data-store",
|
|
3
|
-
"version": "0.34.1-fix.
|
|
3
|
+
"version": "0.34.1-fix.141+ea643e42",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -28,16 +28,16 @@
|
|
|
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-fix.
|
|
32
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-fix.
|
|
33
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-fix.
|
|
34
|
-
"@sphereon/ssi-sdk.core": "0.34.1-fix.
|
|
35
|
-
"@sphereon/ssi-types": "0.34.1-fix.
|
|
31
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-fix.141+ea643e42",
|
|
32
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-fix.141+ea643e42",
|
|
33
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-fix.141+ea643e42",
|
|
34
|
+
"@sphereon/ssi-sdk.core": "0.34.1-fix.141+ea643e42",
|
|
35
|
+
"@sphereon/ssi-types": "0.34.1-fix.141+ea643e42",
|
|
36
36
|
"@veramo/core": "4.2.0",
|
|
37
37
|
"@veramo/utils": "4.2.0",
|
|
38
38
|
"blakejs": "^1.2.1",
|
|
39
39
|
"class-validator": "0.14.1",
|
|
40
|
-
"dcql": "0.
|
|
40
|
+
"dcql": "1.0.1",
|
|
41
41
|
"debug": "^4.3.5",
|
|
42
42
|
"typeorm": "0.3.20"
|
|
43
43
|
},
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"PostgreSQL",
|
|
66
66
|
"Contact Store"
|
|
67
67
|
],
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "ea643e42804501f2a323a73971465d527981123d"
|
|
69
69
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getDID } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
2
2
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
3
|
+
import { CredentialRole } from '@sphereon/ssi-types'
|
|
3
4
|
import { DataSource, FindOptionsWhere } from 'typeorm'
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
4
6
|
import { BaseContactEntity } from '../entities/contact/BaseContactEntity'
|
|
5
7
|
import { ConnectionEntity } from '../entities/contact/ConnectionEntity'
|
|
6
8
|
import { ContactMetadataItemEntity } from '../entities/contact/ContactMetadataItemEntity'
|
|
@@ -18,7 +20,6 @@ import { PartyTypeEntity } from '../entities/contact/PartyTypeEntity'
|
|
|
18
20
|
import { PhysicalAddressEntity } from '../entities/contact/PhysicalAddressEntity'
|
|
19
21
|
import {
|
|
20
22
|
contactMetadataItemEntityFrom,
|
|
21
|
-
CredentialRole,
|
|
22
23
|
DataStoreContactEntities,
|
|
23
24
|
DataStoreMigrations,
|
|
24
25
|
identityMetadataItemEntityFrom,
|
|
@@ -57,7 +58,6 @@ import {
|
|
|
57
58
|
partyTypeEntityFrom,
|
|
58
59
|
physicalAddressEntityFrom,
|
|
59
60
|
} from '../utils/contact/MappingUtils'
|
|
60
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
61
61
|
// TODO write test adding two contacts reusing the same contactType
|
|
62
62
|
|
|
63
63
|
describe('Database entities tests', (): void => {
|
|
@@ -4,7 +4,6 @@ import { ConnectionType, DataStoreContactEntities, DataStoreMigrations, Identity
|
|
|
4
4
|
import { ContactStore } from '../contact/ContactStore'
|
|
5
5
|
import {
|
|
6
6
|
CorrelationIdentifierType,
|
|
7
|
-
CredentialRole,
|
|
8
7
|
ElectronicAddress,
|
|
9
8
|
GetElectronicAddressesArgs,
|
|
10
9
|
GetIdentitiesArgs,
|
|
@@ -27,6 +26,7 @@ import {
|
|
|
27
26
|
PhysicalAddress,
|
|
28
27
|
} from '../types'
|
|
29
28
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
29
|
+
import { CredentialRole } from "@sphereon/ssi-types"
|
|
30
30
|
|
|
31
31
|
describe('Contact store tests', (): void => {
|
|
32
32
|
let dbConnection: DataSource
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
+
import { CredentialRole } from '@sphereon/ssi-types'
|
|
2
3
|
import { DataSource } from 'typeorm'
|
|
3
|
-
import {
|
|
4
|
+
import { DataStoreDigitalCredentialEntities } from '../index'
|
|
4
5
|
import { DataStoreDigitalCredentialMigrations } from '../migrations'
|
|
5
6
|
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
6
7
|
import { computeEntryHash } from '@veramo/utils'
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
-
import {
|
|
2
|
+
import { defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
3
|
+
import { CredentialRole, IVerifiablePresentation } from '@sphereon/ssi-types'
|
|
3
4
|
import { DataSource } from 'typeorm'
|
|
4
|
-
import {
|
|
5
|
-
import { CredentialRole, DataStoreDigitalCredentialEntities } from '../index'
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
6
6
|
import { DigitalCredentialStore } from '../digitalCredential/DigitalCredentialStore'
|
|
7
|
+
import { DataStoreDigitalCredentialEntities } from '../index'
|
|
8
|
+
import { DataStoreDigitalCredentialMigrations } from '../migrations'
|
|
7
9
|
import {
|
|
8
10
|
AddCredentialArgs,
|
|
9
11
|
CredentialCorrelationType,
|
|
@@ -14,8 +16,6 @@ import {
|
|
|
14
16
|
GetCredentialsArgs,
|
|
15
17
|
GetCredentialsResponse,
|
|
16
18
|
} from '../types'
|
|
17
|
-
import { defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
18
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
19
19
|
|
|
20
20
|
describe('Database entities tests', (): void => {
|
|
21
21
|
let dbConnection: DataSource
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
+
import { DcqlQuery } from 'dcql'
|
|
2
3
|
import { DataSource } from 'typeorm'
|
|
3
4
|
import { PresentationDefinitionItemEntity } from '../entities/presentationDefinition/PresentationDefinitionItemEntity'
|
|
4
5
|
import { DataStorePresentationDefinitionMigrations } from '../migrations'
|
|
5
6
|
import { DataStorePresentationDefinitionEntities } from '../index'
|
|
6
7
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
8
|
+
import { SAMPLE_DCQL_QUERY_PAYLOAD } from './pd-manager.store.test'
|
|
7
9
|
|
|
8
10
|
describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
9
11
|
let dbConnection: DataSource
|
|
@@ -28,23 +30,9 @@ describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
|
28
30
|
it('should create and retrieve PresentationDefinitionItemEntity with dcqlPayload', async (): Promise<void> => {
|
|
29
31
|
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
30
32
|
const entity = new PresentationDefinitionItemEntity()
|
|
31
|
-
entity.definitionId = '
|
|
33
|
+
entity.definitionId = 'ajax-club'
|
|
32
34
|
entity.version = '1.0'
|
|
33
|
-
entity.
|
|
34
|
-
entity.dcqlPayload = JSON.stringify({
|
|
35
|
-
credentials: [
|
|
36
|
-
{
|
|
37
|
-
id: 'credential1',
|
|
38
|
-
format: 'jwt_vc',
|
|
39
|
-
claims: [
|
|
40
|
-
{
|
|
41
|
-
namespace: 'test',
|
|
42
|
-
claim_name: 'testClaim',
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
})
|
|
35
|
+
entity.dcqlPayload = JSON.stringify(SAMPLE_DCQL_QUERY_PAYLOAD.dcqlQuery)
|
|
48
36
|
|
|
49
37
|
const savedEntity = await repository.save(entity)
|
|
50
38
|
expect(savedEntity).toBeDefined()
|
|
@@ -55,29 +43,18 @@ describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
|
55
43
|
expect(retrievedEntity).toBeDefined()
|
|
56
44
|
expect(retrievedEntity!.dcqlPayload).toBeDefined()
|
|
57
45
|
const parsedDcql = JSON.parse(retrievedEntity!.dcqlPayload)
|
|
58
|
-
expect(parsedDcql.credentials[0].id).toEqual('
|
|
46
|
+
expect(parsedDcql.credentials[0].id).toEqual('clubcard-v1')
|
|
47
|
+
expect(parsedDcql.credentials[0].format).toEqual('dc+sd-jwt')
|
|
48
|
+
expect(parsedDcql.credentials[0].meta.vct_values).toContain('clubcard-v1')
|
|
49
|
+
expect(parsedDcql.credentials[0].claims).toHaveLength(4)
|
|
59
50
|
})
|
|
60
51
|
|
|
61
52
|
it('should update PresentationDefinitionItemEntity dcqlPayload', async (): Promise<void> => {
|
|
62
53
|
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
|
|
63
54
|
const entity = new PresentationDefinitionItemEntity()
|
|
64
|
-
entity.definitionId = '
|
|
55
|
+
entity.definitionId = 'ajax-club'
|
|
65
56
|
entity.version = '1.0'
|
|
66
|
-
entity.
|
|
67
|
-
entity.dcqlPayload = JSON.stringify({
|
|
68
|
-
credentials: [
|
|
69
|
-
{
|
|
70
|
-
id: 'credential1',
|
|
71
|
-
format: 'jwt_vc',
|
|
72
|
-
claims: [
|
|
73
|
-
{
|
|
74
|
-
namespace: 'test',
|
|
75
|
-
claim_name: 'testClaim',
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
})
|
|
57
|
+
entity.dcqlPayload = JSON.stringify(SAMPLE_DCQL_QUERY_PAYLOAD.dcqlQuery)
|
|
81
58
|
|
|
82
59
|
const savedEntity = await repository.save(entity)
|
|
83
60
|
expect(savedEntity).toBeDefined()
|
|
@@ -85,12 +62,11 @@ describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
|
85
62
|
const updatedDcql = {
|
|
86
63
|
credentials: [
|
|
87
64
|
{
|
|
88
|
-
id: '
|
|
65
|
+
id: 'updated-clubcard',
|
|
89
66
|
format: 'jwt_vc',
|
|
90
67
|
claims: [
|
|
91
68
|
{
|
|
92
|
-
|
|
93
|
-
claim_name: 'updatedClaim',
|
|
69
|
+
path: ['name'],
|
|
94
70
|
},
|
|
95
71
|
],
|
|
96
72
|
},
|
|
@@ -99,7 +75,8 @@ describe('PresentationDefinitionItemEntity tests', (): void => {
|
|
|
99
75
|
savedEntity.dcqlPayload = JSON.stringify(updatedDcql)
|
|
100
76
|
const updatedEntity = await repository.save(savedEntity)
|
|
101
77
|
expect(updatedEntity).toBeDefined()
|
|
102
|
-
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].id).toEqual('
|
|
78
|
+
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].id).toEqual('updated-clubcard')
|
|
79
|
+
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].format).toEqual('jwt_vc')
|
|
103
80
|
})
|
|
104
81
|
|
|
105
82
|
it('should create and retrieve PresentationDefinitionItemEntity', async (): Promise<void> => {
|
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
+
import { DcqlQueryPayload } from '@sphereon/ssi-types'
|
|
2
3
|
import { DataSource } from 'typeorm'
|
|
3
4
|
import { DataStorePresentationDefinitionEntities, DataStorePresentationDefinitionMigrations, PDStore } from '../index'
|
|
4
5
|
import { GetDefinitionsArgs, NonPersistedPresentationDefinitionItem, PresentationDefinitionItem } from '../types'
|
|
5
6
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
6
7
|
|
|
8
|
+
export const SAMPLE_DCQL_QUERY_PAYLOAD: DcqlQueryPayload = {
|
|
9
|
+
queryId: 'ajax-club',
|
|
10
|
+
dcqlQuery: {
|
|
11
|
+
credentials: [
|
|
12
|
+
{
|
|
13
|
+
id: 'clubcard-v1',
|
|
14
|
+
format: 'dc+sd-jwt',
|
|
15
|
+
require_cryptographic_holder_binding: true,
|
|
16
|
+
multiple: false,
|
|
17
|
+
meta: {
|
|
18
|
+
vct_values: ['clubcard-v1'],
|
|
19
|
+
},
|
|
20
|
+
claims: [
|
|
21
|
+
{
|
|
22
|
+
path: ['personData', 'name'],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
path: ['personData', 'birthDate'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
path: ['membershipData', 'membershipId'],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
path: ['membershipData', 'season'],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
7
39
|
describe('PDStore tests', (): void => {
|
|
8
40
|
let dbConnection: DataSource
|
|
9
41
|
let pdStore: PDStore
|
|
@@ -130,6 +162,23 @@ describe('PDStore tests', (): void => {
|
|
|
130
162
|
expect(result.definitionId).toEqual(definition.definitionId)
|
|
131
163
|
})
|
|
132
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
|
+
|
|
133
182
|
it('should update definition', async (): Promise<void> => {
|
|
134
183
|
const definition: NonPersistedPresentationDefinitionItem = {
|
|
135
184
|
definitionId: 'definition1',
|
|
@@ -151,6 +200,90 @@ describe('PDStore tests', (): void => {
|
|
|
151
200
|
expect(result.version).toEqual('1.1')
|
|
152
201
|
})
|
|
153
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
|
|
229
|
+
|
|
230
|
+
const updatedDefinition: PresentationDefinitionItem = {
|
|
231
|
+
...savedDefinition,
|
|
232
|
+
version: '1.1',
|
|
233
|
+
dcqlPayload: updatedDcqlQueryPayload,
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
await pdStore.updateDefinition(updatedDefinition)
|
|
237
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
238
|
+
|
|
239
|
+
expect(result).toBeDefined()
|
|
240
|
+
expect(result.version).toEqual('1.1')
|
|
241
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].id).toEqual('updated-clubcard')
|
|
242
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].format).toEqual('dc+sd-jwt')
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
it('should get definition with dcqlPayload by id', async (): Promise<void> => {
|
|
246
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
247
|
+
definitionId: 'ajax-club',
|
|
248
|
+
version: '1.0',
|
|
249
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
250
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
254
|
+
expect(savedDefinition).toBeDefined()
|
|
255
|
+
|
|
256
|
+
const result: PresentationDefinitionItem = await pdStore.getDefinition({ itemId: savedDefinition.id })
|
|
257
|
+
|
|
258
|
+
expect(result).toBeDefined()
|
|
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')
|
|
263
|
+
}
|
|
264
|
+
expect(result.dcqlPayload?.dcqlQuery.credentials[0].claims).toHaveLength(4)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('should get definitions with dcqlPayload by filter', async (): Promise<void> => {
|
|
268
|
+
const definition: NonPersistedPresentationDefinitionItem = {
|
|
269
|
+
definitionId: 'ajax-club',
|
|
270
|
+
version: '1.0',
|
|
271
|
+
definitionPayload: { id: 'ajax-club', input_descriptors: [] },
|
|
272
|
+
dcqlPayload: SAMPLE_DCQL_QUERY_PAYLOAD,
|
|
273
|
+
}
|
|
274
|
+
const savedDefinition: PresentationDefinitionItem = await pdStore.addDefinition(definition)
|
|
275
|
+
expect(savedDefinition).toBeDefined()
|
|
276
|
+
|
|
277
|
+
const args: GetDefinitionsArgs = {
|
|
278
|
+
filter: [{ definitionId: 'ajax-club' }],
|
|
279
|
+
}
|
|
280
|
+
const result: Array<PresentationDefinitionItem> = await pdStore.getDefinitions(args)
|
|
281
|
+
|
|
282
|
+
expect(result.length).toEqual(1)
|
|
283
|
+
expect(result[0].dcqlPayload).toBeDefined()
|
|
284
|
+
expect(result[0].dcqlPayload?.dcqlQuery.credentials[0].id).toEqual('clubcard-v1')
|
|
285
|
+
})
|
|
286
|
+
|
|
154
287
|
it('should delete definition', async (): Promise<void> => {
|
|
155
288
|
const definition: NonPersistedPresentationDefinitionItem = {
|
|
156
289
|
definitionId: 'definition1',
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CredentialRole, OrPromise } from '@sphereon/ssi-types'
|
|
2
|
+
import Debug from 'debug'
|
|
3
|
+
import { DataSource, type FindOptionsOrder, type FindOptionsWhere, Repository } from 'typeorm'
|
|
4
|
+
|
|
5
|
+
import { digitalCredentialFrom, digitalCredentialsFrom, nonPersistedDigitalCredentialEntityFromAddArgs } from '../../src'
|
|
6
|
+
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
2
7
|
import {
|
|
3
8
|
AddCredentialArgs,
|
|
4
|
-
CredentialRole,
|
|
5
9
|
CredentialStateType,
|
|
6
10
|
DigitalCredential,
|
|
7
11
|
GetCredentialArgs,
|
|
@@ -11,14 +15,10 @@ import {
|
|
|
11
15
|
RemoveCredentialArgs,
|
|
12
16
|
UpdateCredentialStateArgs,
|
|
13
17
|
} from '../types'
|
|
14
|
-
import { OrPromise } from '@sphereon/ssi-types'
|
|
15
|
-
import { DataSource, type FindOptionsOrder, type FindOptionsWhere, Repository } from 'typeorm'
|
|
16
|
-
import Debug from 'debug'
|
|
17
|
-
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
18
|
-
|
|
19
|
-
import { digitalCredentialFrom, digitalCredentialsFrom, nonPersistedDigitalCredentialEntityFromAddArgs } from '../../src'
|
|
20
18
|
import { parseAndValidateOrderOptions } from '../utils/SortingUtils'
|
|
21
19
|
|
|
20
|
+
import { AbstractDigitalCredentialStore } from './AbstractDigitalCredentialStore'
|
|
21
|
+
|
|
22
22
|
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:credential-store')
|
|
23
23
|
|
|
24
24
|
export class DigitalCredentialStore extends AbstractDigitalCredentialStore {
|
|
@@ -78,7 +78,7 @@ export class DigitalCredentialStore extends AbstractDigitalCredentialStore {
|
|
|
78
78
|
return false
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
const query: FindOptionsWhere<DigitalCredentialEntity> = {}
|
|
82
82
|
|
|
83
83
|
if ('id' in args) {
|
|
84
84
|
query.id = args.id
|
|
@@ -17,7 +17,8 @@ import { typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
|
|
|
17
17
|
import { CorrelationIdentifierEntity } from './CorrelationIdentifierEntity'
|
|
18
18
|
import { ConnectionEntity } from './ConnectionEntity'
|
|
19
19
|
import { IdentityMetadataItemEntity } from './IdentityMetadataItemEntity'
|
|
20
|
-
import {
|
|
20
|
+
import { IdentityOrigin, ValidationConstraint } from '../../types'
|
|
21
|
+
import { CredentialRole } from '@sphereon/ssi-types'
|
|
21
22
|
import { PartyEntity } from './PartyEntity'
|
|
22
23
|
import { getConstraint } from '../../utils/ValidatorUtils'
|
|
23
24
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { typeormDate, typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
|
|
2
|
+
import { CredentialRole } from '@sphereon/ssi-types'
|
|
2
3
|
import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
|
|
4
|
+
|
|
3
5
|
import {
|
|
4
6
|
CredentialCorrelationType,
|
|
5
7
|
CredentialDocumentFormat,
|
|
6
|
-
CredentialRole,
|
|
7
8
|
CredentialStateType,
|
|
8
9
|
type DigitalCredential,
|
|
9
10
|
DocumentType,
|
|
@@ -25,7 +25,7 @@ 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: 'definition_payload', type: 'text', nullable:
|
|
28
|
+
@Column({ name: 'definition_payload', type: 'text', nullable: true, unique: false })
|
|
29
29
|
@IsNotEmpty({ message: 'A blank PD definition payload field is not allowed' })
|
|
30
30
|
definitionPayload!: string
|
|
31
31
|
|
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
1
|
import Debug from 'debug'
|
|
3
|
-
import {
|
|
2
|
+
import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AddBitstringStatusListEnumPG1741895823000,
|
|
6
|
+
CreateBitstringStatusListPG1741895823000,
|
|
7
|
+
} from '../postgres/1741895823000-CreateBitstringStatusList'
|
|
4
8
|
import { CreateBitstringStatusListSqlite1741895823001 } from '../sqlite/1741895823001-CreateBitstringStatusList'
|
|
5
9
|
|
|
6
10
|
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')
|
|
7
11
|
|
|
12
|
+
export class AddBitstringStatusListEnum1741895823000 implements MigrationInterface {
|
|
13
|
+
name = 'AddBitstringStatusListEnum1741895823000'
|
|
14
|
+
|
|
15
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
16
|
+
debug('migration: creating bitstring status list tables')
|
|
17
|
+
const dbType: DatabaseType = queryRunner.connection.driver.options.type
|
|
18
|
+
switch (dbType) {
|
|
19
|
+
case 'postgres': {
|
|
20
|
+
const mig = new AddBitstringStatusListEnumPG1741895823000()
|
|
21
|
+
await mig.up(queryRunner)
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
case 'sqlite':
|
|
25
|
+
case 'expo':
|
|
26
|
+
case 'react-native': {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
default:
|
|
30
|
+
return Promise.reject(`Migrations only supported for sqlite and postgres. Was ${dbType}`)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
35
|
+
public async down(queryRunner: QueryRunner): Promise<void> {}
|
|
36
|
+
}
|
|
37
|
+
|
|
8
38
|
export class CreateBitstringStatusList1741895823000 implements MigrationInterface {
|
|
9
39
|
name = 'CreateBitstringStatusList1741895823000'
|
|
10
40
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Debug from 'debug'
|
|
2
|
+
import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
|
|
3
|
+
|
|
4
|
+
import { UpdatePresentationDefinitionItemNullablePG1741895824000 } from '../postgres/1756975509000-UpdatePresentationDefinitionItemNullable'
|
|
5
|
+
import { UpdatePresentationDefinitionItemNullableSqlite1756975340000 } from '../sqlite/1756975340000-UpdatePresentationDefinitionItemNullable'
|
|
6
|
+
|
|
7
|
+
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')
|
|
8
|
+
|
|
9
|
+
export class UpdatePresentationDefinitionItemNullable1741895824000 implements MigrationInterface {
|
|
10
|
+
name = 'UpdatePresentationDefinitionItemNullable1741895824000'
|
|
11
|
+
|
|
12
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
debug('migration: updating presentation definition item nullable fields')
|
|
14
|
+
const dbType: DatabaseType = queryRunner.connection.driver.options.type
|
|
15
|
+
|
|
16
|
+
switch (dbType) {
|
|
17
|
+
case 'postgres': {
|
|
18
|
+
debug('using postgres migration file')
|
|
19
|
+
const mig: UpdatePresentationDefinitionItemNullablePG1741895824000 = new UpdatePresentationDefinitionItemNullablePG1741895824000()
|
|
20
|
+
await mig.up(queryRunner)
|
|
21
|
+
debug('Migration statements executed')
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
case 'sqlite':
|
|
25
|
+
case 'expo':
|
|
26
|
+
case 'react-native': {
|
|
27
|
+
debug('using sqlite/react-native migration file')
|
|
28
|
+
const mig: UpdatePresentationDefinitionItemNullableSqlite1756975340000 = new UpdatePresentationDefinitionItemNullableSqlite1756975340000()
|
|
29
|
+
await mig.up(queryRunner)
|
|
30
|
+
debug('Migration statements executed')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
default:
|
|
34
|
+
return Promise.reject(
|
|
35
|
+
`Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now`,
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
41
|
+
debug('migration: reverting presentation definition item nullable fields')
|
|
42
|
+
const dbType: DatabaseType = queryRunner.connection.driver.options.type
|
|
43
|
+
|
|
44
|
+
switch (dbType) {
|
|
45
|
+
case 'postgres': {
|
|
46
|
+
debug('using postgres migration file')
|
|
47
|
+
const mig: UpdatePresentationDefinitionItemNullablePG1741895824000 = new UpdatePresentationDefinitionItemNullablePG1741895824000()
|
|
48
|
+
await mig.down(queryRunner)
|
|
49
|
+
debug('Migration statements executed')
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
case 'sqlite':
|
|
53
|
+
case 'expo':
|
|
54
|
+
case 'react-native': {
|
|
55
|
+
debug('using sqlite/react-native migration file')
|
|
56
|
+
const mig: UpdatePresentationDefinitionItemNullableSqlite1756975340000 = new UpdatePresentationDefinitionItemNullableSqlite1756975340000()
|
|
57
|
+
await mig.down(queryRunner)
|
|
58
|
+
debug('Migration statements executed')
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
default:
|
|
62
|
+
return Promise.reject(
|
|
63
|
+
`Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now`,
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { CreateContacts1659463079429 } from './1-CreateContacts'
|
|
2
|
+
import { CreatePresentationDefinitions1716533767523 } from './10-CreatePresentationDefinitions'
|
|
3
|
+
import { FixCredentialClaimsReferencesUuid1741895822987 } from './11-FixCredentialClaimsReferenceUuid'
|
|
4
|
+
import { AddBitstringStatusListEnum1741895823000, CreateBitstringStatusList1741895823000 } from './12-CreateBitstringStatusList'
|
|
5
|
+
import { UpdatePresentationDefinitionItemNullable1741895824000 } from './13-UpdatePresentationDefinitionItemNullable'
|
|
2
6
|
import { CreateIssuanceBranding1659463079429 } from './2-CreateIssuanceBranding'
|
|
3
7
|
import { CreateContacts1690925872318 } from './3-CreateContacts'
|
|
4
8
|
import { CreateStatusList1693866470000 } from './4-CreateStatusList'
|
|
@@ -7,9 +11,6 @@ import { CreateDigitalCredential1708525189000 } from './6-CreateDigitalCredentia
|
|
|
7
11
|
import { CreateMachineStateStore1708098041262 } from './7-CreateMachineStateStore'
|
|
8
12
|
import { CreateContacts1708525189000 } from './8-CreateContacts'
|
|
9
13
|
import { CreateContacts1715761125000 } from './9-CreateContacts'
|
|
10
|
-
import { CreatePresentationDefinitions1716533767523 } from './10-CreatePresentationDefinitions'
|
|
11
|
-
import { FixCredentialClaimsReferencesUuid1741895822987 } from './11-FixCredentialClaimsReferenceUuid'
|
|
12
|
-
import { CreateBitstringStatusList1741895823000 } from './12-CreateBitstringStatusList'
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* The migrations array that SHOULD be used when initializing a TypeORM database connection.
|
|
@@ -27,11 +28,18 @@ export const DataStoreContactMigrations = [
|
|
|
27
28
|
CreateContacts1715761125000,
|
|
28
29
|
]
|
|
29
30
|
export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429, FixCredentialClaimsReferencesUuid1741895822987]
|
|
30
|
-
export const DataStoreStatusListMigrations = [
|
|
31
|
+
export const DataStoreStatusListMigrations = [
|
|
32
|
+
CreateStatusList1693866470000,
|
|
33
|
+
AddBitstringStatusListEnum1741895823000,
|
|
34
|
+
CreateBitstringStatusList1741895823000,
|
|
35
|
+
]
|
|
31
36
|
export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330]
|
|
32
37
|
export const DataStoreDigitalCredentialMigrations = [CreateDigitalCredential1708525189000]
|
|
33
38
|
export const DataStoreMachineStateMigrations = [CreateMachineStateStore1708098041262]
|
|
34
|
-
export const DataStorePresentationDefinitionMigrations = [
|
|
39
|
+
export const DataStorePresentationDefinitionMigrations = [
|
|
40
|
+
CreatePresentationDefinitions1716533767523,
|
|
41
|
+
UpdatePresentationDefinitionItemNullable1741895824000,
|
|
42
|
+
]
|
|
35
43
|
|
|
36
44
|
// All migrations together
|
|
37
45
|
export const DataStoreMigrations = [
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
2
|
|
|
3
|
-
export class
|
|
4
|
-
name = '
|
|
3
|
+
export class AddBitstringStatusListEnumPG1741895823000 implements MigrationInterface {
|
|
4
|
+
name = 'AddBitstringStatusListEnum1741895823000'
|
|
5
5
|
|
|
6
6
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
7
|
await queryRunner.startTransaction()
|
|
8
8
|
await queryRunner.query(`ALTER TYPE "StatusList_type_enum" ADD VALUE 'BitstringStatusList'`)
|
|
9
9
|
await queryRunner.commitTransaction()
|
|
10
|
+
}
|
|
10
11
|
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
14
|
+
// Note: Cannot remove enum value in Postgres without recreating the type
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class CreateBitstringStatusListPG1741895823000 implements MigrationInterface {
|
|
19
|
+
name = 'CreateBitstringStatusList1741895823000'
|
|
20
|
+
|
|
21
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
11
22
|
// Add BitstringStatusList columns to StatusList table
|
|
12
23
|
await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "ttl" integer`)
|
|
13
24
|
await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "validFrom" TIMESTAMP`)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
export class UpdatePresentationDefinitionItemNullablePG1741895824000 implements MigrationInterface {
|
|
4
|
+
name = 'UpdatePresentationDefinitionItemNullable1741895824000'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
// Make definition_payload nullable
|
|
8
|
+
await queryRunner.query(`ALTER TABLE "PresentationDefinitionItem" ALTER COLUMN "definition_payload" DROP NOT NULL`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
12
|
+
// Make definition_payload NOT NULL again
|
|
13
|
+
await queryRunner.query(`ALTER TABLE "PresentationDefinitionItem" ALTER COLUMN "definition_payload" SET NOT NULL`)
|
|
14
|
+
}
|
|
15
|
+
}
|