@sphereon/ssi-sdk.data-store 0.33.1-next.73 → 0.34.1-feature.SSISDK.17.bitstring.sl.10
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 +911 -444
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -9
- package/dist/index.d.ts +40 -9
- package/dist/index.js +857 -390
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/statusList.entities.test.ts +58 -1
- package/src/__tests__/statusList.store.test.ts +64 -1
- package/src/entities/statusList/BitstringStatusListEntryEntity.ts +60 -0
- package/src/entities/statusList/StatusList2021EntryEntity.ts +4 -3
- package/src/entities/statusList/StatusListEntities.ts +54 -5
- package/src/index.ts +12 -2
- package/src/migrations/generic/12-CreateBitstringStatusList.ts +52 -0
- package/src/migrations/generic/index.ts +2 -1
- package/src/migrations/postgres/1741895823000-CreateBitstringStatusList.ts +53 -0
- package/src/migrations/sqlite/1741895823001-CreateBitstringStatusList.ts +145 -0
- package/src/statusList/IStatusListStore.ts +5 -2
- package/src/statusList/StatusListStore.ts +39 -16
- package/src/types/index.ts +1 -0
- package/src/types/statusList/bitstringTypes.ts +7 -0
- package/src/types/statusList/statusList.ts +13 -2
- package/src/utils/statusList/MappingUtils.ts +40 -2
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
export class CreateBitstringStatusListSqlite1741895823001 implements MigrationInterface {
|
|
4
|
+
name = 'CreateBitstringStatusList1741895823000'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
// Update StatusList table to include BitstringStatusList type and columns
|
|
8
|
+
await queryRunner.query(`
|
|
9
|
+
CREATE TABLE "temporary_StatusList" (
|
|
10
|
+
"id" varchar PRIMARY KEY NOT NULL,
|
|
11
|
+
"correlationId" varchar NOT NULL,
|
|
12
|
+
"length" integer NOT NULL,
|
|
13
|
+
"issuer" text NOT NULL,
|
|
14
|
+
"type" varchar CHECK( "type" IN ('StatusList2021', 'OAuthStatusList', 'BitstringStatusList') ) NOT NULL DEFAULT ('StatusList2021'),
|
|
15
|
+
"driverType" varchar CHECK( "driverType" IN ('agent_typeorm','agent_kv_store','github','agent_filesystem') ) NOT NULL DEFAULT ('agent_typeorm'),
|
|
16
|
+
"credentialIdMode" varchar CHECK( "credentialIdMode" IN ('ISSUANCE','PERSISTENCE','NEVER') ) NOT NULL DEFAULT ('ISSUANCE'),
|
|
17
|
+
"proofFormat" varchar CHECK( "proofFormat" IN ('lds','jwt') ) NOT NULL DEFAULT ('lds'),
|
|
18
|
+
"indexingDirection" varchar CHECK( "indexingDirection" IN ('rightToLeft') ),
|
|
19
|
+
"statusPurpose" varchar,
|
|
20
|
+
"statusListCredential" text,
|
|
21
|
+
"expiresAt" datetime,
|
|
22
|
+
"bitsPerStatus" integer DEFAULT (1),
|
|
23
|
+
"ttl" integer,
|
|
24
|
+
"validFrom" datetime,
|
|
25
|
+
"validUntil" datetime,
|
|
26
|
+
CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId")
|
|
27
|
+
)
|
|
28
|
+
`)
|
|
29
|
+
|
|
30
|
+
await queryRunner.query(`
|
|
31
|
+
INSERT INTO "temporary_StatusList"(
|
|
32
|
+
"id", "correlationId", "length", "issuer", "type", "driverType",
|
|
33
|
+
"credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
|
|
34
|
+
"statusListCredential", "bitsPerStatus", "expiresAt"
|
|
35
|
+
)
|
|
36
|
+
SELECT
|
|
37
|
+
"id", "correlationId", "length", "issuer", "type", "driverType",
|
|
38
|
+
"credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
|
|
39
|
+
"statusListCredential", "bitsPerStatus", "expiresAt"
|
|
40
|
+
FROM "StatusList"
|
|
41
|
+
`)
|
|
42
|
+
|
|
43
|
+
await queryRunner.query(`DROP TABLE "StatusList"`)
|
|
44
|
+
await queryRunner.query(`ALTER TABLE "temporary_StatusList" RENAME TO "StatusList"`)
|
|
45
|
+
|
|
46
|
+
// Update StatusListEntry table with inheritance and bitstring columns
|
|
47
|
+
await queryRunner.query(`
|
|
48
|
+
CREATE TABLE "temporary_StatusListEntry" (
|
|
49
|
+
"statusListId" varchar NOT NULL,
|
|
50
|
+
"statusListIndex" integer NOT NULL,
|
|
51
|
+
"credentialId" text,
|
|
52
|
+
"credentialHash" varchar(128),
|
|
53
|
+
"correlationId" varchar(255),
|
|
54
|
+
"value" varchar(50),
|
|
55
|
+
"type" varchar CHECK( "type" IN ('StatusListEntryEntity', 'bitstring') ) NOT NULL DEFAULT ('StatusListEntryEntity'),
|
|
56
|
+
"statusPurpose" varchar,
|
|
57
|
+
"bitsPerStatus" integer DEFAULT (1),
|
|
58
|
+
"statusMessage" text,
|
|
59
|
+
"statusReference" text,
|
|
60
|
+
PRIMARY KEY ("statusListId", "statusListIndex")
|
|
61
|
+
)
|
|
62
|
+
`)
|
|
63
|
+
|
|
64
|
+
await queryRunner.query(`
|
|
65
|
+
INSERT INTO "temporary_StatusListEntry"(
|
|
66
|
+
"statusListId", "statusListIndex", "credentialId", "credentialHash",
|
|
67
|
+
"correlationId", "value", "type"
|
|
68
|
+
)
|
|
69
|
+
SELECT
|
|
70
|
+
"statusListId", "statusListIndex", "credentialId", "credentialHash",
|
|
71
|
+
"correlationId", "value", 'StatusListEntryEntity'
|
|
72
|
+
FROM "StatusListEntry"
|
|
73
|
+
`)
|
|
74
|
+
|
|
75
|
+
await queryRunner.query(`DROP TABLE "StatusListEntry"`)
|
|
76
|
+
await queryRunner.query(`ALTER TABLE "temporary_StatusListEntry" RENAME TO "StatusListEntry"`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
80
|
+
// Revert StatusListEntry table changes
|
|
81
|
+
await queryRunner.query(`
|
|
82
|
+
CREATE TABLE "temporary_StatusListEntry" (
|
|
83
|
+
"statusListId" varchar NOT NULL,
|
|
84
|
+
"statusListIndex" integer NOT NULL,
|
|
85
|
+
"credentialId" text,
|
|
86
|
+
"credentialHash" varchar(128),
|
|
87
|
+
"correlationId" varchar(255),
|
|
88
|
+
"value" varchar(50),
|
|
89
|
+
PRIMARY KEY ("statusListId", "statusListIndex")
|
|
90
|
+
)
|
|
91
|
+
`)
|
|
92
|
+
|
|
93
|
+
await queryRunner.query(`
|
|
94
|
+
INSERT INTO "temporary_StatusListEntry"(
|
|
95
|
+
"statusListId", "statusListIndex", "credentialId", "credentialHash",
|
|
96
|
+
"correlationId", "value"
|
|
97
|
+
)
|
|
98
|
+
SELECT
|
|
99
|
+
"statusListId", "statusListIndex", "credentialId", "credentialHash",
|
|
100
|
+
"correlationId", "value"
|
|
101
|
+
FROM "StatusListEntry"
|
|
102
|
+
WHERE "type" = 'StatusListEntryEntity'
|
|
103
|
+
`)
|
|
104
|
+
|
|
105
|
+
await queryRunner.query(`DROP TABLE "StatusListEntry"`)
|
|
106
|
+
await queryRunner.query(`ALTER TABLE "temporary_StatusListEntry" RENAME TO "StatusListEntry"`)
|
|
107
|
+
|
|
108
|
+
// Revert StatusList table changes
|
|
109
|
+
await queryRunner.query(`
|
|
110
|
+
CREATE TABLE "temporary_StatusList" (
|
|
111
|
+
"id" varchar PRIMARY KEY NOT NULL,
|
|
112
|
+
"correlationId" varchar NOT NULL,
|
|
113
|
+
"length" integer NOT NULL,
|
|
114
|
+
"issuer" text NOT NULL,
|
|
115
|
+
"type" varchar CHECK( "type" IN ('StatusList2021', 'OAuthStatusList') ) NOT NULL DEFAULT ('StatusList2021'),
|
|
116
|
+
"driverType" varchar CHECK( "driverType" IN ('agent_typeorm','agent_kv_store','github','agent_filesystem') ) NOT NULL DEFAULT ('agent_typeorm'),
|
|
117
|
+
"credentialIdMode" varchar CHECK( "credentialIdMode" IN ('ISSUANCE','PERSISTENCE','NEVER') ) NOT NULL DEFAULT ('ISSUANCE'),
|
|
118
|
+
"proofFormat" varchar CHECK( "proofFormat" IN ('lds','jwt') ) NOT NULL DEFAULT ('lds'),
|
|
119
|
+
"indexingDirection" varchar CHECK( "indexingDirection" IN ('rightToLeft') ),
|
|
120
|
+
"statusPurpose" varchar,
|
|
121
|
+
"statusListCredential" text,
|
|
122
|
+
"bitsPerStatus" integer,
|
|
123
|
+
"expiresAt" datetime,
|
|
124
|
+
CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId")
|
|
125
|
+
)
|
|
126
|
+
`)
|
|
127
|
+
|
|
128
|
+
await queryRunner.query(`
|
|
129
|
+
INSERT INTO "temporary_StatusList"(
|
|
130
|
+
"id", "correlationId", "length", "issuer", "type", "driverType",
|
|
131
|
+
"credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
|
|
132
|
+
"statusListCredential", "bitsPerStatus", "expiresAt"
|
|
133
|
+
)
|
|
134
|
+
SELECT
|
|
135
|
+
"id", "correlationId", "length", "issuer",
|
|
136
|
+
CASE WHEN "type" = 'BitstringStatusList' THEN 'StatusList2021' ELSE "type" END,
|
|
137
|
+
"driverType", "credentialIdMode", "proofFormat", "indexingDirection",
|
|
138
|
+
"statusPurpose", "statusListCredential", "bitsPerStatus", "expiresAt"
|
|
139
|
+
FROM "StatusList"
|
|
140
|
+
`)
|
|
141
|
+
|
|
142
|
+
await queryRunner.query(`DROP TABLE "StatusList"`)
|
|
143
|
+
await queryRunner.query(`ALTER TABLE "temporary_StatusList" RENAME TO "StatusList"`)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
IUpdateStatusListIndexArgs,
|
|
13
13
|
} from '../types'
|
|
14
14
|
import { IStatusListEntity, IStatusListEntryEntity } from '../types'
|
|
15
|
+
import { BitstringStatusListEntryEntity } from '../entities/statusList/BitstringStatusListEntryEntity'
|
|
15
16
|
|
|
16
17
|
export interface IStatusListStore {
|
|
17
18
|
getStatusList(args: IGetStatusListArgs): Promise<IStatusListEntity>
|
|
@@ -30,9 +31,11 @@ export interface IStatusListStore {
|
|
|
30
31
|
|
|
31
32
|
updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity>
|
|
32
33
|
|
|
33
|
-
getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | undefined>
|
|
34
|
+
getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | BitstringStatusListEntryEntity | undefined>
|
|
34
35
|
|
|
35
|
-
getStatusListEntryByCredentialId(
|
|
36
|
+
getStatusListEntryByCredentialId(
|
|
37
|
+
args: IGetStatusListEntryByCredentialIdArgs,
|
|
38
|
+
): Promise<StatusListEntryEntity | BitstringStatusListEntryEntity | undefined>
|
|
36
39
|
|
|
37
40
|
removeStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<boolean>
|
|
38
41
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type OrPromise, StatusListType } from '@sphereon/ssi-types'
|
|
2
2
|
import Debug from 'debug'
|
|
3
3
|
import { DataSource, In, type Repository } from 'typeorm'
|
|
4
|
-
import { OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from '../entities/statusList/StatusListEntities'
|
|
4
|
+
import { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from '../entities/statusList/StatusListEntities'
|
|
5
5
|
import { StatusListEntryEntity } from '../entities/statusList/StatusList2021EntryEntity'
|
|
6
|
+
import { BitstringStatusListEntryEntity } from '../entities/statusList/BitstringStatusListEntryEntity'
|
|
6
7
|
import type {
|
|
7
8
|
IAddStatusListArgs,
|
|
8
9
|
IAddStatusListEntryArgs,
|
|
@@ -41,11 +42,11 @@ export class StatusListStore implements IStatusListStore {
|
|
|
41
42
|
async availableStatusListEntries(args: IStatusListEntryAvailableArgs): Promise<number[]> {
|
|
42
43
|
const statusListIndex = Array.isArray(args.statusListIndex) ? args.statusListIndex : [args.statusListIndex]
|
|
43
44
|
const statusList = await this.getStatusList({ ...args, id: args.statusListId })
|
|
44
|
-
const repo = await this.getStatusListEntryRepo()
|
|
45
|
+
const repo = await this.getStatusListEntryRepo(statusList.type)
|
|
45
46
|
const results = (
|
|
46
47
|
await repo.find({
|
|
47
48
|
where: {
|
|
48
|
-
statusList,
|
|
49
|
+
statusListId: statusList.id,
|
|
49
50
|
statusListIndex: In(statusListIndex),
|
|
50
51
|
},
|
|
51
52
|
})
|
|
@@ -54,11 +55,13 @@ export class StatusListStore implements IStatusListStore {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
async addStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
|
|
57
|
-
|
|
58
|
+
const statusList = await this.getStatusList({ id: args.statusListId })
|
|
59
|
+
return (await this.getStatusListEntryRepo(statusList.type)).save(args)
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
|
|
61
63
|
const statusListId = args.statusListId ?? args.statusList?.id
|
|
64
|
+
const statusList = await this.getStatusList({ id: statusListId })
|
|
62
65
|
const result = await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: false })
|
|
63
66
|
const updatedEntry: Partial<IStatusListEntryEntity> = {
|
|
64
67
|
value: args.value,
|
|
@@ -69,7 +72,7 @@ export class StatusListStore implements IStatusListStore {
|
|
|
69
72
|
|
|
70
73
|
const updStatusListId = result?.statusListId ?? statusListId
|
|
71
74
|
const updateResult = await (
|
|
72
|
-
await this.getStatusListEntryRepo()
|
|
75
|
+
await this.getStatusListEntryRepo(statusList.type)
|
|
73
76
|
).upsert(
|
|
74
77
|
{ ...(result ?? { statusListId: updStatusListId, statusListIndex: args.statusListIndex }), ...updatedEntry },
|
|
75
78
|
{ conflictPaths: ['statusList', 'statusListIndex'] },
|
|
@@ -88,7 +91,7 @@ export class StatusListStore implements IStatusListStore {
|
|
|
88
91
|
statusListIndex,
|
|
89
92
|
entryCorrelationId,
|
|
90
93
|
errorOnNotFound,
|
|
91
|
-
}: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | undefined> {
|
|
94
|
+
}: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | BitstringStatusListEntryEntity | undefined> {
|
|
92
95
|
if (!statusListId && !statusListCorrelationId) {
|
|
93
96
|
throw Error(`Cannot get statusList entry without either a statusList id or statusListCorrelationId`)
|
|
94
97
|
}
|
|
@@ -97,8 +100,12 @@ export class StatusListStore implements IStatusListStore {
|
|
|
97
100
|
throw Error(`Cannot get statusList entry without either a statusListIndex or entryCorrelationId`)
|
|
98
101
|
}
|
|
99
102
|
|
|
103
|
+
const statusList = statusListId
|
|
104
|
+
? await this.getStatusList({ id: statusListId })
|
|
105
|
+
: await this.getStatusList({ correlationId: statusListCorrelationId })
|
|
106
|
+
|
|
100
107
|
const result = await (
|
|
101
|
-
await this.getStatusListEntryRepo()
|
|
108
|
+
await this.getStatusListEntryRepo(statusList.type)
|
|
102
109
|
).findOne({
|
|
103
110
|
where: {
|
|
104
111
|
...(statusListId && { statusListId }),
|
|
@@ -118,7 +125,9 @@ export class StatusListStore implements IStatusListStore {
|
|
|
118
125
|
return result ?? undefined
|
|
119
126
|
}
|
|
120
127
|
|
|
121
|
-
async getStatusListEntryByCredentialId(
|
|
128
|
+
async getStatusListEntryByCredentialId(
|
|
129
|
+
args: IGetStatusListEntryByCredentialIdArgs,
|
|
130
|
+
): Promise<StatusListEntryEntity | BitstringStatusListEntryEntity | undefined> {
|
|
122
131
|
const credentialId = args.credentialId
|
|
123
132
|
if (!credentialId) {
|
|
124
133
|
throw Error('Can only get a credential by credentialId when a credentialId is supplied')
|
|
@@ -132,8 +141,8 @@ export class StatusListStore implements IStatusListStore {
|
|
|
132
141
|
...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
|
|
133
142
|
credentialId,
|
|
134
143
|
}
|
|
135
|
-
console.log(`Entries: ${JSON.stringify(await (await this.getStatusListEntryRepo()).find(), null, 2)}`)
|
|
136
|
-
const result = await (await this.getStatusListEntryRepo()).findOne({ where })
|
|
144
|
+
console.log(`Entries: ${JSON.stringify(await (await this.getStatusListEntryRepo(statusList.type)).find(), null, 2)}`)
|
|
145
|
+
const result = await (await this.getStatusListEntryRepo(statusList.type)).findOne({ where })
|
|
137
146
|
|
|
138
147
|
if (!result && args.errorOnNotFound) {
|
|
139
148
|
throw Error(`Could not find status list credential id ${credentialId} for status list id ${statusList.id}`)
|
|
@@ -149,8 +158,12 @@ export class StatusListStore implements IStatusListStore {
|
|
|
149
158
|
error = true
|
|
150
159
|
}
|
|
151
160
|
if (!error) {
|
|
161
|
+
const statusList = await this.getStatusList({
|
|
162
|
+
id: args.statusListId,
|
|
163
|
+
correlationId: args.statusListCorrelationId,
|
|
164
|
+
})
|
|
152
165
|
const result = await (
|
|
153
|
-
await this.getStatusListEntryRepo()
|
|
166
|
+
await this.getStatusListEntryRepo(statusList.type)
|
|
154
167
|
).delete({
|
|
155
168
|
...(args.statusListId && { statusList: args.statusListId }),
|
|
156
169
|
...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
|
|
@@ -171,8 +184,9 @@ export class StatusListStore implements IStatusListStore {
|
|
|
171
184
|
if (error) {
|
|
172
185
|
console.log(`Could not delete statusList ${args.statusListId} entry by index ${args.statusListIndex}`)
|
|
173
186
|
} else {
|
|
187
|
+
const statusList = await this.getStatusList({ id: args.statusListId })
|
|
174
188
|
const result = await (
|
|
175
|
-
await this.getStatusListEntryRepo()
|
|
189
|
+
await this.getStatusListEntryRepo(statusList.type)
|
|
176
190
|
).delete({
|
|
177
191
|
...(args.statusListId && { statusList: args.statusListId }),
|
|
178
192
|
...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
|
|
@@ -184,7 +198,8 @@ export class StatusListStore implements IStatusListStore {
|
|
|
184
198
|
}
|
|
185
199
|
|
|
186
200
|
async getStatusListEntries(args: IGetStatusListEntriesArgs): Promise<StatusListEntryEntity[]> {
|
|
187
|
-
|
|
201
|
+
const statusList = await this.getStatusList({ id: args.statusListId })
|
|
202
|
+
return (await this.getStatusListEntryRepo(statusList.type)).find({ where: { ...args?.filter, statusList: args.statusListId } })
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
async getStatusList(args: IGetStatusListArgs): Promise<IStatusListEntity> {
|
|
@@ -251,7 +266,7 @@ export class StatusListStore implements IStatusListStore {
|
|
|
251
266
|
async removeStatusList(args: IRemoveStatusListArgs): Promise<boolean> {
|
|
252
267
|
const result = await this.getStatusListEntity(args)
|
|
253
268
|
|
|
254
|
-
await (await this.getStatusListEntryRepo()).delete({ statusListId: result.id })
|
|
269
|
+
await (await this.getStatusListEntryRepo(result.type)).delete({ statusListId: result.id })
|
|
255
270
|
const deletedEntity = await (await this.getStatusListRepo()).remove(result)
|
|
256
271
|
|
|
257
272
|
return Boolean(deletedEntity)
|
|
@@ -268,12 +283,20 @@ export class StatusListStore implements IStatusListStore {
|
|
|
268
283
|
return dataSource.getRepository(StatusList2021Entity)
|
|
269
284
|
case StatusListType.OAuthStatusList:
|
|
270
285
|
return dataSource.getRepository(OAuthStatusListEntity)
|
|
286
|
+
case StatusListType.BitstringStatusList:
|
|
287
|
+
return dataSource.getRepository(BitstringStatusListEntity)
|
|
271
288
|
default:
|
|
272
289
|
return dataSource.getRepository(StatusListEntity)
|
|
273
290
|
}
|
|
274
291
|
}
|
|
275
292
|
|
|
276
|
-
async getStatusListEntryRepo(): Promise<Repository<StatusListEntryEntity>> {
|
|
277
|
-
|
|
293
|
+
async getStatusListEntryRepo(type?: StatusListType): Promise<Repository<StatusListEntryEntity | BitstringStatusListEntryEntity>> {
|
|
294
|
+
const dataSource = await this.getDS()
|
|
295
|
+
switch (type) {
|
|
296
|
+
case StatusListType.BitstringStatusList:
|
|
297
|
+
return dataSource.getRepository(BitstringStatusListEntryEntity)
|
|
298
|
+
default:
|
|
299
|
+
return dataSource.getRepository(StatusListEntryEntity)
|
|
300
|
+
}
|
|
278
301
|
}
|
|
279
302
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './presentationDefinition/presentationDefinition'
|
|
|
6
6
|
export * from './presentationDefinition/IAbstractPDStore'
|
|
7
7
|
export * from './validation/validation'
|
|
8
8
|
export * from './statusList/statusList'
|
|
9
|
+
export * from './statusList/bitstringTypes'
|
|
9
10
|
export * from './statusList/IAbstractStatusListStore'
|
|
10
11
|
export * from './eventLogger/IAbstractEventLoggerStore'
|
|
11
12
|
export * from './eventLogger/eventLogger'
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type BitstringStatusPurpose = 'revocation' | 'suspension' | 'refresh' | 'message' | string // From vc-bitstring-status-lists without pulling in the whole dep for just this one type
|
|
2
|
+
|
|
3
|
+
export type BitstringStatus = {
|
|
4
|
+
status: string
|
|
5
|
+
message?: string
|
|
6
|
+
[x: string]: any
|
|
7
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type CredentialProofFormat,
|
|
2
3
|
IIssuer,
|
|
4
|
+
RequireOneOf,
|
|
3
5
|
StatusListCredential,
|
|
4
6
|
StatusListCredentialIdMode,
|
|
5
7
|
StatusListDriverType,
|
|
6
8
|
StatusListIndexingDirection,
|
|
7
9
|
StatusListType,
|
|
8
10
|
StatusPurpose2021,
|
|
9
|
-
type CredentialProofFormat,
|
|
10
|
-
RequireOneOf,
|
|
11
11
|
} from '@sphereon/ssi-types'
|
|
12
12
|
import { StatusListEntity } from '../../entities/statusList/StatusListEntities'
|
|
13
|
+
import { BitstringStatusPurpose } from './bitstringTypes'
|
|
13
14
|
|
|
14
15
|
export interface IStatusListEntity {
|
|
15
16
|
id: string
|
|
@@ -21,6 +22,7 @@ export interface IStatusListEntity {
|
|
|
21
22
|
type: StatusListType
|
|
22
23
|
proofFormat: CredentialProofFormat
|
|
23
24
|
statusListCredential?: StatusListCredential
|
|
25
|
+
bitsPerStatus?: number
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface IStatusList2021Entity extends IStatusListEntity {
|
|
@@ -33,6 +35,14 @@ export interface IOAuthStatusListEntity extends IStatusListEntity {
|
|
|
33
35
|
expiresAt?: Date
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
export interface IBitstringStatusListEntity extends IStatusListEntity {
|
|
39
|
+
statusPurpose: BitstringStatusPurpose | BitstringStatusPurpose[]
|
|
40
|
+
bitsPerStatus?: number
|
|
41
|
+
validFrom?: Date
|
|
42
|
+
validUntil?: Date
|
|
43
|
+
ttl?: number
|
|
44
|
+
}
|
|
45
|
+
|
|
36
46
|
export type IStatusListEntryEntity = RequireOneOf<
|
|
37
47
|
{
|
|
38
48
|
statusList: StatusListEntity
|
|
@@ -42,6 +52,7 @@ export type IStatusListEntryEntity = RequireOneOf<
|
|
|
42
52
|
credentialHash?: string
|
|
43
53
|
credentialId?: string
|
|
44
54
|
correlationId?: string
|
|
55
|
+
bitsPerStatus?: number
|
|
45
56
|
},
|
|
46
57
|
'statusList' | 'statusListId'
|
|
47
58
|
>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { IOAuthStatusListEntity, IStatusList2021Entity, IStatusListEntity } from '../../types'
|
|
2
|
-
import {
|
|
1
|
+
import { IBitstringStatusListEntity, IOAuthStatusListEntity, IStatusList2021Entity, IStatusListEntity } from '../../types'
|
|
2
|
+
import {
|
|
3
|
+
BitstringStatusListEntity,
|
|
4
|
+
OAuthStatusListEntity,
|
|
5
|
+
StatusList2021Entity,
|
|
6
|
+
StatusListEntity,
|
|
7
|
+
} from '../../entities/statusList/StatusListEntities'
|
|
3
8
|
import { StatusListType } from '@sphereon/ssi-types'
|
|
4
9
|
import { replaceNullWithUndefined } from '../FormattingUtils'
|
|
5
10
|
|
|
@@ -32,6 +37,27 @@ export const statusListEntityFrom = (args: IStatusListEntity): StatusListEntity
|
|
|
32
37
|
return entity
|
|
33
38
|
}
|
|
34
39
|
|
|
40
|
+
if (args.type === StatusListType.BitstringStatusList) {
|
|
41
|
+
const entity = new BitstringStatusListEntity()
|
|
42
|
+
const bitstringsl = args as IBitstringStatusListEntity
|
|
43
|
+
if (!bitstringsl.bitsPerStatus) {
|
|
44
|
+
throw Error('bitsPerStatus must be set for BitstringStatusList')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
entity.statusPurpose = bitstringsl.statusPurpose
|
|
48
|
+
entity.bitsPerStatus = bitstringsl.bitsPerStatus
|
|
49
|
+
entity.validFrom = bitstringsl.validFrom
|
|
50
|
+
entity.validUntil = bitstringsl.validUntil
|
|
51
|
+
entity.ttl = bitstringsl.ttl
|
|
52
|
+
setBaseFields(entity, args)
|
|
53
|
+
Object.defineProperty(entity, 'type', {
|
|
54
|
+
value: StatusListType.BitstringStatusList,
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true,
|
|
57
|
+
})
|
|
58
|
+
return entity
|
|
59
|
+
}
|
|
60
|
+
|
|
35
61
|
throw new Error(`Invalid status list type ${args.type}`)
|
|
36
62
|
}
|
|
37
63
|
|
|
@@ -56,6 +82,18 @@ export const statusListFrom = (entity: StatusListEntity): IStatusListEntity => {
|
|
|
56
82
|
return replaceNullWithUndefined(result)
|
|
57
83
|
}
|
|
58
84
|
|
|
85
|
+
if (entity instanceof BitstringStatusListEntity) {
|
|
86
|
+
const result: IBitstringStatusListEntity = {
|
|
87
|
+
...getBaseFields(entity),
|
|
88
|
+
type: StatusListType.BitstringStatusList,
|
|
89
|
+
statusPurpose: entity.statusPurpose,
|
|
90
|
+
bitsPerStatus: entity.bitsPerStatus,
|
|
91
|
+
validFrom: entity.validFrom,
|
|
92
|
+
validUntil: entity.validUntil,
|
|
93
|
+
ttl: entity.ttl,
|
|
94
|
+
}
|
|
95
|
+
return replaceNullWithUndefined(result)
|
|
96
|
+
}
|
|
59
97
|
throw new Error(`Invalid status list type ${typeof entity}`)
|
|
60
98
|
}
|
|
61
99
|
|