@sphereon/ssi-sdk.data-store 0.32.1-feature.VDX.341.57 → 0.32.1-feature.new.develop.274

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 (72) hide show
  1. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts +13 -0
  2. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts.map +1 -0
  3. package/dist/entities/oid4vcState/Oid4vcStateEntity.js +57 -0
  4. package/dist/entities/oid4vcState/Oid4vcStateEntity.js.map +1 -0
  5. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.d.ts +4 -3
  6. package/dist/entities/statusList/StatusList2021EntryEntity.d.ts.map +1 -0
  7. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.js +11 -6
  8. package/dist/entities/statusList/StatusList2021EntryEntity.js.map +1 -0
  9. package/dist/entities/statusList/StatusListEntities.d.ts +23 -0
  10. package/dist/entities/statusList/StatusListEntities.d.ts.map +1 -0
  11. package/dist/entities/{statusList2021/StatusList2021Entity.js → statusList/StatusListEntities.js} +45 -16
  12. package/dist/entities/statusList/StatusListEntities.js.map +1 -0
  13. package/dist/index.d.ts +5 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +10 -6
  16. package/dist/index.js.map +1 -1
  17. package/dist/migrations/generic/4-CreateStatusList.d.ts.map +1 -1
  18. package/dist/migrations/generic/4-CreateStatusList.js +22 -12
  19. package/dist/migrations/generic/4-CreateStatusList.js.map +1 -1
  20. package/dist/migrations/postgres/1693866470001-CreateStatusList.d.ts.map +1 -1
  21. package/dist/migrations/postgres/1693866470001-CreateStatusList.js +40 -7
  22. package/dist/migrations/postgres/1693866470001-CreateStatusList.js.map +1 -1
  23. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts +7 -0
  24. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts.map +1 -0
  25. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js +39 -0
  26. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js.map +1 -0
  27. package/dist/migrations/sqlite/1693866470000-CreateStatusList.d.ts.map +1 -1
  28. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js +45 -5
  29. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js.map +1 -1
  30. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts +7 -0
  31. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts.map +1 -0
  32. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js +96 -0
  33. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js.map +1 -0
  34. package/dist/statusList/IStatusListStore.d.ts +2 -2
  35. package/dist/statusList/IStatusListStore.d.ts.map +1 -1
  36. package/dist/statusList/StatusListStore.d.ts +9 -8
  37. package/dist/statusList/StatusListStore.d.ts.map +1 -1
  38. package/dist/statusList/StatusListStore.js +72 -42
  39. package/dist/statusList/StatusListStore.js.map +1 -1
  40. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts +2 -2
  41. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts.map +1 -1
  42. package/dist/types/statusList/IAbstractStatusListStore.d.ts +5 -4
  43. package/dist/types/statusList/IAbstractStatusListStore.d.ts.map +1 -1
  44. package/dist/types/statusList/statusList.d.ts +13 -7
  45. package/dist/types/statusList/statusList.d.ts.map +1 -1
  46. package/dist/utils/statusList/MappingUtils.d.ts +5 -0
  47. package/dist/utils/statusList/MappingUtils.d.ts.map +1 -0
  48. package/dist/utils/statusList/MappingUtils.js +69 -0
  49. package/dist/utils/statusList/MappingUtils.js.map +1 -0
  50. package/package.json +7 -7
  51. package/src/__tests__/statusList.entities.test.ts +216 -0
  52. package/src/__tests__/statusList.store.test.ts +232 -0
  53. package/src/entities/oid4vcState/Oid4vcStateEntity.ts +32 -0
  54. package/src/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.ts +10 -6
  55. package/src/entities/{statusList2021/StatusList2021Entity.ts → statusList/StatusListEntities.ts} +38 -18
  56. package/src/index.ts +8 -3
  57. package/src/migrations/generic/4-CreateStatusList.ts +22 -12
  58. package/src/migrations/postgres/1693866470001-CreateStatusList.ts +42 -9
  59. package/src/migrations/postgres/1737110469001-UpdateStatusList.ts +25 -0
  60. package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +45 -5
  61. package/src/migrations/sqlite/1737110469000-UpdateStatusList.ts +94 -0
  62. package/src/statusList/IStatusListStore.ts +2 -2
  63. package/src/statusList/StatusListStore.ts +94 -51
  64. package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +2 -2
  65. package/src/types/statusList/IAbstractStatusListStore.ts +5 -4
  66. package/src/types/statusList/statusList.ts +24 -16
  67. package/src/utils/statusList/MappingUtils.ts +82 -0
  68. package/dist/entities/statusList2021/StatusList2021Entity.d.ts +0 -19
  69. package/dist/entities/statusList2021/StatusList2021Entity.d.ts.map +0 -1
  70. package/dist/entities/statusList2021/StatusList2021Entity.js.map +0 -1
  71. package/dist/entities/statusList2021/StatusList2021EntryEntity.d.ts.map +0 -1
  72. package/dist/entities/statusList2021/StatusList2021EntryEntity.js.map +0 -1
@@ -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
  }
@@ -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 {
@@ -1,24 +1,57 @@
1
+ // noinspection SqlPostgresDialect SqlNoDataSourceInspection
1
2
  import { MigrationInterface, QueryRunner } from 'typeorm'
2
3
 
3
4
  export class CreateStatusList1693866470001 implements MigrationInterface {
4
5
  name = 'CreateStatusList1693866470001'
5
6
 
6
7
  public async up(queryRunner: QueryRunner): Promise<void> {
8
+ await queryRunner.query(`CREATE TYPE "StatusList_type_enum" AS ENUM('StatusList2021')`)
9
+ await queryRunner.query(`CREATE TYPE "StatusList_drivertype_enum" AS ENUM('agent_typeorm', 'agent_kv_store', 'github', 'agent_filesystem')`)
10
+ await queryRunner.query(`CREATE TYPE "StatusList_credentialidmode_enum" AS ENUM('ISSUANCE', 'PERSISTENCE', 'NEVER')`)
11
+
7
12
  await queryRunner.query(
8
- `CREATE TABLE "StatusListEntry" ("statusListId" character varying NOT NULL, "statusListIndex" integer NOT NULL, "credentialId" character varying, "credentialHash" character varying(128), "correlationId" character varying(255), "value" character varying(50), CONSTRAINT "PK_68704d2d13857360c6b44a3d1d0" PRIMARY KEY ("statusListId", "statusListIndex"))`,
9
- )
10
- await queryRunner.query(`CREATE TYPE "public"."StatusList_type_enum" AS ENUM('StatusList2021')`)
11
- await queryRunner.query(
12
- `CREATE TYPE "public"."StatusList_drivertype_enum" AS ENUM('agent_typeorm', 'agent_kv_store', 'github', 'agent_filesystem')`,
13
+ `CREATE TABLE "StatusListEntry"
14
+ (
15
+ "statusListId" character varying NOT NULL,
16
+ "statusListIndex" integer NOT NULL,
17
+ "credentialId" character varying,
18
+ "credentialHash" character varying(128),
19
+ "correlationId" character varying(255),
20
+ "value" character varying(50),
21
+ CONSTRAINT "PK_68704d2d13857360c6b44a3d1d0" PRIMARY KEY ("statusListId", "statusListIndex")
22
+ )`,
13
23
  )
14
- await queryRunner.query(`CREATE TYPE "public"."StatusList_credentialidmode_enum" AS ENUM('ISSUANCE', 'PERSISTENCE', 'NEVER')`)
15
24
  await queryRunner.query(
16
- `CREATE TABLE "StatusList" ("id" character varying NOT NULL, "correlationId" character varying NOT NULL, "length" integer NOT NULL, "issuer" text NOT NULL, "type" "public"."StatusList_type_enum" NOT NULL DEFAULT 'StatusList2021', "driverType" "public"."StatusList_drivertype_enum" NOT NULL DEFAULT 'agent_typeorm', "credentialIdMode" "public"."StatusList_credentialidmode_enum" NOT NULL DEFAULT 'ISSUANCE', "proofFormat" character varying NOT NULL DEFAULT 'lds', "indexingDirection" character varying NOT NULL DEFAULT 'rightToLeft', "statusPurpose" character varying NOT NULL DEFAULT 'revocation', "statusListCredential" text, CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId"), CONSTRAINT "PK_StatusList_Id" PRIMARY KEY ("id"))`,
25
+ `CREATE TABLE "StatusList"
26
+ (
27
+ "id" character varying NOT NULL,
28
+ "correlationId" character varying NOT NULL,
29
+ "length" integer NOT NULL,
30
+ "issuer" text NOT NULL,
31
+ "type" "StatusList_type_enum" NOT NULL DEFAULT 'StatusList2021',
32
+ "driverType" "StatusList_drivertype_enum" NOT NULL DEFAULT 'agent_typeorm',
33
+ "credentialIdMode" "StatusList_credentialidmode_enum" NOT NULL DEFAULT 'ISSUANCE',
34
+ "proofFormat" character varying NOT NULL DEFAULT 'lds',
35
+ "indexingDirection" character varying NOT NULL DEFAULT 'rightToLeft',
36
+ "statusPurpose" character varying NOT NULL DEFAULT 'revocation',
37
+ "statusListCredential" text,
38
+ CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId"),
39
+ CONSTRAINT "PK_StatusList_Id" PRIMARY KEY ("id")
40
+ )`,
17
41
  )
18
42
  await queryRunner.query(
19
- `ALTER TABLE "StatusListEntry" ADD CONSTRAINT "FK_statusListEntry_statusListId" FOREIGN KEY ("statusListId") REFERENCES "StatusList"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
43
+ `ALTER TABLE "StatusListEntry"
44
+ ADD CONSTRAINT "FK_statusListEntry_statusListId" FOREIGN KEY ("statusListId") REFERENCES "StatusList" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
20
45
  )
21
46
  }
22
47
 
23
- public async down(queryRunner: QueryRunner): Promise<void> {}
48
+ public async down(queryRunner: QueryRunner): Promise<void> {
49
+ await queryRunner.query(`ALTER TABLE "StatusListEntry"
50
+ DROP CONSTRAINT "FK_statusListEntry_statusListId"`)
51
+ await queryRunner.query(`DROP TABLE "StatusListEntry"`)
52
+ await queryRunner.query(`DROP TABLE "StatusList"`)
53
+ await queryRunner.query(`DROP TYPE "StatusList_credentialidmode_enum"`)
54
+ await queryRunner.query(`DROP TYPE "StatusList_drivertype_enum"`)
55
+ await queryRunner.query(`DROP TYPE "StatusList_type_enum"`)
56
+ }
24
57
  }
@@ -0,0 +1,25 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm'
2
+
3
+ export class UpdateStatusList1737110469001 implements MigrationInterface {
4
+ name = 'UpdateStatusList1737110469001'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Add new enum value
8
+ await queryRunner.query(`ALTER TYPE "StatusList_type_enum" ADD VALUE 'OAuthStatusList'`)
9
+
10
+ // Make columns nullable and add new columns
11
+ await queryRunner.query(`ALTER TABLE "StatusList" ALTER COLUMN "indexingDirection" DROP NOT NULL`)
12
+ await queryRunner.query(`ALTER TABLE "StatusList" ALTER COLUMN "statusPurpose" DROP NOT NULL`)
13
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD "bitsPerStatus" integer`)
14
+ await queryRunner.query(`ALTER TABLE "StatusList" ADD "expiresAt" timestamp with time zone`)
15
+ }
16
+
17
+ public async down(queryRunner: QueryRunner): Promise<void> {
18
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "expiresAt"`)
19
+ await queryRunner.query(`ALTER TABLE "StatusList" DROP COLUMN "bitsPerStatus"`)
20
+ await queryRunner.query(`ALTER TABLE "StatusList" ALTER COLUMN "statusPurpose" SET NOT NULL`)
21
+ await queryRunner.query(`ALTER TABLE "StatusList" ALTER COLUMN "indexingDirection" SET NOT NULL`)
22
+
23
+ // Note: Cannot remove enum value in Postgres, would need to recreate the type
24
+ }
25
+ }
@@ -5,20 +5,60 @@ export class CreateStatusList1693866470002 implements MigrationInterface {
5
5
 
6
6
  public async up(queryRunner: QueryRunner): Promise<void> {
7
7
  await queryRunner.query(
8
- `CREATE TABLE "StatusListEntry" ("statusListId" varchar NOT NULL, "statusListIndex" integer NOT NULL, "credentialId" varchar, "credentialHash" varchar(128), "correlationId" varchar(255), "value" varchar(50), PRIMARY KEY ("statusListId", "statusListIndex"))`,
8
+ `CREATE TABLE "StatusListEntry"
9
+ (
10
+ "statusListId" varchar NOT NULL,
11
+ "statusListIndex" integer NOT NULL,
12
+ "credentialId" varchar,
13
+ "credentialHash" varchar(128),
14
+ "correlationId" varchar(255),
15
+ "value" varchar(50),
16
+ PRIMARY KEY ("statusListId", "statusListIndex")
17
+ )`,
9
18
  )
10
19
  await queryRunner.query(
11
- `CREATE TABLE "StatusList" ("id" varchar PRIMARY KEY NOT NULL, "correlationId" varchar NOT NULL, "length" integer NOT NULL, "issuer" text NOT NULL, "type" varchar CHECK( "type" IN ('StatusList2021') ) NOT NULL DEFAULT ('StatusList2021'), "driverType" varchar CHECK( "driverType" IN ('agent_typeorm','agent_kv_store','github','agent_filesystem') ) NOT NULL DEFAULT ('agent_typeorm'), "credentialIdMode" varchar CHECK( "credentialIdMode" IN ('ISSUANCE','PERSISTENCE','NEVER') ) NOT NULL DEFAULT ('ISSUANCE'), "proofFormat" varchar CHECK( "proofFormat" IN ('lds','jwt') ) NOT NULL DEFAULT ('lds'), "indexingDirection" varchar CHECK( "indexingDirection" IN ('rightToLeft') ) NOT NULL DEFAULT ('rightToLeft'), "statusPurpose" varchar NOT NULL DEFAULT ('revocation'), "statusListCredential" text, CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId"))`,
20
+ `CREATE TABLE "StatusList"
21
+ (
22
+ "id" varchar PRIMARY KEY NOT NULL,
23
+ "correlationId" varchar NOT NULL,
24
+ "length" integer NOT NULL,
25
+ "issuer" text NOT NULL,
26
+ "type" varchar CHECK ( "type" IN ('StatusList2021') ) NOT NULL DEFAULT ('StatusList2021'),
27
+ "driverType" varchar CHECK ( "driverType" IN ('agent_typeorm', 'agent_kv_store', 'github',
28
+ 'agent_filesystem') ) NOT NULL DEFAULT ('agent_typeorm'),
29
+ "credentialIdMode" varchar CHECK ( "credentialIdMode" IN ('ISSUANCE', 'PERSISTENCE', 'NEVER') ) NOT NULL DEFAULT ('ISSUANCE'),
30
+ "proofFormat" varchar CHECK ( "proofFormat" IN ('lds', 'jwt') ) NOT NULL DEFAULT ('lds'),
31
+ "indexingDirection" varchar CHECK ( "indexingDirection" IN ('rightToLeft') ) NOT NULL DEFAULT ('rightToLeft'),
32
+ "statusPurpose" varchar NOT NULL DEFAULT ('revocation'),
33
+ "statusListCredential" text,
34
+ CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId")
35
+ )`,
12
36
  )
13
37
  await queryRunner.query(
14
- `CREATE TABLE "temporary_StatusListEntry" ("statusListId" varchar NOT NULL, "statusListIndex" integer NOT NULL, "credentialId" varchar, "credentialHash" varchar(128), "correlationId" varchar(255), "value" varchar(50), CONSTRAINT "FK_statusListEntry_statusListId" FOREIGN KEY ("statusListId") REFERENCES "StatusList" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, PRIMARY KEY ("statusListId", "statusListIndex"))`,
38
+ `CREATE TABLE "temporary_StatusListEntry"
39
+ (
40
+ "statusListId" varchar NOT NULL,
41
+ "statusListIndex" integer NOT NULL,
42
+ "credentialId" varchar,
43
+ "credentialHash" varchar(128),
44
+ "correlationId" varchar(255),
45
+ "value" varchar(50),
46
+ CONSTRAINT "FK_statusListEntry_statusListId" FOREIGN KEY ("statusListId") REFERENCES "StatusList" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
47
+ PRIMARY KEY ("statusListId", "statusListIndex")
48
+ )`,
15
49
  )
16
50
  await queryRunner.query(
17
- `INSERT INTO "temporary_StatusListEntry"("statusListId", "statusListIndex", "credentialId", "credentialHash", "correlationId", "value") SELECT "statusListId", "statusListIndex", "credentialId", "credentialHash", "correlationId", "value" FROM "StatusListEntry"`,
51
+ `INSERT INTO "temporary_StatusListEntry"("statusListId", "statusListIndex", "credentialId",
52
+ "credentialHash", "correlationId", "value")
53
+ SELECT "statusListId", "statusListIndex", "credentialId", "credentialHash", "correlationId", "value"
54
+ FROM "StatusListEntry"`,
18
55
  )
19
56
  await queryRunner.query(`DROP TABLE "StatusListEntry"`)
20
57
  await queryRunner.query(`ALTER TABLE "temporary_StatusListEntry" RENAME TO "StatusListEntry"`)
21
58
  }
22
59
 
23
- public async down(queryRunner: QueryRunner): Promise<void> {}
60
+ public async down(queryRunner: QueryRunner): Promise<void> {
61
+ await queryRunner.query(`DROP TABLE "StatusListEntry"`)
62
+ await queryRunner.query(`DROP TABLE "StatusList"`)
63
+ }
24
64
  }
@@ -0,0 +1,94 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm'
2
+
3
+ export class UpdateStatusList1737110469000 implements MigrationInterface {
4
+ name = 'UpdateStatusList1737110469000'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Create temporary table with new schema
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') ) 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
+ "bitsPerStatus" integer,
22
+ "expiresAt" datetime,
23
+ CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId")
24
+ )`,
25
+ )
26
+
27
+ // Copy data from old table to temporary table
28
+ await queryRunner.query(
29
+ `INSERT INTO "temporary_StatusList"(
30
+ "id", "correlationId", "length", "issuer", "type", "driverType",
31
+ "credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
32
+ "statusListCredential"
33
+ )
34
+ SELECT
35
+ "id", "correlationId", "length", "issuer", "type", "driverType",
36
+ "credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
37
+ "statusListCredential"
38
+ FROM "StatusList"`,
39
+ )
40
+
41
+ // Drop old table and rename temporary table
42
+ await queryRunner.query(`DROP TABLE "StatusList"`)
43
+ await queryRunner.query(`ALTER TABLE "temporary_StatusList" RENAME TO "StatusList"`)
44
+ }
45
+
46
+ public async down(queryRunner: QueryRunner): Promise<void> {
47
+ await queryRunner.query(`
48
+ ALTER TABLE "StatusListEntry"
49
+ RENAME COLUMN "entryCorrelationId" TO "correlationId"
50
+ `)
51
+
52
+ await queryRunner.query(`
53
+ ALTER TABLE "StatusListEntry"
54
+ DROP COLUMN "statusListCorrelationId"
55
+ `)
56
+
57
+ // Create temporary table with old schema
58
+ await queryRunner.query(
59
+ `CREATE TABLE "temporary_StatusList" (
60
+ "id" varchar PRIMARY KEY NOT NULL,
61
+ "correlationId" varchar NOT NULL,
62
+ "length" integer NOT NULL,
63
+ "issuer" text NOT NULL,
64
+ "type" varchar CHECK( "type" IN ('StatusList2021') ) NOT NULL DEFAULT ('StatusList2021'),
65
+ "driverType" varchar CHECK( "driverType" IN ('agent_typeorm','agent_kv_store','github','agent_filesystem') ) NOT NULL DEFAULT ('agent_typeorm'),
66
+ "credentialIdMode" varchar CHECK( "credentialIdMode" IN ('ISSUANCE','PERSISTENCE','NEVER') ) NOT NULL DEFAULT ('ISSUANCE'),
67
+ "proofFormat" varchar CHECK( "proofFormat" IN ('lds','jwt') ) NOT NULL DEFAULT ('lds'),
68
+ "indexingDirection" varchar CHECK( "indexingDirection" IN ('rightToLeft') ) NOT NULL DEFAULT ('rightToLeft'),
69
+ "statusPurpose" varchar NOT NULL DEFAULT ('revocation'),
70
+ "statusListCredential" text,
71
+ CONSTRAINT "UQ_correlationId" UNIQUE ("correlationId")
72
+ )`,
73
+ )
74
+
75
+ // Copy data back, excluding new columns
76
+ await queryRunner.query(
77
+ `INSERT INTO "temporary_StatusList"(
78
+ "id", "correlationId", "length", "issuer", "type", "driverType",
79
+ "credentialIdMode", "proofFormat", "indexingDirection", "statusPurpose",
80
+ "statusListCredential"
81
+ )
82
+ SELECT
83
+ "id", "correlationId", "length", "issuer",
84
+ CASE WHEN "type" = 'OAuthStatusList' THEN 'StatusList2021' ELSE "type" END,
85
+ "driverType", "credentialIdMode", "proofFormat", "indexingDirection",
86
+ COALESCE("statusPurpose", 'revocation'), "statusListCredential"
87
+ FROM "StatusList"`,
88
+ )
89
+
90
+ // Drop new table and rename temporary table back
91
+ await queryRunner.query(`DROP TABLE "StatusList"`)
92
+ await queryRunner.query(`ALTER TABLE "temporary_StatusList" RENAME TO "StatusList"`)
93
+ }
94
+ }
@@ -1,4 +1,4 @@
1
- import { StatusListEntryEntity } from '../entities/statusList2021/StatusList2021EntryEntity'
1
+ import { StatusListEntryEntity } from '../entities/statusList/StatusList2021EntryEntity'
2
2
  import {
3
3
  IAddStatusListArgs,
4
4
  IAddStatusListEntryArgs,
@@ -18,7 +18,7 @@ export interface IStatusListStore {
18
18
 
19
19
  getStatusLists(args: IGetStatusListsArgs): Promise<Array<IStatusListEntity>>
20
20
 
21
- removeStatusList(args: IRemoveStatusListArgs): Promise<void>
21
+ removeStatusList(args: IRemoveStatusListArgs): Promise<boolean>
22
22
 
23
23
  addStatusList(args: IAddStatusListArgs): Promise<IStatusListEntity>
24
24