@sphereon/ssi-sdk.data-store 0.34.1-feature.disable.test.8 → 0.34.1-next.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sphereon/ssi-sdk.data-store",
3
- "version": "0.34.1-feature.disable.test.8+4f707ea5",
3
+ "version": "0.34.1-next.29+2593a430",
4
4
  "source": "src/index.ts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,9 +30,9 @@
30
30
  "@sphereon/pex": "5.0.0-unstable.28",
31
31
  "@sphereon/ssi-sdk-ext.did-utils": "0.29.1-next.3",
32
32
  "@sphereon/ssi-sdk-ext.identifier-resolution": "0.29.1-next.3",
33
- "@sphereon/ssi-sdk.agent-config": "0.34.1-feature.disable.test.8+4f707ea5",
34
- "@sphereon/ssi-sdk.core": "0.34.1-feature.disable.test.8+4f707ea5",
35
- "@sphereon/ssi-types": "0.34.1-feature.disable.test.8+4f707ea5",
33
+ "@sphereon/ssi-sdk.agent-config": "0.34.1-next.29+2593a430",
34
+ "@sphereon/ssi-sdk.core": "0.34.1-next.29+2593a430",
35
+ "@sphereon/ssi-types": "0.34.1-next.29+2593a430",
36
36
  "@veramo/core": "4.2.0",
37
37
  "@veramo/utils": "4.2.0",
38
38
  "blakejs": "^1.2.1",
@@ -65,5 +65,5 @@
65
65
  "PostgreSQL",
66
66
  "Contact Store"
67
67
  ],
68
- "gitHead": "4f707ea55e0d84c474ed41e5b36a43658f71aa5a"
68
+ "gitHead": "2593a430ac4faca47b620a3e12b297899518f2af"
69
69
  }
@@ -1,6 +1,6 @@
1
1
  import { DataSource } from 'typeorm'
2
2
  import { DataSources } from '@sphereon/ssi-sdk.agent-config'
3
- import { DataStoreStatusListEntities, StatusListEntryEntity } from '../index'
3
+ import { BitstringStatusListEntity, BitstringStatusListEntryEntity, DataStoreStatusListEntities, StatusListEntryEntity } from '../index'
4
4
  import { DataStoreStatusListMigrations } from '../migrations'
5
5
  import { OAuthStatusListEntity, StatusList2021Entity } from '../entities/statusList/StatusListEntities'
6
6
  import { IIssuer, StatusListCredentialIdMode, StatusListDriverType } from '@sphereon/ssi-types'
@@ -18,6 +18,8 @@ describe('Status list entities tests', () => {
18
18
  migrations: DataStoreStatusListMigrations,
19
19
  synchronize: false,
20
20
  entities: [...DataStoreStatusListEntities],
21
+ logger: 'advanced-console',
22
+ logging: ['query', 'error', 'schema', 'warn', 'info', 'log', 'migration'],
21
23
  }).initialize()
22
24
  await dbConnection.runMigrations()
23
25
  expect(await dbConnection.showMigrations()).toBeFalsy()
@@ -214,4 +216,59 @@ describe('Status list entities tests', () => {
214
216
  })
215
217
  expect(foundEntry).toBeNull()
216
218
  })
219
+
220
+ it('should save bitstring status list to database', async () => {
221
+ const statusList = new BitstringStatusListEntity()
222
+ statusList.id = 'bitstring-list-1'
223
+ statusList.correlationId = 'correlation-bitstring-1'
224
+ statusList.driverType = StatusListDriverType.AGENT_TYPEORM
225
+ statusList.length = 131072
226
+ statusList.credentialIdMode = StatusListCredentialIdMode.ISSUANCE
227
+ statusList.proofFormat = 'lds'
228
+ statusList.statusPurpose = 'revocation'
229
+ statusList.bitsPerStatus = 1
230
+ statusList.ttl = 3600000
231
+ statusList.validFrom = new Date('2024-01-01T00:00:00Z')
232
+ statusList.validUntil = new Date('2025-01-01T00:00:00Z')
233
+ statusList.issuer = 'did:example:789'
234
+
235
+ const fromDb = await dbConnection.getRepository(BitstringStatusListEntity).save(statusList)
236
+ expect(fromDb).toBeDefined()
237
+ expect(fromDb.id).toEqual(statusList.id)
238
+ expect(fromDb.statusPurpose).toEqual(statusList.statusPurpose)
239
+ expect(fromDb.bitsPerStatus).toEqual(statusList.bitsPerStatus)
240
+ expect(fromDb.ttl).toEqual(statusList.ttl)
241
+ expect(fromDb.validFrom).toEqual(statusList.validFrom)
242
+ expect(fromDb.validUntil).toEqual(statusList.validUntil)
243
+ })
244
+
245
+ it('should save bitstring status list entry to database', async () => {
246
+ const statusList = new BitstringStatusListEntity()
247
+ statusList.id = 'bitstring-list-1'
248
+ statusList.correlationId = 'correlation-bitstring-1'
249
+ statusList.driverType = StatusListDriverType.AGENT_TYPEORM
250
+ statusList.length = 131072
251
+ statusList.credentialIdMode = StatusListCredentialIdMode.ISSUANCE
252
+ statusList.proofFormat = 'lds'
253
+ statusList.statusPurpose = 'revocation'
254
+ statusList.issuer = 'did:example:789'
255
+
256
+ await dbConnection.getRepository(BitstringStatusListEntity).save(statusList)
257
+
258
+ const entry = new BitstringStatusListEntryEntity()
259
+ entry.statusList = statusList
260
+ entry.statusListIndex = 42
261
+ entry.credentialId = 'bitstring-credential-1'
262
+ entry.credentialHash = 'bitstring-hash-1'
263
+ entry.statusPurpose = 'revocation'
264
+ entry.bitsPerStatus = 1
265
+ entry.statusReference = 'https://example.org/status-ref'
266
+
267
+ const fromDb = await dbConnection.getRepository(BitstringStatusListEntryEntity).save(entry)
268
+ expect(fromDb).toBeDefined()
269
+ expect(fromDb.statusListIndex).toEqual(entry.statusListIndex)
270
+ expect(fromDb.statusPurpose).toEqual(entry.statusPurpose)
271
+ expect(fromDb.bitsPerStatus).toEqual(entry.bitsPerStatus)
272
+ expect(fromDb.statusReference).toEqual(entry.statusReference)
273
+ })
217
274
  })
@@ -1,6 +1,6 @@
1
1
  import { DataSource } from 'typeorm'
2
2
  import { DataSources } from '@sphereon/ssi-sdk.agent-config'
3
- import { DataStoreStatusListEntities } from '../index'
3
+ import { DataStoreStatusListEntities, IBitstringStatusListEntity } from '../index'
4
4
  import { DataStoreStatusListMigrations } from '../migrations'
5
5
  import { StatusListStore } from '../statusList/StatusListStore'
6
6
  import { IOAuthStatusListEntity, IStatusList2021Entity, IStatusListEntryEntity } from '../types'
@@ -230,4 +230,67 @@ describe('Status list store tests', () => {
230
230
 
231
231
  await expect(statusListStore.getStatusList({ id: statusList.id })).rejects.toThrow(`No status list found for id ${statusList.id}`)
232
232
  })
233
+
234
+ it('should store bitstring status list', async () => {
235
+ const statusList: IBitstringStatusListEntity = {
236
+ id: 'bitstring-list-1',
237
+ correlationId: 'correlation-bitstring-1',
238
+ driverType: StatusListDriverType.AGENT_TYPEORM,
239
+ length: 131072,
240
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
241
+ type: StatusListType.BitstringStatusList,
242
+ proofFormat: 'lds',
243
+ statusPurpose: 'revocation',
244
+ bitsPerStatus: 1,
245
+ ttl: 3600000,
246
+ validFrom: new Date('2024-01-01T00:00:00Z'),
247
+ validUntil: new Date('2025-01-01T00:00:00Z'),
248
+ issuer: 'did:example:789',
249
+ }
250
+
251
+ const result = await statusListStore.addStatusList(statusList)
252
+ expect(result).toBeDefined()
253
+ expect(result.id).toEqual(statusList.id)
254
+ expect((result as IBitstringStatusListEntity).statusPurpose).toEqual(statusList.statusPurpose)
255
+ expect((result as IBitstringStatusListEntity).ttl).toEqual(statusList.ttl)
256
+ })
257
+
258
+ it('should store and retrieve all three types of status lists', async () => {
259
+ const statusList2021: IStatusList2021Entity = {
260
+ id: 'test-list-1',
261
+ correlationId: 'correlation-1',
262
+ driverType: StatusListDriverType.AGENT_TYPEORM,
263
+ length: 100000,
264
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
265
+ type: StatusListType.StatusList2021,
266
+ proofFormat: 'jwt',
267
+ statusPurpose: 'revocation',
268
+ indexingDirection: 'rightToLeft',
269
+ issuer: 'did:example:123',
270
+ }
271
+
272
+ const bitstringStatusList: IBitstringStatusListEntity = {
273
+ id: 'bitstring-list-1',
274
+ correlationId: 'correlation-bitstring-1',
275
+ driverType: StatusListDriverType.AGENT_TYPEORM,
276
+ length: 131072,
277
+ credentialIdMode: StatusListCredentialIdMode.ISSUANCE,
278
+ type: StatusListType.BitstringStatusList,
279
+ proofFormat: 'lds',
280
+ bitsPerStatus: 1,
281
+ statusPurpose: 'suspension',
282
+ ttl: 3600000,
283
+ issuer: 'did:example:789',
284
+ }
285
+
286
+ await statusListStore.addStatusList(statusList2021)
287
+ await statusListStore.addStatusList(bitstringStatusList)
288
+
289
+ const found2021 = await statusListStore.getStatusList({ id: statusList2021.id })
290
+ const foundBitstring = await statusListStore.getStatusList({ id: bitstringStatusList.id })
291
+
292
+ expect(found2021.type).toEqual(StatusListType.StatusList2021)
293
+ expect(foundBitstring.type).toEqual(StatusListType.BitstringStatusList)
294
+ expect((foundBitstring as IBitstringStatusListEntity).statusPurpose).toEqual('suspension')
295
+ })
233
296
  })
@@ -0,0 +1,60 @@
1
+ import { ChildEntity, Column } from 'typeorm'
2
+ import { StatusListEntryEntity } from './StatusList2021EntryEntity'
3
+ import { BitstringStatusMessage } from '../../types'
4
+
5
+ @ChildEntity('bitstring')
6
+ export class BitstringStatusListEntryEntity extends StatusListEntryEntity {
7
+ @Column({ type: 'varchar', name: 'statusPurpose', nullable: false })
8
+ statusPurpose!: string
9
+
10
+ @Column({ type: 'integer', name: 'bitsPerStatus', nullable: true, default: 1 })
11
+ bitsPerStatus?: number
12
+
13
+ @Column({
14
+ type: 'text',
15
+ name: 'statusMessage',
16
+ nullable: true,
17
+ transformer: {
18
+ from(value: string): Array<BitstringStatusMessage> | undefined {
19
+ if (!value) {
20
+ return undefined
21
+ }
22
+ return JSON.parse(value)
23
+ },
24
+ to(value: Array<BitstringStatusMessage> | undefined): string | undefined {
25
+ if (!value) {
26
+ return undefined
27
+ }
28
+ return JSON.stringify(value)
29
+ },
30
+ },
31
+ })
32
+ statusMessage?: Array<BitstringStatusMessage>
33
+
34
+ @Column({
35
+ type: 'text',
36
+ name: 'statusReference',
37
+ nullable: true,
38
+ transformer: {
39
+ from(value: string): string | string[] | undefined {
40
+ if (!value) {
41
+ return undefined
42
+ }
43
+ if (value.startsWith('[')) {
44
+ return JSON.parse(value)
45
+ }
46
+ return value
47
+ },
48
+ to(value: string | string[] | undefined): string | undefined {
49
+ if (!value) {
50
+ return undefined
51
+ }
52
+ if (Array.isArray(value)) {
53
+ return JSON.stringify(value)
54
+ }
55
+ return value
56
+ },
57
+ },
58
+ })
59
+ statusReference?: string | string[]
60
+ }
@@ -1,11 +1,12 @@
1
1
  import { Validate } from 'class-validator'
2
- import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'
2
+ import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, TableInheritance } from 'typeorm'
3
3
  import { IsNonEmptyStringConstraint } from '../validators'
4
- import { StatusListEntity } from './StatusListEntities'
4
+ import { StatusList2021Entity, 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
+ @TableInheritance({ column: { type: 'varchar', name: 'type' } })
9
10
  export class StatusListEntryEntity extends BaseEntity {
10
11
  @PrimaryColumn({ name: 'statusListId', type: 'varchar', nullable: false, unique: false })
11
12
  @Validate(IsNonEmptyStringConstraint, { message: 'Status list id is required' })
@@ -15,7 +16,7 @@ export class StatusListEntryEntity extends BaseEntity {
15
16
  @Validate(IsNonEmptyStringConstraint, { message: 'Status list index is required' })
16
17
  statusListIndex!: number
17
18
 
18
- @ManyToOne(() => StatusListEntity, (statusList) => statusList.statusListEntries)
19
+ @ManyToOne(() => StatusList2021Entity, (statusList) => statusList.statusListEntries)
19
20
  @JoinColumn({ name: 'statusListId' })
20
21
  statusList!: StatusListEntity
21
22
 
@@ -1,4 +1,5 @@
1
1
  import {
2
+ type CredentialProofFormat,
2
3
  type IIssuer,
3
4
  type StatusListCredential,
4
5
  StatusListCredentialIdMode,
@@ -6,12 +7,14 @@ import {
6
7
  type StatusListIndexingDirection,
7
8
  StatusListType,
8
9
  type StatusPurpose2021,
9
- type CredentialProofFormat,
10
10
  } from '@sphereon/ssi-types'
11
+
11
12
  import typeorm from 'typeorm'
12
- const { BaseEntity, ChildEntity, Column, Entity, OneToMany, PrimaryColumn, TableInheritance, Unique } = typeorm
13
13
  import { StatusListEntryEntity } from './StatusList2021EntryEntity'
14
14
  import { typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'
15
+ import { BitstringStatusListEntryEntity } from './BitstringStatusListEntryEntity'
16
+
17
+ const { BaseEntity, ChildEntity, Column, Entity, OneToMany, PrimaryColumn, TableInheritance, Unique } = typeorm
15
18
 
16
19
  @Entity('StatusList')
17
20
  @Unique('UQ_correlationId', ['correlationId'])
@@ -26,6 +29,13 @@ export abstract class StatusListEntity extends BaseEntity {
26
29
  @Column({ name: 'length', type: 'integer', nullable: false, unique: false })
27
30
  length!: number
28
31
 
32
+ @Column('simple-enum', {
33
+ name: 'type',
34
+ enum: StatusListType,
35
+ nullable: false,
36
+ })
37
+ type!: StatusListType
38
+
29
39
  @Column({
30
40
  name: 'issuer',
31
41
  type: 'text',
@@ -88,9 +98,6 @@ export abstract class StatusListEntity extends BaseEntity {
88
98
  },
89
99
  })
90
100
  statusListCredential?: StatusListCredential
91
-
92
- @OneToMany((type) => StatusListEntryEntity, (entry) => entry.statusList)
93
- statusListEntries!: StatusListEntryEntity[]
94
101
  }
95
102
 
96
103
  @ChildEntity(StatusListType.StatusList2021)
@@ -106,6 +113,9 @@ export class StatusList2021Entity extends StatusListEntity {
106
113
 
107
114
  @Column({ type: 'varchar', name: 'statusPurpose', nullable: false, default: 'revocation' })
108
115
  statusPurpose!: StatusPurpose2021
116
+
117
+ @OneToMany((type) => StatusListEntryEntity, (entry) => entry.statusList)
118
+ statusListEntries!: StatusListEntryEntity[]
109
119
  }
110
120
 
111
121
  @ChildEntity(StatusListType.OAuthStatusList)
@@ -115,3 +125,42 @@ export class OAuthStatusListEntity extends StatusListEntity {
115
125
  @Column({ name: 'expiresAt', nullable: true, type: typeOrmDateTime() })
116
126
  expiresAt?: Date
117
127
  }
128
+
129
+ @ChildEntity(StatusListType.BitstringStatusList)
130
+ export class BitstringStatusListEntity extends StatusListEntity {
131
+ @Column({
132
+ type: 'varchar',
133
+ name: 'statusPurpose',
134
+ nullable: false,
135
+ transformer: {
136
+ from(value: string): string | string[] {
137
+ if (value?.includes(',')) {
138
+ return value.split(',').map((v) => v.trim() as string)
139
+ }
140
+ return value as string
141
+ },
142
+ to(value: string | string[]): string {
143
+ if (Array.isArray(value)) {
144
+ return value.join(',')
145
+ }
146
+ return value
147
+ },
148
+ },
149
+ })
150
+ statusPurpose!: string | string[]
151
+
152
+ @Column({ type: 'integer', name: 'bitsPerStatus', nullable: false })
153
+ bitsPerStatus?: number
154
+
155
+ @Column({ name: 'validFrom', nullable: true, type: typeOrmDateTime() })
156
+ validFrom?: Date
157
+
158
+ @Column({ name: 'validUntil', nullable: true, type: typeOrmDateTime() })
159
+ validUntil?: Date
160
+
161
+ @Column({ type: 'integer', name: 'ttl', nullable: true })
162
+ ttl?: number
163
+
164
+ @OneToMany((type) => BitstringStatusListEntryEntity, (entry) => entry.statusList)
165
+ statusListEntries!: BitstringStatusListEntryEntity[]
166
+ }
package/src/index.ts CHANGED
@@ -16,8 +16,9 @@ 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 { OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from './entities/statusList/StatusListEntities'
19
+ import { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from './entities/statusList/StatusListEntities'
20
20
  import { StatusListEntryEntity } from './entities/statusList/StatusList2021EntryEntity'
21
+ import { BitstringStatusListEntryEntity } from './entities/statusList/BitstringStatusListEntryEntity'
21
22
  import { MachineStateInfoEntity } from './entities/machineState/MachineStateInfoEntity'
22
23
  // import { IStatusListEntity, IStatusListEntryEntity } from './types.'
23
24
  import { PartyRelationshipEntity } from './entities/contact/PartyRelationshipEntity'
@@ -100,7 +101,14 @@ export const DataStoreIssuanceBrandingEntities = [
100
101
 
101
102
  export const DataStorePresentationDefinitionEntities = [PresentationDefinitionItemEntity]
102
103
 
103
- export const DataStoreStatusListEntities = [StatusListEntity, StatusList2021Entity, OAuthStatusListEntity, StatusListEntryEntity]
104
+ export const DataStoreStatusListEntities = [
105
+ StatusListEntity,
106
+ StatusList2021Entity,
107
+ OAuthStatusListEntity,
108
+ BitstringStatusListEntity,
109
+ BitstringStatusListEntryEntity,
110
+ StatusListEntryEntity,
111
+ ]
104
112
 
105
113
  export const DataStoreEventLoggerEntities = [AuditEventEntity]
106
114
 
@@ -143,8 +151,10 @@ export {
143
151
  PhysicalAddressEntity,
144
152
  StatusListEntity,
145
153
  StatusListEntryEntity,
154
+ BitstringStatusListEntryEntity,
146
155
  OAuthStatusListEntity,
147
156
  StatusList2021Entity,
157
+ BitstringStatusListEntity,
148
158
  AuditEventEntity,
149
159
  DigitalCredentialEntity,
150
160
  MachineStateInfoEntity,
@@ -0,0 +1,52 @@
1
+ import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
2
+ import Debug from 'debug'
3
+ import { CreateBitstringStatusListPG1741895823000 } from '../postgres/1741895823000-CreateBitstringStatusList'
4
+ import { CreateBitstringStatusListSqlite1741895823001 } from '../sqlite/1741895823001-CreateBitstringStatusList'
5
+
6
+ const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')
7
+
8
+ export class CreateBitstringStatusList1741895823000 implements MigrationInterface {
9
+ name = 'CreateBitstringStatusList1741895823000'
10
+
11
+ public async up(queryRunner: QueryRunner): Promise<void> {
12
+ debug('migration: creating bitstring status list tables')
13
+ const dbType: DatabaseType = queryRunner.connection.driver.options.type
14
+ switch (dbType) {
15
+ case 'postgres': {
16
+ const mig = new CreateBitstringStatusListPG1741895823000()
17
+ await mig.up(queryRunner)
18
+ return
19
+ }
20
+ case 'sqlite':
21
+ case 'expo':
22
+ case 'react-native': {
23
+ const mig = new CreateBitstringStatusListSqlite1741895823001()
24
+ await mig.up(queryRunner)
25
+ return
26
+ }
27
+ default:
28
+ return Promise.reject(`Migrations only supported for sqlite and postgres. Was ${dbType}`)
29
+ }
30
+ }
31
+
32
+ public async down(queryRunner: QueryRunner): Promise<void> {
33
+ debug('migration: dropping bitstring status list tables')
34
+ const dbType: DatabaseType = queryRunner.connection.driver.options.type
35
+ switch (dbType) {
36
+ case 'postgres': {
37
+ const mig = new CreateBitstringStatusListPG1741895823000()
38
+ await mig.down(queryRunner)
39
+ return
40
+ }
41
+ case 'sqlite':
42
+ case 'expo':
43
+ case 'react-native': {
44
+ const mig = new CreateBitstringStatusListSqlite1741895823001()
45
+ await mig.down(queryRunner)
46
+ return
47
+ }
48
+ default:
49
+ return Promise.reject(`Migrations only supported for sqlite and postgres. Was ${dbType}`)
50
+ }
51
+ }
52
+ }
@@ -9,6 +9,7 @@ import { CreateContacts1708525189000 } from './8-CreateContacts'
9
9
  import { CreateContacts1715761125000 } from './9-CreateContacts'
10
10
  import { CreatePresentationDefinitions1716533767523 } from './10-CreatePresentationDefinitions'
11
11
  import { FixCredentialClaimsReferencesUuid1741895822987 } from './11-FixCredentialClaimsReferenceUuid'
12
+ import { CreateBitstringStatusList1741895823000 } from './12-CreateBitstringStatusList'
12
13
 
13
14
  /**
14
15
  * The migrations array that SHOULD be used when initializing a TypeORM database connection.
@@ -26,7 +27,7 @@ export const DataStoreContactMigrations = [
26
27
  CreateContacts1715761125000,
27
28
  ]
28
29
  export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429, FixCredentialClaimsReferencesUuid1741895822987]
29
- export const DataStoreStatusListMigrations = [CreateStatusList1693866470000]
30
+ export const DataStoreStatusListMigrations = [CreateStatusList1693866470000, CreateBitstringStatusList1741895823000]
30
31
  export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330]
31
32
  export const DataStoreDigitalCredentialMigrations = [CreateDigitalCredential1708525189000]
32
33
  export const DataStoreMachineStateMigrations = [CreateMachineStateStore1708098041262]
@@ -0,0 +1,53 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm'
2
+
3
+ export class CreateBitstringStatusListPG1741895823000 implements MigrationInterface {
4
+ name = 'CreateBitstringStatusList1741895823000'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Add BitstringStatusList columns to StatusList table
8
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "bitsPerStatus" integer DEFAULT 1`)
9
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "ttl" integer`)
10
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "validFrom" TIMESTAMP`)
11
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD COLUMN "validUntil" TIMESTAMP`)
12
+
13
+ // Update type enum constraint to include BitstringStatusList
14
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP CONSTRAINT IF EXISTS "CHK_StatusList_type"`)
15
+ await queryRunner.query(
16
+ `ALTER TABLE "StatusList" ADD CONSTRAINT "CHK_StatusList_type" CHECK ("type" IN ('StatusList2021', 'OAuthStatusList', 'BitstringStatusList'))`,
17
+ )
18
+
19
+ // Add inheritance discriminator column to StatusListEntry table
20
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" ADD COLUMN "type" character varying NOT NULL DEFAULT 'StatusListEntryEntity'`)
21
+
22
+ // Add BitstringStatusListEntry specific columns to StatusListEntry table
23
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" ADD COLUMN "statusPurpose" character varying`)
24
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" ADD COLUMN "bitsPerStatus" integer DEFAULT 1`)
25
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" ADD COLUMN "statusMessage" text`)
26
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" ADD COLUMN "statusReference" text`)
27
+
28
+ // Add constraint for entry type
29
+ await queryRunner.query(
30
+ `ALTER TABLE "StatusListEntry" ADD CONSTRAINT "CHK_StatusListEntry_type" CHECK ("type" IN ('StatusListEntryEntity', 'bitstring'))`,
31
+ )
32
+ }
33
+
34
+ public async down(queryRunner: QueryRunner): Promise<void> {
35
+ // Remove entry type constraint and columns
36
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP CONSTRAINT "CHK_StatusListEntry_type"`)
37
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP COLUMN "statusReference"`)
38
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP COLUMN "statusMessage"`)
39
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP COLUMN "bitsPerStatus"`)
40
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP COLUMN "statusPurpose"`)
41
+ await queryRunner.query(`ALTER TABLE "StatusListEntry" DROP COLUMN "type"`)
42
+
43
+ // Revert StatusList type constraint
44
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP CONSTRAINT "CHK_StatusList_type"`)
45
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD CONSTRAINT "CHK_StatusList_type" CHECK ("type" IN ('StatusList2021', 'OAuthStatusList'))`)
46
+
47
+ // Remove BitstringStatusList columns from StatusList table
48
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "validUntil"`)
49
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "validFrom"`)
50
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "ttl"`)
51
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "bitsPerStatus"`)
52
+ }
53
+ }