@sphereon/ssi-sdk.data-store 0.30.1-unstable.4 → 0.30.1

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 (136) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +77 -77
  3. package/dist/contact/ContactStore.d.ts.map +1 -1
  4. package/dist/digitalCredential/DigitalCredentialStore.d.ts.map +1 -1
  5. package/dist/eventLogger/EventLoggerStore.d.ts.map +1 -1
  6. package/dist/issuanceBranding/IssuanceBrandingStore.d.ts.map +1 -1
  7. package/dist/migrations/internal-migrations-ormconfig.d.ts.map +1 -1
  8. package/dist/migrations/postgres/1708525189001-CreateDigitalCredential.js +33 -33
  9. package/dist/migrations/postgres/1708797018115-CreateMachineStateStore.js +16 -16
  10. package/dist/migrations/postgres/1715761125001-CreateContacts.js +33 -33
  11. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js +12 -12
  12. package/dist/migrations/sqlite/1708525189002-CreateDigitalCredential.js +32 -32
  13. package/dist/migrations/sqlite/1708796002272-CreateMachineStateStore.js +15 -15
  14. package/dist/migrations/sqlite/1710438363002-CreateContacts.js +13 -13
  15. package/dist/migrations/sqlite/1715761125002-CreateContacts.js +32 -32
  16. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js +9 -9
  17. package/dist/presentationDefinition/PDStore.d.ts.map +1 -1
  18. package/dist/utils/SortingUtils.d.ts.map +1 -1
  19. package/dist/utils/contact/MappingUtils.d.ts.map +1 -1
  20. package/dist/utils/digitalCredential/MappingUtils.d.ts.map +1 -1
  21. package/dist/utils/digitalCredential/MappingUtils.js +4 -4
  22. package/dist/utils/digitalCredential/MappingUtils.js.map +1 -1
  23. package/dist/utils/presentationDefinition/MappingUtils.js +2 -2
  24. package/dist/utils/presentationDefinition/MappingUtils.js.map +1 -1
  25. package/package.json +8 -8
  26. package/src/__tests__/contact.entities.test.ts +2642 -2642
  27. package/src/__tests__/contact.store.test.ts +2649 -2649
  28. package/src/__tests__/digitalCredential.entities.test.ts +274 -274
  29. package/src/__tests__/digitalCredential.store.test.ts +330 -330
  30. package/src/__tests__/eventLogger.entities.test.ts +76 -76
  31. package/src/__tests__/eventLogger.store.test.ts +130 -130
  32. package/src/__tests__/issuanceBranding.entities.test.ts +846 -846
  33. package/src/__tests__/issuanceBranding.store.test.ts +1886 -1886
  34. package/src/__tests__/machineState.entities.test.ts +53 -53
  35. package/src/__tests__/machineState.store.test.ts +176 -176
  36. package/src/__tests__/pd-manager.entities.test.ts +73 -73
  37. package/src/__tests__/pd-manager.store.test.ts +193 -193
  38. package/src/contact/AbstractContactStore.ts +71 -71
  39. package/src/contact/ContactStore.ts +768 -768
  40. package/src/digitalCredential/AbstractDigitalCredentialStore.ts +21 -21
  41. package/src/digitalCredential/DigitalCredentialStore.ts +189 -189
  42. package/src/entities/contact/BaseContactEntity.ts +51 -51
  43. package/src/entities/contact/ConnectionEntity.ts +35 -35
  44. package/src/entities/contact/ContactMetadataItemEntity.ts +51 -51
  45. package/src/entities/contact/CorrelationIdentifierEntity.ts +43 -43
  46. package/src/entities/contact/DidAuthConfigEntity.ts +20 -20
  47. package/src/entities/contact/ElectronicAddressEntity.ts +70 -70
  48. package/src/entities/contact/IdentityEntity.ts +107 -107
  49. package/src/entities/contact/IdentityMetadataItemEntity.ts +48 -48
  50. package/src/entities/contact/NaturalPersonEntity.ts +44 -44
  51. package/src/entities/contact/OpenIdConfigEntity.ts +32 -32
  52. package/src/entities/contact/OrganizationEntity.ts +35 -35
  53. package/src/entities/contact/PartyEntity.ts +117 -117
  54. package/src/entities/contact/PartyRelationshipEntity.ts +68 -68
  55. package/src/entities/contact/PartyTypeEntity.ts +63 -63
  56. package/src/entities/contact/PhysicalAddressEntity.ts +95 -95
  57. package/src/entities/digitalCredential/DigitalCredentialEntity.ts +98 -98
  58. package/src/entities/eventLogger/AuditEventEntity.ts +92 -92
  59. package/src/entities/issuanceBranding/BackgroundAttributesEntity.ts +42 -42
  60. package/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts +87 -87
  61. package/src/entities/issuanceBranding/CredentialBrandingEntity.ts +79 -79
  62. package/src/entities/issuanceBranding/CredentialLocaleBrandingEntity.ts +33 -33
  63. package/src/entities/issuanceBranding/ImageAttributesEntity.ts +57 -57
  64. package/src/entities/issuanceBranding/ImageDimensionsEntity.ts +22 -22
  65. package/src/entities/issuanceBranding/IssuerBrandingEntity.ts +73 -73
  66. package/src/entities/issuanceBranding/IssuerLocaleBrandingEntity.ts +33 -33
  67. package/src/entities/issuanceBranding/TextAttributesEntity.ts +31 -31
  68. package/src/entities/machineState/MachineStateInfoEntity.ts +59 -59
  69. package/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +44 -44
  70. package/src/entities/statusList2021/StatusList2021Entity.ts +96 -96
  71. package/src/entities/statusList2021/StatusList2021EntryEntity.ts +29 -29
  72. package/src/eventLogger/AbstractEventLoggerStore.ts +7 -7
  73. package/src/eventLogger/EventLoggerStore.ts +62 -62
  74. package/src/index.ts +160 -160
  75. package/src/issuanceBranding/IssuanceBrandingStore.ts +559 -559
  76. package/src/machineState/IAbstractMachineStateStore.ts +65 -65
  77. package/src/machineState/MachineStateStore.ts +149 -149
  78. package/src/migrations/generic/1-CreateContacts.ts +66 -66
  79. package/src/migrations/generic/10-CreatePresentationDefinitions.ts +66 -66
  80. package/src/migrations/generic/2-CreateIssuanceBranding.ts +64 -64
  81. package/src/migrations/generic/3-CreateContacts.ts +66 -66
  82. package/src/migrations/generic/4-CreateStatusList.ts +54 -54
  83. package/src/migrations/generic/5-CreateAuditEvents.ts +66 -66
  84. package/src/migrations/generic/6-CreateDigitalCredential.ts +66 -66
  85. package/src/migrations/generic/7-CreateMachineStateStore.ts +66 -66
  86. package/src/migrations/generic/8-CreateContacts.ts +66 -66
  87. package/src/migrations/generic/9-CreateContacts.ts +66 -66
  88. package/src/migrations/generic/index.ts +43 -43
  89. package/src/migrations/index.ts +10 -10
  90. package/src/migrations/postgres/1659463079428-CreateContacts.ts +63 -63
  91. package/src/migrations/postgres/1685628974232-CreateIssuanceBranding.ts +85 -85
  92. package/src/migrations/postgres/1690925872592-CreateContacts.ts +158 -158
  93. package/src/migrations/postgres/1693866470001-CreateStatusList.ts +24 -24
  94. package/src/migrations/postgres/1701634812183-CreateAuditEvents.ts +33 -33
  95. package/src/migrations/postgres/1708525189001-CreateDigitalCredential.ts +61 -61
  96. package/src/migrations/postgres/1708797018115-CreateMachineStateStore.ts +29 -29
  97. package/src/migrations/postgres/1710438363001-CreateContacts.ts +63 -63
  98. package/src/migrations/postgres/1715761125001-CreateContacts.ts +60 -60
  99. package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +25 -25
  100. package/src/migrations/sqlite/1659463069549-CreateContacts.ts +110 -110
  101. package/src/migrations/sqlite/1685628973231-CreateIssuanceBranding.ts +119 -119
  102. package/src/migrations/sqlite/1690925872693-CreateContacts.ts +228 -228
  103. package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +24 -24
  104. package/src/migrations/sqlite/1701634819487-CreateAuditEvents.ts +15 -15
  105. package/src/migrations/sqlite/1708525189002-CreateDigitalCredential.ts +46 -46
  106. package/src/migrations/sqlite/1708796002272-CreateMachineStateStore.ts +28 -28
  107. package/src/migrations/sqlite/1710438363002-CreateContacts.ts +83 -83
  108. package/src/migrations/sqlite/1715761125002-CreateContacts.ts +59 -59
  109. package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +24 -24
  110. package/src/presentationDefinition/AbstractPDStore.ts +20 -20
  111. package/src/presentationDefinition/PDStore.ts +185 -185
  112. package/src/statusList/IStatusListStore.ts +44 -44
  113. package/src/statusList/StatusListStore.ts +236 -236
  114. package/src/types/contact/IAbstractContactStore.ts +161 -161
  115. package/src/types/contact/contact.ts +295 -295
  116. package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +42 -42
  117. package/src/types/digitalCredential/digitalCredential.ts +102 -102
  118. package/src/types/eventLogger/IAbstractEventLoggerStore.ts +12 -12
  119. package/src/types/eventLogger/eventLogger.ts +3 -3
  120. package/src/types/index.ts +14 -14
  121. package/src/types/machineState/IAbstractMachineStateStore.ts +68 -68
  122. package/src/types/presentationDefinition/IAbstractPDStore.ts +25 -25
  123. package/src/types/presentationDefinition/presentationDefinition.ts +17 -17
  124. package/src/utils/SortingUtils.ts +16 -16
  125. package/src/utils/contact/MappingUtils.ts +506 -506
  126. package/src/utils/digitalCredential/MappingUtils.ts +160 -160
  127. package/src/utils/hasher.ts +19 -19
  128. package/src/utils/presentationDefinition/MappingUtils.ts +52 -52
  129. package/dist/entities/contact/IMetadataEntity.d.ts +0 -8
  130. package/dist/entities/contact/IMetadataEntity.d.ts.map +0 -1
  131. package/dist/entities/contact/IMetadataEntity.js +0 -2
  132. package/dist/entities/contact/IMetadataEntity.js.map +0 -1
  133. package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts +0 -7
  134. package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts.map +0 -1
  135. package/dist/migrations/generic/8-CreatePresentationDefinitions.js +0 -78
  136. package/dist/migrations/generic/8-CreatePresentationDefinitions.js.map +0 -1
@@ -1,236 +1,236 @@
1
- import { OrPromise } from '@sphereon/ssi-types'
2
- import Debug from 'debug'
3
- import { DataSource, In, Repository } from 'typeorm'
4
- import { StatusListEntity } from '../entities/statusList2021/StatusList2021Entity'
5
- import { StatusListEntryEntity } from '../entities/statusList2021/StatusList2021EntryEntity'
6
- import {
7
- IAddStatusListArgs,
8
- IAddStatusListEntryArgs,
9
- IGetStatusListArgs,
10
- IGetStatusListEntriesArgs,
11
- IGetStatusListEntryByCredentialIdArgs,
12
- IGetStatusListEntryByIndexArgs,
13
- IGetStatusListsArgs,
14
- IRemoveStatusListArgs,
15
- IStatusListEntryAvailableArgs,
16
- IUpdateStatusListIndexArgs,
17
- IStatusListEntity,
18
- IStatusListEntryEntity,
19
- } from '../types'
20
- import { IStatusListStore } from './IStatusListStore'
21
-
22
- const debug = Debug('sphereon:ssi-sdk:data-store:status-list')
23
-
24
- export class StatusListStore implements IStatusListStore {
25
- private readonly _dbConnection: OrPromise<DataSource>
26
-
27
- constructor(dbConnection: OrPromise<DataSource>) {
28
- this._dbConnection = dbConnection
29
- }
30
-
31
- /**
32
- * Gets the available status list indices from the provided indices. Meaning it will filter out any index that is already known.
33
- *
34
- * The idea is that the caller provides a set of random status list indices. We can relatively easy check against the DB in an optimized way.
35
- * If the status list is large it is probably best to also provide at least a good number of indices. So something like 10 or 20 values.
36
- * Callers are also expected to call this function multiple times if it does not yield results
37
- *
38
- * @param args
39
- */
40
- async availableStatusListEntries(args: IStatusListEntryAvailableArgs): Promise<number[]> {
41
- const statusListIndex = Array.isArray(args.statusListIndex) ? args.statusListIndex : [args.statusListIndex]
42
- const statusList = await this.getStatusList({ ...args, id: args.statusListId })
43
- const repo = await this.getStatusListEntryRepo()
44
- const results = (
45
- await repo.find({
46
- where: {
47
- statusList,
48
- statusListIndex: In(statusListIndex),
49
- },
50
- })
51
- ).map((index) => index.statusListIndex)
52
- return statusListIndex.filter((index) => !results.includes(index))
53
- }
54
-
55
- async addStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
56
- return (await this.getStatusListEntryRepo()).save(args)
57
- }
58
-
59
- async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
60
- const statusListId = typeof args.statusList === 'string' ? args.statusList : args.statusList.id
61
- const result = await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: false })
62
- const updatedEntry: Partial<IStatusListEntryEntity> = {
63
- value: args.value,
64
- correlationId: args.correlationId,
65
- credentialHash: args.credentialHash,
66
- credentialId: args.credentialId,
67
- }
68
-
69
- const updateResult = await (
70
- await this.getStatusListEntryRepo()
71
- ).upsert(
72
- { ...(result ?? { statusList: args.statusList, statusListIndex: args.statusListIndex }), ...updatedEntry },
73
- { conflictPaths: ['statusList', 'statusListIndex'] },
74
- )
75
- console.log(updateResult)
76
- return (await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: true })) as IStatusListEntryEntity
77
- }
78
-
79
- async getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | undefined> {
80
- if (!args.statusListId && !args.correlationId) {
81
- throw Error(`Cannot get statusList entry if not either a statusList id or correlationId is provided`)
82
- }
83
- const result = await (
84
- await this.getStatusListEntryRepo()
85
- ).findOne({
86
- where: {
87
- ...(args.statusListId && { statusList: args.statusListId }),
88
- ...(args.correlationId && { correlationId: args.correlationId }),
89
- statusListIndex: args.statusListIndex,
90
- },
91
- })
92
-
93
- if (!result && args.errorOnNotFound) {
94
- throw Error(`Could not find status list index ${args.statusListIndex} for status list id ${args.statusListId}`)
95
- }
96
- return result ?? undefined
97
- }
98
-
99
- async removeStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<boolean> {
100
- let error = false
101
- try {
102
- await this.getStatusListEntryByIndex(args) // only used to check it exists
103
- } catch (error) {
104
- error = true
105
- }
106
- if (error) {
107
- console.log(`Could not delete statusList ${args.statusListId} entry by index ${args.statusListIndex}`)
108
- } else {
109
- const result = await (
110
- await this.getStatusListEntryRepo()
111
- ).delete({
112
- ...(args.statusListId && { statusList: args.statusListId }),
113
- ...(args.correlationId && { correlationId: args.correlationId }),
114
- statusListIndex: args.statusListIndex,
115
- })
116
- error = !result.affected || result.affected !== 1
117
- }
118
- return !error
119
- }
120
-
121
- async getStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<StatusListEntryEntity | undefined> {
122
- const credentialId = args.credentialId
123
- if (!credentialId) {
124
- throw Error('Can only get a credential by credentialId when a credentialId is supplied')
125
- }
126
- const statusList = await this.getStatusList({ id: args.statusListId, correlationId: args.statusListCorrelationId })
127
- const where = {
128
- statusList: statusList.id,
129
- ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
130
- credentialId,
131
- }
132
- console.log(`Entries: ${JSON.stringify(await (await this.getStatusListEntryRepo()).find(), null, 2)}`)
133
- const result = await (await this.getStatusListEntryRepo()).findOne({ where })
134
-
135
- if (!result && args.errorOnNotFound) {
136
- throw Error(`Could not find status list credential id ${credentialId} for status list id ${statusList.id}`)
137
- }
138
- return result ?? undefined
139
- }
140
-
141
- async removeStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<boolean> {
142
- let error = false
143
- try {
144
- await this.getStatusListEntryByCredentialId(args) // only used to check it exists
145
- } catch (error) {
146
- error = true
147
- }
148
- if (!error) {
149
- const result = await (
150
- await this.getStatusListEntryRepo()
151
- ).delete({
152
- ...(args.statusListId && { statusList: args.statusListId }),
153
- ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
154
- credentialId: args.credentialId,
155
- })
156
- error = !result.affected || result.affected !== 1
157
- }
158
- return !error
159
- }
160
-
161
- async getStatusListEntries(args: IGetStatusListEntriesArgs): Promise<StatusListEntryEntity[]> {
162
- return (await this.getStatusListEntryRepo()).find({ where: { ...args?.filter, statusList: args.statusListId } })
163
- }
164
-
165
- async getStatusList(args: IGetStatusListArgs): Promise<IStatusListEntity> {
166
- if (!args.id && !args.correlationId) {
167
- throw Error(`At least and 'id' or 'correlationId' needs to be provided to lookup a status list`)
168
- }
169
- const where = []
170
- if (args.id) {
171
- where.push({ id: args.id })
172
- } else if (args.correlationId) {
173
- where.push({ correlationId: args.correlationId })
174
- }
175
- const result = await (await this.getStatusListRepo()).findOne({where})
176
- if (!result) {
177
- throw Error(`No status list found for id ${args.id}`)
178
- }
179
- return result
180
- }
181
-
182
- async getStatusLists(args: IGetStatusListsArgs): Promise<Array<IStatusListEntity>> {
183
- const result = await (
184
- await this.getStatusListRepo()
185
- ).find({
186
- where: args.filter,
187
- })
188
-
189
- if (!result) {
190
- return []
191
- }
192
- return result
193
- }
194
-
195
- async addStatusList(args: IAddStatusListArgs): Promise<IStatusListEntity> {
196
- const { id, correlationId } = args
197
-
198
- const result = await (
199
- await this.getStatusListRepo()
200
- ).findOne({
201
- where: [{ id }, { correlationId }],
202
- })
203
- if (result) {
204
- throw Error(`Status list for id ${id}, correlationId ${correlationId} already exists`)
205
- }
206
-
207
- debug('Adding status list ', id)
208
- const createdResult = await (await this.getStatusListRepo()).save(args)
209
-
210
- return createdResult
211
- }
212
-
213
- async updateStatusList(args: IUpdateStatusListIndexArgs): Promise<IStatusListEntity> {
214
- const result = await this.getStatusList(args)
215
- debug('Updating status list', result)
216
- const updatedResult = await (await this.getStatusListRepo()).save(args, { transaction: true })
217
- return updatedResult
218
- }
219
-
220
- async removeStatusList(args: IRemoveStatusListArgs): Promise<void> {
221
- const result = await this.getStatusList(args)
222
- await (await this.getStatusListRepo()).delete(result)
223
- }
224
-
225
- private async getDS(): Promise<DataSource> {
226
- return this._dbConnection
227
- }
228
-
229
- async getStatusListRepo(): Promise<Repository<StatusListEntity>> {
230
- return (await this.getDS()).getRepository(StatusListEntity)
231
- }
232
-
233
- async getStatusListEntryRepo(): Promise<Repository<StatusListEntryEntity>> {
234
- return (await this.getDS()).getRepository(StatusListEntryEntity)
235
- }
236
- }
1
+ import { OrPromise } from '@sphereon/ssi-types'
2
+ import Debug from 'debug'
3
+ import { DataSource, In, Repository } from 'typeorm'
4
+ import { StatusListEntity } from '../entities/statusList2021/StatusList2021Entity'
5
+ import { StatusListEntryEntity } from '../entities/statusList2021/StatusList2021EntryEntity'
6
+ import {
7
+ IAddStatusListArgs,
8
+ IAddStatusListEntryArgs,
9
+ IGetStatusListArgs,
10
+ IGetStatusListEntriesArgs,
11
+ IGetStatusListEntryByCredentialIdArgs,
12
+ IGetStatusListEntryByIndexArgs,
13
+ IGetStatusListsArgs,
14
+ IRemoveStatusListArgs,
15
+ IStatusListEntryAvailableArgs,
16
+ IUpdateStatusListIndexArgs,
17
+ IStatusListEntity,
18
+ IStatusListEntryEntity,
19
+ } from '../types'
20
+ import { IStatusListStore } from './IStatusListStore'
21
+
22
+ const debug = Debug('sphereon:ssi-sdk:data-store:status-list')
23
+
24
+ export class StatusListStore implements IStatusListStore {
25
+ private readonly _dbConnection: OrPromise<DataSource>
26
+
27
+ constructor(dbConnection: OrPromise<DataSource>) {
28
+ this._dbConnection = dbConnection
29
+ }
30
+
31
+ /**
32
+ * Gets the available status list indices from the provided indices. Meaning it will filter out any index that is already known.
33
+ *
34
+ * The idea is that the caller provides a set of random status list indices. We can relatively easy check against the DB in an optimized way.
35
+ * If the status list is large it is probably best to also provide at least a good number of indices. So something like 10 or 20 values.
36
+ * Callers are also expected to call this function multiple times if it does not yield results
37
+ *
38
+ * @param args
39
+ */
40
+ async availableStatusListEntries(args: IStatusListEntryAvailableArgs): Promise<number[]> {
41
+ const statusListIndex = Array.isArray(args.statusListIndex) ? args.statusListIndex : [args.statusListIndex]
42
+ const statusList = await this.getStatusList({ ...args, id: args.statusListId })
43
+ const repo = await this.getStatusListEntryRepo()
44
+ const results = (
45
+ await repo.find({
46
+ where: {
47
+ statusList,
48
+ statusListIndex: In(statusListIndex),
49
+ },
50
+ })
51
+ ).map((index) => index.statusListIndex)
52
+ return statusListIndex.filter((index) => !results.includes(index))
53
+ }
54
+
55
+ async addStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
56
+ return (await this.getStatusListEntryRepo()).save(args)
57
+ }
58
+
59
+ async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
60
+ const statusListId = typeof args.statusList === 'string' ? args.statusList : args.statusList.id
61
+ const result = await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: false })
62
+ const updatedEntry: Partial<IStatusListEntryEntity> = {
63
+ value: args.value,
64
+ correlationId: args.correlationId,
65
+ credentialHash: args.credentialHash,
66
+ credentialId: args.credentialId,
67
+ }
68
+
69
+ const updateResult = await (
70
+ await this.getStatusListEntryRepo()
71
+ ).upsert(
72
+ { ...(result ?? { statusList: args.statusList, statusListIndex: args.statusListIndex }), ...updatedEntry },
73
+ { conflictPaths: ['statusList', 'statusListIndex'] },
74
+ )
75
+ console.log(updateResult)
76
+ return (await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: true })) as IStatusListEntryEntity
77
+ }
78
+
79
+ async getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | undefined> {
80
+ if (!args.statusListId && !args.correlationId) {
81
+ throw Error(`Cannot get statusList entry if not either a statusList id or correlationId is provided`)
82
+ }
83
+ const result = await (
84
+ await this.getStatusListEntryRepo()
85
+ ).findOne({
86
+ where: {
87
+ ...(args.statusListId && { statusList: args.statusListId }),
88
+ ...(args.correlationId && { correlationId: args.correlationId }),
89
+ statusListIndex: args.statusListIndex,
90
+ },
91
+ })
92
+
93
+ if (!result && args.errorOnNotFound) {
94
+ throw Error(`Could not find status list index ${args.statusListIndex} for status list id ${args.statusListId}`)
95
+ }
96
+ return result ?? undefined
97
+ }
98
+
99
+ async removeStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<boolean> {
100
+ let error = false
101
+ try {
102
+ await this.getStatusListEntryByIndex(args) // only used to check it exists
103
+ } catch (error) {
104
+ error = true
105
+ }
106
+ if (error) {
107
+ console.log(`Could not delete statusList ${args.statusListId} entry by index ${args.statusListIndex}`)
108
+ } else {
109
+ const result = await (
110
+ await this.getStatusListEntryRepo()
111
+ ).delete({
112
+ ...(args.statusListId && { statusList: args.statusListId }),
113
+ ...(args.correlationId && { correlationId: args.correlationId }),
114
+ statusListIndex: args.statusListIndex,
115
+ })
116
+ error = !result.affected || result.affected !== 1
117
+ }
118
+ return !error
119
+ }
120
+
121
+ async getStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<StatusListEntryEntity | undefined> {
122
+ const credentialId = args.credentialId
123
+ if (!credentialId) {
124
+ throw Error('Can only get a credential by credentialId when a credentialId is supplied')
125
+ }
126
+ const statusList = await this.getStatusList({ id: args.statusListId, correlationId: args.statusListCorrelationId })
127
+ const where = {
128
+ statusList: statusList.id,
129
+ ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
130
+ credentialId,
131
+ }
132
+ console.log(`Entries: ${JSON.stringify(await (await this.getStatusListEntryRepo()).find(), null, 2)}`)
133
+ const result = await (await this.getStatusListEntryRepo()).findOne({ where })
134
+
135
+ if (!result && args.errorOnNotFound) {
136
+ throw Error(`Could not find status list credential id ${credentialId} for status list id ${statusList.id}`)
137
+ }
138
+ return result ?? undefined
139
+ }
140
+
141
+ async removeStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<boolean> {
142
+ let error = false
143
+ try {
144
+ await this.getStatusListEntryByCredentialId(args) // only used to check it exists
145
+ } catch (error) {
146
+ error = true
147
+ }
148
+ if (!error) {
149
+ const result = await (
150
+ await this.getStatusListEntryRepo()
151
+ ).delete({
152
+ ...(args.statusListId && { statusList: args.statusListId }),
153
+ ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
154
+ credentialId: args.credentialId,
155
+ })
156
+ error = !result.affected || result.affected !== 1
157
+ }
158
+ return !error
159
+ }
160
+
161
+ async getStatusListEntries(args: IGetStatusListEntriesArgs): Promise<StatusListEntryEntity[]> {
162
+ return (await this.getStatusListEntryRepo()).find({ where: { ...args?.filter, statusList: args.statusListId } })
163
+ }
164
+
165
+ async getStatusList(args: IGetStatusListArgs): Promise<IStatusListEntity> {
166
+ if (!args.id && !args.correlationId) {
167
+ throw Error(`At least and 'id' or 'correlationId' needs to be provided to lookup a status list`)
168
+ }
169
+ const where = []
170
+ if (args.id) {
171
+ where.push({ id: args.id })
172
+ } else if (args.correlationId) {
173
+ where.push({ correlationId: args.correlationId })
174
+ }
175
+ const result = await (await this.getStatusListRepo()).findOne({where})
176
+ if (!result) {
177
+ throw Error(`No status list found for id ${args.id}`)
178
+ }
179
+ return result
180
+ }
181
+
182
+ async getStatusLists(args: IGetStatusListsArgs): Promise<Array<IStatusListEntity>> {
183
+ const result = await (
184
+ await this.getStatusListRepo()
185
+ ).find({
186
+ where: args.filter,
187
+ })
188
+
189
+ if (!result) {
190
+ return []
191
+ }
192
+ return result
193
+ }
194
+
195
+ async addStatusList(args: IAddStatusListArgs): Promise<IStatusListEntity> {
196
+ const { id, correlationId } = args
197
+
198
+ const result = await (
199
+ await this.getStatusListRepo()
200
+ ).findOne({
201
+ where: [{ id }, { correlationId }],
202
+ })
203
+ if (result) {
204
+ throw Error(`Status list for id ${id}, correlationId ${correlationId} already exists`)
205
+ }
206
+
207
+ debug('Adding status list ', id)
208
+ const createdResult = await (await this.getStatusListRepo()).save(args)
209
+
210
+ return createdResult
211
+ }
212
+
213
+ async updateStatusList(args: IUpdateStatusListIndexArgs): Promise<IStatusListEntity> {
214
+ const result = await this.getStatusList(args)
215
+ debug('Updating status list', result)
216
+ const updatedResult = await (await this.getStatusListRepo()).save(args, { transaction: true })
217
+ return updatedResult
218
+ }
219
+
220
+ async removeStatusList(args: IRemoveStatusListArgs): Promise<void> {
221
+ const result = await this.getStatusList(args)
222
+ await (await this.getStatusListRepo()).delete(result)
223
+ }
224
+
225
+ private async getDS(): Promise<DataSource> {
226
+ return this._dbConnection
227
+ }
228
+
229
+ async getStatusListRepo(): Promise<Repository<StatusListEntity>> {
230
+ return (await this.getDS()).getRepository(StatusListEntity)
231
+ }
232
+
233
+ async getStatusListEntryRepo(): Promise<Repository<StatusListEntryEntity>> {
234
+ return (await this.getDS()).getRepository(StatusListEntryEntity)
235
+ }
236
+ }