@sphereon/ssi-sdk.data-store 0.32.1-next.54 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/entities/issuanceBranding/CredentialLocaleBrandingEntity.js +1 -1
  2. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts +13 -0
  3. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts.map +1 -0
  4. package/dist/entities/oid4vcState/Oid4vcStateEntity.js +57 -0
  5. package/dist/entities/oid4vcState/Oid4vcStateEntity.js.map +1 -0
  6. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.d.ts +1 -0
  7. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.d.ts.map +1 -1
  8. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.js +8 -2
  9. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.js.map +1 -1
  10. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.d.ts +4 -3
  11. package/dist/entities/statusList/StatusList2021EntryEntity.d.ts.map +1 -0
  12. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.js +11 -6
  13. package/dist/entities/statusList/StatusList2021EntryEntity.js.map +1 -0
  14. package/dist/entities/statusList/StatusListEntities.d.ts +23 -0
  15. package/dist/entities/statusList/StatusListEntities.d.ts.map +1 -0
  16. package/dist/entities/{statusList2021/StatusList2021Entity.js → statusList/StatusListEntities.js} +45 -16
  17. package/dist/entities/statusList/StatusListEntities.js.map +1 -0
  18. package/dist/index.d.ts +5 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +10 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.d.ts +7 -0
  23. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.d.ts.map +1 -0
  24. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.js +80 -0
  25. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.js.map +1 -0
  26. package/dist/migrations/generic/4-CreateStatusList.d.ts.map +1 -1
  27. package/dist/migrations/generic/4-CreateStatusList.js +22 -12
  28. package/dist/migrations/generic/4-CreateStatusList.js.map +1 -1
  29. package/dist/migrations/generic/index.d.ts.map +1 -1
  30. package/dist/migrations/generic/index.js +2 -1
  31. package/dist/migrations/generic/index.js.map +1 -1
  32. package/dist/migrations/postgres/1693866470001-CreateStatusList.d.ts.map +1 -1
  33. package/dist/migrations/postgres/1693866470001-CreateStatusList.js +40 -7
  34. package/dist/migrations/postgres/1693866470001-CreateStatusList.js.map +1 -1
  35. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.d.ts.map +1 -1
  36. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js +1 -0
  37. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js.map +1 -1
  38. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts +7 -0
  39. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts.map +1 -0
  40. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js +39 -0
  41. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js.map +1 -0
  42. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.d.ts +7 -0
  43. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.d.ts.map +1 -0
  44. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.js +37 -0
  45. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.js.map +1 -0
  46. package/dist/migrations/sqlite/1693866470000-CreateStatusList.d.ts.map +1 -1
  47. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js +45 -5
  48. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js.map +1 -1
  49. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.d.ts.map +1 -1
  50. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js +1 -0
  51. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js.map +1 -1
  52. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts +7 -0
  53. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts.map +1 -0
  54. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js +96 -0
  55. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js.map +1 -0
  56. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.d.ts +7 -0
  57. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.d.ts.map +1 -0
  58. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.js +80 -0
  59. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.js.map +1 -0
  60. package/dist/statusList/IStatusListStore.d.ts +2 -2
  61. package/dist/statusList/IStatusListStore.d.ts.map +1 -1
  62. package/dist/statusList/StatusListStore.d.ts +9 -8
  63. package/dist/statusList/StatusListStore.d.ts.map +1 -1
  64. package/dist/statusList/StatusListStore.js +72 -42
  65. package/dist/statusList/StatusListStore.js.map +1 -1
  66. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts +2 -2
  67. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts.map +1 -1
  68. package/dist/types/presentationDefinition/presentationDefinition.d.ts +3 -1
  69. package/dist/types/presentationDefinition/presentationDefinition.d.ts.map +1 -1
  70. package/dist/types/statusList/IAbstractStatusListStore.d.ts +5 -4
  71. package/dist/types/statusList/IAbstractStatusListStore.d.ts.map +1 -1
  72. package/dist/types/statusList/statusList.d.ts +13 -7
  73. package/dist/types/statusList/statusList.d.ts.map +1 -1
  74. package/dist/utils/digitalCredential/MappingUtils.d.ts.map +1 -1
  75. package/dist/utils/digitalCredential/MappingUtils.js +7 -6
  76. package/dist/utils/digitalCredential/MappingUtils.js.map +1 -1
  77. package/dist/utils/presentationDefinition/MappingUtils.d.ts.map +1 -1
  78. package/dist/utils/presentationDefinition/MappingUtils.js +2 -0
  79. package/dist/utils/presentationDefinition/MappingUtils.js.map +1 -1
  80. package/dist/utils/statusList/MappingUtils.d.ts +5 -0
  81. package/dist/utils/statusList/MappingUtils.d.ts.map +1 -0
  82. package/dist/utils/statusList/MappingUtils.js +69 -0
  83. package/dist/utils/statusList/MappingUtils.js.map +1 -0
  84. package/package.json +9 -8
  85. package/src/__tests__/digitalCredential.entities.test.ts +2 -2
  86. package/src/__tests__/digitalCredential.store.test.ts +2 -2
  87. package/src/__tests__/pd-manager.entities.test.ts +77 -0
  88. package/src/__tests__/statusList.entities.test.ts +216 -0
  89. package/src/__tests__/statusList.store.test.ts +232 -0
  90. package/src/entities/issuanceBranding/CredentialLocaleBrandingEntity.ts +1 -1
  91. package/src/entities/oid4vcState/Oid4vcStateEntity.ts +32 -0
  92. package/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +6 -2
  93. package/src/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.ts +10 -6
  94. package/src/entities/{statusList2021/StatusList2021Entity.ts → statusList/StatusListEntities.ts} +38 -18
  95. package/src/index.ts +8 -3
  96. package/src/migrations/generic/11-FixCredentialClaimsReferenceUuid.ts +66 -0
  97. package/src/migrations/generic/4-CreateStatusList.ts +22 -12
  98. package/src/migrations/generic/index.ts +2 -1
  99. package/src/migrations/postgres/1693866470001-CreateStatusList.ts +42 -9
  100. package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +1 -0
  101. package/src/migrations/postgres/1737110469001-UpdateStatusList.ts +25 -0
  102. package/src/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.ts +21 -0
  103. package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +45 -5
  104. package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +1 -0
  105. package/src/migrations/sqlite/1737110469000-UpdateStatusList.ts +94 -0
  106. package/src/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.ts +73 -0
  107. package/src/statusList/IStatusListStore.ts +2 -2
  108. package/src/statusList/StatusListStore.ts +94 -51
  109. package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +2 -2
  110. package/src/types/presentationDefinition/presentationDefinition.ts +3 -1
  111. package/src/types/statusList/IAbstractStatusListStore.ts +5 -4
  112. package/src/types/statusList/statusList.ts +24 -16
  113. package/src/utils/digitalCredential/MappingUtils.ts +3 -2
  114. package/src/utils/presentationDefinition/MappingUtils.ts +3 -0
  115. package/src/utils/statusList/MappingUtils.ts +82 -0
  116. package/dist/entities/statusList2021/StatusList2021Entity.d.ts +0 -19
  117. package/dist/entities/statusList2021/StatusList2021Entity.d.ts.map +0 -1
  118. package/dist/entities/statusList2021/StatusList2021Entity.js.map +0 -1
  119. package/dist/entities/statusList2021/StatusList2021EntryEntity.d.ts.map +0 -1
  120. package/dist/entities/statusList2021/StatusList2021EntryEntity.js.map +0 -1
@@ -0,0 +1,232 @@
1
+ import { DataSource } from 'typeorm'
2
+ import { DataSources } from '@sphereon/ssi-sdk.agent-config'
3
+ import { DataStoreStatusListEntities } from '../index'
4
+ import { DataStoreStatusListMigrations } from '../migrations'
5
+ import { StatusListStore } from '../statusList/StatusListStore'
6
+ import { IStatusList2021Entity, IStatusListEntryEntity, IOAuthStatusListEntity } from '../types'
7
+ import { StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'
8
+
9
+ describe('Status list store tests', () => {
10
+ let dbConnection: DataSource
11
+ let statusListStore: StatusListStore
12
+
13
+ beforeEach(async () => {
14
+ DataSources.singleInstance().defaultDbType = 'sqlite'
15
+ dbConnection = await new DataSource({
16
+ type: 'sqlite',
17
+ database: ':memory:',
18
+ migrationsRun: false,
19
+ migrations: DataStoreStatusListMigrations,
20
+ synchronize: false,
21
+ entities: DataStoreStatusListEntities,
22
+ }).initialize()
23
+ await dbConnection.runMigrations()
24
+ expect(await dbConnection.showMigrations()).toBeFalsy()
25
+ statusListStore = new StatusListStore(dbConnection)
26
+ })
27
+
28
+ afterEach(async () => {
29
+ await dbConnection.destroy()
30
+ })
31
+
32
+ it('should store status list', async () => {
33
+ const statusList: IStatusList2021Entity = {
34
+ id: 'test-list-1',
35
+ correlationId: 'correlation-1',
36
+ driverType: StatusListDriverType.AGENT_TYPEORM,
37
+ length: 100000,
38
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
39
+ type: StatusListType.StatusList2021,
40
+ proofFormat: 'jwt',
41
+ statusPurpose: 'revocation',
42
+ indexingDirection: 'rightToLeft',
43
+ issuer: 'did:example:123',
44
+ }
45
+
46
+ const result = await statusListStore.addStatusList(statusList)
47
+ expect(result).toBeDefined()
48
+ expect(result.id).toEqual(statusList.id)
49
+ expect(result.correlationId).toEqual(statusList.correlationId)
50
+ })
51
+
52
+ it('should store status list entry', async () => {
53
+ const statusList: IStatusList2021Entity = {
54
+ id: 'test-list-1',
55
+ correlationId: 'correlation-1',
56
+ driverType: StatusListDriverType.AGENT_TYPEORM,
57
+ length: 100000,
58
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
59
+ type: StatusListType.StatusList2021,
60
+ proofFormat: 'jwt',
61
+ statusPurpose: 'revocation',
62
+ indexingDirection: 'rightToLeft',
63
+ issuer: 'did:example:123',
64
+ }
65
+
66
+ await statusListStore.addStatusList(statusList)
67
+
68
+ const entry: IStatusListEntryEntity = {
69
+ statusListId: statusList.id,
70
+ statusListIndex: 1,
71
+ credentialId: 'credential-1',
72
+ credentialHash: 'hash-1',
73
+ correlationId: 'correlation-1',
74
+ value: '1',
75
+ }
76
+
77
+ const result = await statusListStore.addStatusListEntry(entry)
78
+ expect(result).toBeDefined()
79
+ expect(result.statusListIndex).toEqual(entry.statusListIndex)
80
+ expect(result.credentialId).toEqual(entry.credentialId)
81
+ })
82
+
83
+ it('should store OAuth status list', async () => {
84
+ const statusList: IOAuthStatusListEntity = {
85
+ id: 'oauth-list-1',
86
+ correlationId: 'correlation-oauth-1',
87
+ driverType: StatusListDriverType.AGENT_TYPEORM,
88
+ length: 100000,
89
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
90
+ type: StatusListType.OAuthStatusList,
91
+ proofFormat: 'jwt',
92
+ bitsPerStatus: 1,
93
+ expiresAt: new Date('2025-01-01T00:00:00Z'),
94
+ issuer: 'did:example:123',
95
+ }
96
+
97
+ const result = (await statusListStore.addStatusList(statusList)) as IOAuthStatusListEntity
98
+ expect(result).toBeDefined()
99
+ expect(result.id).toEqual(statusList.id)
100
+ expect(result.correlationId).toEqual(statusList.correlationId)
101
+ expect(result.bitsPerStatus).toEqual(statusList.bitsPerStatus)
102
+ expect(result.expiresAt).toEqual(statusList.expiresAt)
103
+ })
104
+
105
+ it('should store and retrieve both types of status lists', async () => {
106
+ const statusList2021: IStatusList2021Entity = {
107
+ id: 'test-list-1',
108
+ correlationId: 'correlation-1',
109
+ driverType: StatusListDriverType.AGENT_TYPEORM,
110
+ length: 100000,
111
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
112
+ type: StatusListType.StatusList2021,
113
+ proofFormat: 'jwt',
114
+ statusPurpose: 'revocation',
115
+ indexingDirection: 'rightToLeft',
116
+ issuer: 'did:example:123',
117
+ }
118
+
119
+ const oauthStatusList: IOAuthStatusListEntity = {
120
+ id: 'oauth-list-1',
121
+ correlationId: 'correlation-oauth-1',
122
+ driverType: StatusListDriverType.AGENT_TYPEORM,
123
+ length: 100000,
124
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
125
+ type: StatusListType.OAuthStatusList,
126
+ proofFormat: 'jwt',
127
+ bitsPerStatus: 1,
128
+ issuer: 'did:example:456',
129
+ }
130
+
131
+ await statusListStore.addStatusList(statusList2021)
132
+ await statusListStore.addStatusList(oauthStatusList)
133
+
134
+ const found2021 = (await statusListStore.getStatusList({ id: statusList2021.id })) as IStatusList2021Entity
135
+ const foundOAuth = (await statusListStore.getStatusList({ id: oauthStatusList.id })) as IOAuthStatusListEntity
136
+
137
+ expect(found2021.type).toEqual(StatusListType.StatusList2021)
138
+ expect(found2021.statusPurpose).toEqual('revocation')
139
+ expect(foundOAuth.type).toEqual(StatusListType.OAuthStatusList)
140
+ expect((foundOAuth as IOAuthStatusListEntity).bitsPerStatus).toEqual(1)
141
+ })
142
+
143
+ it('should get status list by id', async () => {
144
+ const statusList: IStatusList2021Entity = {
145
+ id: 'test-list-1',
146
+ correlationId: 'correlation-1',
147
+ driverType: StatusListDriverType.AGENT_TYPEORM,
148
+ length: 100000,
149
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
150
+ type: StatusListType.StatusList2021,
151
+ proofFormat: 'jwt',
152
+ statusPurpose: 'revocation',
153
+ indexingDirection: 'rightToLeft',
154
+ issuer: 'did:example:123',
155
+ }
156
+
157
+ await statusListStore.addStatusList(statusList)
158
+
159
+ const result = await statusListStore.getStatusList({ id: statusList.id })
160
+ expect(result).toBeDefined()
161
+ expect(result.id).toEqual(statusList.id)
162
+ })
163
+
164
+ it('should get status lists with filter', async () => {
165
+ const statusList1: IStatusList2021Entity = {
166
+ id: 'test-list-1',
167
+ correlationId: 'correlation-1',
168
+ driverType: StatusListDriverType.AGENT_TYPEORM,
169
+ length: 100000,
170
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
171
+ type: StatusListType.StatusList2021,
172
+ proofFormat: 'jwt',
173
+ statusPurpose: 'revocation',
174
+ indexingDirection: 'rightToLeft',
175
+ issuer: 'did:example:123',
176
+ }
177
+
178
+ const statusList2: IStatusList2021Entity = {
179
+ id: 'test-list-2',
180
+ correlationId: 'correlation-2',
181
+ driverType: StatusListDriverType.AGENT_TYPEORM,
182
+ length: 100000,
183
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
184
+ type: StatusListType.StatusList2021,
185
+ proofFormat: 'jwt',
186
+ statusPurpose: 'suspension',
187
+ indexingDirection: 'rightToLeft',
188
+ issuer: 'did:example:456',
189
+ }
190
+
191
+ await statusListStore.addStatusList(statusList1)
192
+ await statusListStore.addStatusList(statusList2)
193
+
194
+ const result = await statusListStore.getStatusLists({
195
+ filter: [{ statusPurpose: 'revocation' }],
196
+ })
197
+
198
+ expect(result.length).toEqual(1)
199
+ expect(result[0].id).toEqual(statusList1.id)
200
+ })
201
+
202
+ it('should delete status list', async () => {
203
+ const statusList: IStatusList2021Entity = {
204
+ id: 'test-list-1',
205
+ correlationId: 'correlation-1',
206
+ driverType: StatusListDriverType.AGENT_TYPEORM,
207
+ length: 100000,
208
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
209
+ type: StatusListType.StatusList2021,
210
+ proofFormat: 'jwt',
211
+ statusPurpose: 'revocation',
212
+ indexingDirection: 'rightToLeft',
213
+ issuer: 'did:example:123',
214
+ }
215
+
216
+ await statusListStore.addStatusList(statusList)
217
+ const entry: IStatusListEntryEntity = {
218
+ statusListId: statusList.id,
219
+ statusListIndex: 1,
220
+ credentialId: 'credential-1',
221
+ credentialHash: 'hash-1',
222
+ correlationId: 'correlation-1',
223
+ value: '1',
224
+ }
225
+ await statusListStore.addStatusListEntry(entry)
226
+
227
+ const result = await statusListStore.removeStatusList({ id: statusList.id })
228
+ expect(result).toEqual(true)
229
+
230
+ await expect(statusListStore.getStatusList({ id: statusList.id })).rejects.toThrow(`No status list found for id ${statusList.id}`)
231
+ })
232
+ })
@@ -21,6 +21,6 @@ export class CredentialLocaleBrandingEntity extends BaseLocaleBrandingEntity {
21
21
  @JoinColumn({ name: 'claim_id' })
22
22
  claims!: Array<CredentialClaimsEntity>
23
23
 
24
- @Column('text', { name: 'credentialBrandingId', nullable: false })
24
+ @Column('uuid', { name: 'credentialBrandingId', nullable: false })
25
25
  credentialBrandingId!: string
26
26
  }
@@ -0,0 +1,32 @@
1
+ import { typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
2
+ import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm'
3
+
4
+ @Entity('Oid4vcStateEntity')
5
+ export class Oid4vcStateEntity<StateType> extends BaseEntity {
6
+ @PrimaryColumn({ name: 'id', type: 'varchar', nullable: false })
7
+ id!: string
8
+
9
+ @Column({ name: 'lookup_ids', type: 'array', nullable: true })
10
+ lookups?: Array<string>
11
+
12
+ @Column({ name: 'state_id', type: 'varchar', nullable: true })
13
+ stateId?: string
14
+
15
+ @Column({ name: 'correlation_id', type: 'varchar', nullable: true })
16
+ correlationId?: string
17
+
18
+ @Column({ name: 'state', type: 'json', nullable: false })
19
+ state!: StateType
20
+
21
+ @CreateDateColumn({ name: 'created_at', nullable: false, type: typeOrmDateTime() })
22
+ createdAt!: Date
23
+
24
+ @UpdateDateColumn({ name: 'updated_at', nullable: false, type: typeOrmDateTime() })
25
+ updatedAt!: Date
26
+
27
+ @Column({ name: 'expires_at', nullable: true, type: typeOrmDateTime() })
28
+ expiresAt?: Date
29
+
30
+ @Column({ name: 'tenant_id', type: 'varchar', nullable: true })
31
+ tenantId?: string
32
+ }
@@ -25,10 +25,14 @@ 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: false, unique: false })
29
- @IsNotEmpty({ message: 'A blank definition payload field is not allowed' })
28
+ @Column({ name: 'definition_payload', type: 'text', nullable: false, unique: false }) // TODO should this become nullable now we have dcqlPayload?
29
+ @IsNotEmpty({ message: 'A blank PD definition payload field is not allowed' })
30
30
  definitionPayload!: string
31
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
35
+
32
36
  @CreateDateColumn({ name: 'created_at', nullable: false, type: typeOrmDateTime() })
33
37
  createdAt!: Date
34
38
 
@@ -1,20 +1,24 @@
1
1
  import { Validate } from 'class-validator'
2
- import { BaseEntity, Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm'
2
+ import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'
3
3
  import { IsNonEmptyStringConstraint } from '../validators'
4
- import { StatusListEntity } from './StatusList2021Entity'
4
+ import { StatusListEntity } from './StatusListEntities'
5
5
 
6
6
  @Entity('StatusListEntry')
7
7
  // @Unique('uq_credential_statuslist', ['statusList', 'credentialId']) // disabled because one prop can be null
8
8
  // @Unique('uq_credentialHash_statuslistId', ['statusList', 'credentialHash']) // disabled because one prop can be null
9
9
  export class StatusListEntryEntity extends BaseEntity {
10
- @PrimaryColumn({ name: 'statusListId', type: 'varchar' })
11
- @ManyToOne(() => StatusListEntity, (statusList) => statusList.statusListEntries)
12
- statusList!: StatusListEntity
10
+ @PrimaryColumn({ name: 'statusListId', type: 'varchar', nullable: false, unique: false })
11
+ @Validate(IsNonEmptyStringConstraint, { message: 'Status list id is required' })
12
+ statusListId!: string
13
13
 
14
14
  @PrimaryColumn({ name: 'statusListIndex', type: 'integer', nullable: false, unique: false })
15
15
  @Validate(IsNonEmptyStringConstraint, { message: 'Status list index is required' })
16
16
  statusListIndex!: number
17
17
 
18
+ @ManyToOne(() => StatusListEntity, (statusList) => statusList.statusListEntries)
19
+ @JoinColumn({ name: 'statusListId' })
20
+ statusList!: StatusListEntity
21
+
18
22
  @Column({ name: 'credentialId', type: 'text', nullable: true })
19
23
  credentialId?: string
20
24
 
@@ -22,7 +26,7 @@ export class StatusListEntryEntity extends BaseEntity {
22
26
  credentialHash?: string
23
27
 
24
28
  @Column({ name: 'correlationId', length: 255, type: 'varchar', nullable: true, unique: false })
25
- correlationId?: string
29
+ entryCorrelationId?: string
26
30
 
27
31
  @Column({ name: 'value', length: 50, type: 'varchar', nullable: true, unique: false })
28
32
  value?: string
@@ -1,20 +1,21 @@
1
1
  import {
2
2
  IIssuer,
3
- JwtDecodedVerifiableCredential,
3
+ StatusListCredential,
4
4
  StatusListCredentialIdMode,
5
5
  StatusListDriverType,
6
6
  StatusListIndexingDirection,
7
7
  StatusListType,
8
8
  StatusPurpose2021,
9
- W3CVerifiableCredential,
9
+ ProofFormat,
10
10
  } from '@sphereon/ssi-types'
11
- import { ProofFormat } from '@veramo/core'
12
- import { BaseEntity, Column, Entity, OneToMany, PrimaryColumn, Unique } from 'typeorm'
11
+ import { BaseEntity, ChildEntity, Column, Entity, OneToMany, PrimaryColumn, TableInheritance, Unique } from 'typeorm'
13
12
  import { StatusListEntryEntity } from './StatusList2021EntryEntity'
13
+ import { typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
14
14
 
15
15
  @Entity('StatusList')
16
16
  @Unique('UQ_correlationId', ['correlationId'])
17
- export class StatusListEntity extends BaseEntity {
17
+ @TableInheritance({ column: { type: 'simple-enum', name: 'type', enum: StatusListType } })
18
+ export abstract class StatusListEntity extends BaseEntity {
18
19
  @PrimaryColumn({ name: 'id', type: 'varchar' })
19
20
  id!: string
20
21
 
@@ -46,10 +47,12 @@ export class StatusListEntity extends BaseEntity {
46
47
  })
47
48
  issuer!: string | IIssuer
48
49
 
49
- @Column('simple-enum', { name: 'type', enum: StatusListType, nullable: false, default: StatusListType.StatusList2021 })
50
- type!: StatusListType
51
-
52
- @Column('simple-enum', { name: 'driverType', enum: StatusListDriverType, nullable: false, default: StatusListDriverType.AGENT_TYPEORM })
50
+ @Column('simple-enum', {
51
+ name: 'driverType',
52
+ enum: StatusListDriverType,
53
+ nullable: false,
54
+ default: StatusListDriverType.AGENT_TYPEORM,
55
+ })
53
56
  driverType!: StatusListDriverType
54
57
 
55
58
  @Column('simple-enum', {
@@ -63,25 +66,19 @@ export class StatusListEntity extends BaseEntity {
63
66
  @Column({ type: 'varchar', name: 'proofFormat', enum: ['lds', 'jwt'], nullable: false, default: 'lds' })
64
67
  proofFormat!: ProofFormat
65
68
 
66
- @Column({ type: 'varchar', name: 'indexingDirection', enum: ['rightToLeft'], nullable: false, default: 'rightToLeft' })
67
- indexingDirection!: StatusListIndexingDirection
68
-
69
- @Column({ type: 'varchar', name: 'statusPurpose', nullable: false, default: 'revocation' })
70
- statusPurpose!: StatusPurpose2021
71
-
72
69
  @Column({
73
70
  name: 'statusListCredential',
74
71
  type: 'text',
75
72
  nullable: true,
76
73
  unique: false,
77
74
  transformer: {
78
- from(value: string): W3CVerifiableCredential | JwtDecodedVerifiableCredential {
75
+ from(value: string): StatusListCredential {
79
76
  if (value?.startsWith('ey')) {
80
77
  return value
81
78
  }
82
79
  return JSON.parse(value)
83
80
  },
84
- to(value: W3CVerifiableCredential | JwtDecodedVerifiableCredential): string {
81
+ to(value: StatusListCredential): string {
85
82
  if (typeof value === 'string') {
86
83
  return value
87
84
  }
@@ -89,8 +86,31 @@ export class StatusListEntity extends BaseEntity {
89
86
  },
90
87
  },
91
88
  })
92
- statusListCredential?: W3CVerifiableCredential | JwtDecodedVerifiableCredential
89
+ statusListCredential?: StatusListCredential
93
90
 
94
91
  @OneToMany((type) => StatusListEntryEntity, (entry) => entry.statusList)
95
92
  statusListEntries!: StatusListEntryEntity[]
96
93
  }
94
+
95
+ @ChildEntity(StatusListType.StatusList2021)
96
+ export class StatusList2021Entity extends StatusListEntity {
97
+ @Column({
98
+ type: 'varchar',
99
+ name: 'indexingDirection',
100
+ enum: ['rightToLeft'],
101
+ nullable: false,
102
+ default: 'rightToLeft',
103
+ })
104
+ indexingDirection!: StatusListIndexingDirection
105
+
106
+ @Column({ type: 'varchar', name: 'statusPurpose', nullable: false, default: 'revocation' })
107
+ statusPurpose!: StatusPurpose2021
108
+ }
109
+
110
+ @ChildEntity(StatusListType.OAuthStatusList)
111
+ export class OAuthStatusListEntity extends StatusListEntity {
112
+ @Column({ type: 'integer', name: 'bitsPerStatus', nullable: false })
113
+ bitsPerStatus!: number
114
+ @Column({ name: 'expiresAt', nullable: true, type: typeOrmDateTime() })
115
+ expiresAt?: Date
116
+ }
package/src/index.ts CHANGED
@@ -16,8 +16,8 @@ import { ImageDimensionsEntity } from './entities/issuanceBranding/ImageDimensio
16
16
  import { IssuerLocaleBrandingEntity } from './entities/issuanceBranding/IssuerLocaleBrandingEntity'
17
17
  import { IssuerBrandingEntity } from './entities/issuanceBranding/IssuerBrandingEntity'
18
18
  import { TextAttributesEntity } from './entities/issuanceBranding/TextAttributesEntity'
19
- import { StatusListEntity } from './entities/statusList2021/StatusList2021Entity'
20
- import { StatusListEntryEntity } from './entities/statusList2021/StatusList2021EntryEntity'
19
+ import { OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from './entities/statusList/StatusListEntities'
20
+ import { StatusListEntryEntity } from './entities/statusList/StatusList2021EntryEntity'
21
21
  import { MachineStateInfoEntity } from './entities/machineState/MachineStateInfoEntity'
22
22
  import { IStatusListEntity, IStatusListEntryEntity } from './types'
23
23
  import { PartyRelationshipEntity } from './entities/contact/PartyRelationshipEntity'
@@ -32,6 +32,8 @@ import { PresentationDefinitionItemEntity } from './entities/presentationDefinit
32
32
  import { ContactMetadataItemEntity } from './entities/contact/ContactMetadataItemEntity'
33
33
  import { CredentialClaimsEntity } from './entities/issuanceBranding/CredentialClaimsEntity'
34
34
 
35
+ import { Oid4vcStateEntity } from './entities/oid4vcState/Oid4vcStateEntity'
36
+
35
37
  export { ContactStore } from './contact/ContactStore'
36
38
  export { AbstractContactStore } from './contact/AbstractContactStore'
37
39
  export { AbstractDigitalCredentialStore } from './digitalCredential/AbstractDigitalCredentialStore'
@@ -81,6 +83,7 @@ export const DataStoreContactEntities = [
81
83
  ContactMetadataItemEntity,
82
84
  ]
83
85
 
86
+ export const DataStoreOid4vcStateEntities = [Oid4vcStateEntity]
84
87
  export const DataStoreIssuanceBrandingEntities = [
85
88
  BackgroundAttributesEntity,
86
89
  CredentialBrandingEntity,
@@ -96,7 +99,7 @@ export const DataStoreIssuanceBrandingEntities = [
96
99
 
97
100
  export const DataStorePresentationDefinitionEntities = [PresentationDefinitionItemEntity]
98
101
 
99
- export const DataStoreStatusListEntities = [StatusListEntity, StatusListEntryEntity]
102
+ export const DataStoreStatusListEntities = [StatusListEntity, StatusList2021Entity, OAuthStatusListEntity, StatusListEntryEntity]
100
103
 
101
104
  export const DataStoreEventLoggerEntities = [AuditEventEntity]
102
105
 
@@ -113,6 +116,7 @@ export const DataStoreEntities = [
113
116
  ...DataStoreDigitalCredentialEntities,
114
117
  ...DataStoreMachineStateEntities,
115
118
  ...DataStorePresentationDefinitionEntities,
119
+ // ...DataStoreOid4vcStateEntities,
116
120
  ]
117
121
 
118
122
  export {
@@ -146,4 +150,5 @@ export {
146
150
  PresentationDefinitionItemEntity,
147
151
  ContactMetadataItemEntity,
148
152
  CredentialClaimsEntity,
153
+ Oid4vcStateEntity,
149
154
  }
@@ -0,0 +1,66 @@
1
+ import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
2
+ import Debug from 'debug'
3
+ import { CreateIssuanceBranding1685628974232 } from '../postgres/1685628974232-CreateIssuanceBranding'
4
+ import { CreateIssuanceBranding1685628973231 } from '../sqlite/1685628973231-CreateIssuanceBranding'
5
+ import { FixCredentialClaimsReferencesUuidPG1741895822987 } from '../postgres/1741895822987-FixCredentialClaimsReferencesUuid'
6
+ import { FixCredentialClaimsReferencesUuidSqlite1741895822987 } from '../sqlite/1741895822987-FixCredentialClaimsReferencesUuid'
7
+
8
+ const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')
9
+
10
+ export class FixCredentialClaimsReferencesUuid1741895822987 implements MigrationInterface {
11
+ name = 'FixCredentialClaimsReferenceUuid1741895822987'
12
+
13
+ public async up(queryRunner: QueryRunner): Promise<void> {
14
+ debug('migration: creating issuance branding uuid problem')
15
+ const dbType: DatabaseType = queryRunner.connection.driver.options.type
16
+ switch (dbType) {
17
+ case 'postgres': {
18
+ debug('using postgres migration file')
19
+ const mig: FixCredentialClaimsReferencesUuidPG1741895822987 = new FixCredentialClaimsReferencesUuidPG1741895822987()
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: FixCredentialClaimsReferencesUuidSqlite1741895822987 = new FixCredentialClaimsReferencesUuidSqlite1741895822987()
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 issuance branding uuid migration')
42
+ const dbType: DatabaseType = queryRunner.connection.driver.options.type
43
+ switch (dbType) {
44
+ case 'postgres': {
45
+ debug('using postgres migration file')
46
+ const mig: CreateIssuanceBranding1685628974232 = new CreateIssuanceBranding1685628974232()
47
+ await mig.down(queryRunner)
48
+ debug('Migration statements executed')
49
+ return
50
+ }
51
+ case 'sqlite':
52
+ case 'expo':
53
+ case 'react-native': {
54
+ debug('using sqlite/react-native migration file')
55
+ const mig: CreateIssuanceBranding1685628973231 = new CreateIssuanceBranding1685628973231()
56
+ await mig.down(queryRunner)
57
+ debug('Migration statements executed')
58
+ return
59
+ }
60
+ default:
61
+ return Promise.reject(
62
+ `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`,
63
+ )
64
+ }
65
+ }
66
+ }
@@ -2,6 +2,8 @@ import Debug from 'debug'
2
2
  import { MigrationInterface, QueryRunner } from 'typeorm'
3
3
  import { CreateStatusList1693866470001 } from '../postgres/1693866470001-CreateStatusList'
4
4
  import { CreateStatusList1693866470002 } from '../sqlite/1693866470000-CreateStatusList'
5
+ import { UpdateStatusList1737110469001 } from '../postgres/1737110469001-UpdateStatusList'
6
+ import { UpdateStatusList1737110469000 } from '../sqlite/1737110469000-UpdateStatusList'
5
7
 
6
8
  const debug = Debug('sphereon:ssi-sdk:migrations')
7
9
 
@@ -12,15 +14,19 @@ export class CreateStatusList1693866470000 implements MigrationInterface {
12
14
  debug('migration: creating issuance branding tables')
13
15
  const dbType = queryRunner.connection.driver.options.type
14
16
  if (dbType === 'postgres') {
15
- debug('using postgres migration file')
16
- const mig = new CreateStatusList1693866470001()
17
- const up = await mig.up(queryRunner)
17
+ debug('using postgres migration files')
18
+ const createMig = new CreateStatusList1693866470001()
19
+ await createMig.up(queryRunner)
20
+ const updateMig = new UpdateStatusList1737110469001()
21
+ const up = await updateMig.up(queryRunner)
18
22
  debug('Migration statements executed')
19
23
  return up
20
24
  } else if (dbType === 'sqlite' || dbType === 'react-native' || dbType === 'expo') {
21
- debug('using sqlite/react-native migration file')
22
- const mig = new CreateStatusList1693866470002()
23
- const up = await mig.up(queryRunner)
25
+ debug('using sqlite/react-native migration files')
26
+ const createMig = new CreateStatusList1693866470002()
27
+ await createMig.up(queryRunner)
28
+ const updateMig = new UpdateStatusList1737110469000()
29
+ const up = await updateMig.up(queryRunner)
24
30
  debug('Migration statements executed')
25
31
  return up
26
32
  } else {
@@ -34,15 +40,19 @@ export class CreateStatusList1693866470000 implements MigrationInterface {
34
40
  debug('migration: reverting issuance branding tables')
35
41
  const dbType = queryRunner.connection.driver.options.type
36
42
  if (dbType === 'postgres') {
37
- debug('using postgres migration file')
38
- const mig = new CreateStatusList1693866470002()
39
- const down = await mig.down(queryRunner)
43
+ debug('using postgres migration files')
44
+ const updateMig = new UpdateStatusList1737110469001()
45
+ await updateMig.down(queryRunner)
46
+ const createMig = new CreateStatusList1693866470001()
47
+ const down = await createMig.down(queryRunner)
40
48
  debug('Migration statements executed')
41
49
  return down
42
50
  } else if (dbType === 'sqlite' || dbType === 'react-native' || dbType === 'expo') {
43
- debug('using sqlite/react-native migration file')
44
- const mig = new CreateStatusList1693866470002()
45
- const down = await mig.down(queryRunner)
51
+ debug('using sqlite/react-native migration files')
52
+ const updateMig = new UpdateStatusList1737110469000()
53
+ await updateMig.down(queryRunner)
54
+ const createMig = new CreateStatusList1693866470002()
55
+ const down = await createMig.down(queryRunner)
46
56
  debug('Migration statements executed')
47
57
  return down
48
58
  } else {
@@ -8,6 +8,7 @@ import { CreateMachineStateStore1708098041262 } from './7-CreateMachineStateStor
8
8
  import { CreateContacts1708525189000 } from './8-CreateContacts'
9
9
  import { CreateContacts1715761125000 } from './9-CreateContacts'
10
10
  import { CreatePresentationDefinitions1716533767523 } from './10-CreatePresentationDefinitions'
11
+ import { FixCredentialClaimsReferencesUuid1741895822987 } from './11-FixCredentialClaimsReferenceUuid'
11
12
 
12
13
  /**
13
14
  * The migrations array that SHOULD be used when initializing a TypeORM database connection.
@@ -24,7 +25,7 @@ export const DataStoreContactMigrations = [
24
25
  CreateContacts1708525189000,
25
26
  CreateContacts1715761125000,
26
27
  ]
27
- export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429]
28
+ export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429, FixCredentialClaimsReferencesUuid1741895822987]
28
29
  export const DataStoreStatusListMigrations = [CreateStatusList1693866470000]
29
30
  export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330]
30
31
  export const DataStoreDigitalCredentialMigrations = [CreateDigitalCredential1708525189000]