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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/entities/issuanceBranding/CredentialLocaleBrandingEntity.js +1 -1
  2. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts +13 -0
  3. package/dist/entities/oid4vcState/Oid4vcStateEntity.d.ts.map +1 -0
  4. package/dist/entities/oid4vcState/Oid4vcStateEntity.js +57 -0
  5. package/dist/entities/oid4vcState/Oid4vcStateEntity.js.map +1 -0
  6. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.d.ts +1 -0
  7. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.d.ts.map +1 -1
  8. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.js +8 -2
  9. package/dist/entities/presentationDefinition/PresentationDefinitionItemEntity.js.map +1 -1
  10. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.d.ts +4 -3
  11. package/dist/entities/statusList/StatusList2021EntryEntity.d.ts.map +1 -0
  12. package/dist/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.js +11 -6
  13. package/dist/entities/statusList/StatusList2021EntryEntity.js.map +1 -0
  14. package/dist/entities/statusList/StatusListEntities.d.ts +23 -0
  15. package/dist/entities/statusList/StatusListEntities.d.ts.map +1 -0
  16. package/dist/entities/{statusList2021/StatusList2021Entity.js → statusList/StatusListEntities.js} +45 -16
  17. package/dist/entities/statusList/StatusListEntities.js.map +1 -0
  18. package/dist/index.d.ts +5 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +10 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.d.ts +7 -0
  23. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.d.ts.map +1 -0
  24. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.js +80 -0
  25. package/dist/migrations/generic/11-FixCredentialClaimsReferenceUuid.js.map +1 -0
  26. package/dist/migrations/generic/4-CreateStatusList.d.ts.map +1 -1
  27. package/dist/migrations/generic/4-CreateStatusList.js +22 -12
  28. package/dist/migrations/generic/4-CreateStatusList.js.map +1 -1
  29. package/dist/migrations/generic/index.d.ts.map +1 -1
  30. package/dist/migrations/generic/index.js +2 -1
  31. package/dist/migrations/generic/index.js.map +1 -1
  32. package/dist/migrations/postgres/1693866470001-CreateStatusList.d.ts.map +1 -1
  33. package/dist/migrations/postgres/1693866470001-CreateStatusList.js +40 -7
  34. package/dist/migrations/postgres/1693866470001-CreateStatusList.js.map +1 -1
  35. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.d.ts.map +1 -1
  36. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js +1 -0
  37. package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js.map +1 -1
  38. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts +7 -0
  39. package/dist/migrations/postgres/1737110469001-UpdateStatusList.d.ts.map +1 -0
  40. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js +39 -0
  41. package/dist/migrations/postgres/1737110469001-UpdateStatusList.js.map +1 -0
  42. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.d.ts +7 -0
  43. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.d.ts.map +1 -0
  44. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.js +37 -0
  45. package/dist/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.js.map +1 -0
  46. package/dist/migrations/sqlite/1693866470000-CreateStatusList.d.ts.map +1 -1
  47. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js +45 -5
  48. package/dist/migrations/sqlite/1693866470000-CreateStatusList.js.map +1 -1
  49. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.d.ts.map +1 -1
  50. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js +1 -0
  51. package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js.map +1 -1
  52. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts +7 -0
  53. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.d.ts.map +1 -0
  54. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js +96 -0
  55. package/dist/migrations/sqlite/1737110469000-UpdateStatusList.js.map +1 -0
  56. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.d.ts +7 -0
  57. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.d.ts.map +1 -0
  58. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.js +80 -0
  59. package/dist/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.js.map +1 -0
  60. package/dist/statusList/IStatusListStore.d.ts +2 -2
  61. package/dist/statusList/IStatusListStore.d.ts.map +1 -1
  62. package/dist/statusList/StatusListStore.d.ts +9 -8
  63. package/dist/statusList/StatusListStore.d.ts.map +1 -1
  64. package/dist/statusList/StatusListStore.js +72 -42
  65. package/dist/statusList/StatusListStore.js.map +1 -1
  66. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts +2 -2
  67. package/dist/types/digitalCredential/IAbstractDigitalCredentialStore.d.ts.map +1 -1
  68. package/dist/types/presentationDefinition/presentationDefinition.d.ts +3 -1
  69. package/dist/types/presentationDefinition/presentationDefinition.d.ts.map +1 -1
  70. package/dist/types/statusList/IAbstractStatusListStore.d.ts +5 -4
  71. package/dist/types/statusList/IAbstractStatusListStore.d.ts.map +1 -1
  72. package/dist/types/statusList/statusList.d.ts +13 -7
  73. package/dist/types/statusList/statusList.d.ts.map +1 -1
  74. package/dist/utils/digitalCredential/MappingUtils.d.ts.map +1 -1
  75. package/dist/utils/digitalCredential/MappingUtils.js +7 -6
  76. package/dist/utils/digitalCredential/MappingUtils.js.map +1 -1
  77. package/dist/utils/presentationDefinition/MappingUtils.d.ts.map +1 -1
  78. package/dist/utils/presentationDefinition/MappingUtils.js +2 -0
  79. package/dist/utils/presentationDefinition/MappingUtils.js.map +1 -1
  80. package/dist/utils/statusList/MappingUtils.d.ts +5 -0
  81. package/dist/utils/statusList/MappingUtils.d.ts.map +1 -0
  82. package/dist/utils/statusList/MappingUtils.js +69 -0
  83. package/dist/utils/statusList/MappingUtils.js.map +1 -0
  84. package/package.json +9 -8
  85. package/src/__tests__/digitalCredential.entities.test.ts +2 -2
  86. package/src/__tests__/digitalCredential.store.test.ts +2 -2
  87. package/src/__tests__/pd-manager.entities.test.ts +77 -0
  88. package/src/__tests__/statusList.entities.test.ts +216 -0
  89. package/src/__tests__/statusList.store.test.ts +232 -0
  90. package/src/entities/issuanceBranding/CredentialLocaleBrandingEntity.ts +1 -1
  91. package/src/entities/oid4vcState/Oid4vcStateEntity.ts +32 -0
  92. package/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +6 -2
  93. package/src/entities/{statusList2021 → statusList}/StatusList2021EntryEntity.ts +10 -6
  94. package/src/entities/{statusList2021/StatusList2021Entity.ts → statusList/StatusListEntities.ts} +38 -18
  95. package/src/index.ts +8 -3
  96. package/src/migrations/generic/11-FixCredentialClaimsReferenceUuid.ts +66 -0
  97. package/src/migrations/generic/4-CreateStatusList.ts +22 -12
  98. package/src/migrations/generic/index.ts +2 -1
  99. package/src/migrations/postgres/1693866470001-CreateStatusList.ts +42 -9
  100. package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +1 -0
  101. package/src/migrations/postgres/1737110469001-UpdateStatusList.ts +25 -0
  102. package/src/migrations/postgres/1741895822987-FixCredentialClaimsReferencesUuid.ts +21 -0
  103. package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +45 -5
  104. package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +1 -0
  105. package/src/migrations/sqlite/1737110469000-UpdateStatusList.ts +94 -0
  106. package/src/migrations/sqlite/1741895822987-FixCredentialClaimsReferencesUuid.ts +73 -0
  107. package/src/statusList/IStatusListStore.ts +2 -2
  108. package/src/statusList/StatusListStore.ts +94 -51
  109. package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +2 -2
  110. package/src/types/presentationDefinition/presentationDefinition.ts +3 -1
  111. package/src/types/statusList/IAbstractStatusListStore.ts +5 -4
  112. package/src/types/statusList/statusList.ts +24 -16
  113. package/src/utils/digitalCredential/MappingUtils.ts +3 -2
  114. package/src/utils/presentationDefinition/MappingUtils.ts +3 -0
  115. package/src/utils/statusList/MappingUtils.ts +82 -0
  116. package/dist/entities/statusList2021/StatusList2021Entity.d.ts +0 -19
  117. package/dist/entities/statusList2021/StatusList2021Entity.d.ts.map +0 -1
  118. package/dist/entities/statusList2021/StatusList2021Entity.js.map +0 -1
  119. package/dist/entities/statusList2021/StatusList2021EntryEntity.d.ts.map +0 -1
  120. package/dist/entities/statusList2021/StatusList2021EntryEntity.js.map +0 -1
@@ -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
  }
@@ -13,6 +13,7 @@ CREATE TABLE "PresentationDefinitionItem" (
13
13
  "version" TEXT NOT NULL,
14
14
  "purpose" TEXT,
15
15
  "definition_payload" TEXT NOT NULL,
16
+ "dcql_payload" TEXT,
16
17
  "created_at" TIMESTAMP NOT NULL DEFAULT now(),
17
18
  "last_updated_at" TIMESTAMP NOT NULL DEFAULT now(),
18
19
  CONSTRAINT "PK_PresentationDefinitionItem_id" PRIMARY KEY ("id"))
@@ -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
+ }
@@ -0,0 +1,21 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm'
2
+
3
+ export class FixCredentialClaimsReferencesUuidPG1741895822987 implements MigrationInterface {
4
+ name = 'FixCredentialClaimsReferencesUuid1741895822987'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Migrate varchar to uuid
8
+ await queryRunner.query(`
9
+ ALTER TABLE "CredentialClaims"
10
+ ALTER COLUMN "credentialLocaleBrandingId" TYPE uuid USING "credentialLocaleBrandingId"::uuid;
11
+ `)
12
+ }
13
+
14
+ public async down(queryRunner: QueryRunner): Promise<void> {
15
+ // Migrate uuid back to varchar
16
+ await queryRunner.query(`
17
+ ALTER TABLE "CredentialClaims"
18
+ ALTER COLUMN "credentialLocaleBrandingId" TYPE character varying USING "credentialLocaleBrandingId"::text;
19
+ `)
20
+ }
21
+ }
@@ -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
  }
@@ -13,6 +13,7 @@ export class CreatePresentationDefinitions1716475165344 implements MigrationInte
13
13
  "version" varchar NOT NULL,
14
14
  "purpose" varchar,
15
15
  "definition_payload" varchar NOT NULL,
16
+ "dcql_payload" varchar,
16
17
  "created_at" datetime NOT NULL DEFAULT (datetime('now')),
17
18
  "last_updated_at" datetime NOT NULL DEFAULT (datetime('now')))`,
18
19
  )
@@ -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
+ }
@@ -0,0 +1,73 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm'
2
+
3
+ export class FixCredentialClaimsReferencesUuidSqlite1741895822987 implements MigrationInterface {
4
+ name = 'FixCredentialClaimsReferencesUuid1741895822987'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Create a new table with the updated column type (uuid)
8
+ await queryRunner.query(`
9
+ CREATE TABLE "CredentialClaims_new"
10
+ (
11
+ "id" uuid NOT NULL DEFAULT (lower(hex(randomblob(16)))),
12
+ "key" character varying(255) NOT NULL,
13
+ "name" character varying(255) NOT NULL,
14
+ "credentialLocaleBrandingId" uuid,
15
+ CONSTRAINT "PK_CredentialClaims_id" PRIMARY KEY ("id")
16
+ )
17
+ `)
18
+
19
+ // Copy data from the old table
20
+ await queryRunner.query(`
21
+ INSERT INTO "CredentialClaims_new" ("id", "key", "name", "credentialLocaleBrandingId")
22
+ SELECT "id", "key", "name", "credentialLocaleBrandingId"
23
+ FROM "CredentialClaims"
24
+ `)
25
+
26
+ // Drop the old table
27
+ await queryRunner.query(`DROP TABLE "CredentialClaims"`)
28
+
29
+ // Rename the new table to the original name
30
+ await queryRunner.query(`ALTER TABLE "CredentialClaims_new" RENAME TO "CredentialClaims"`)
31
+
32
+ // Recreate the unique index
33
+ await queryRunner.query(`
34
+ CREATE UNIQUE INDEX "IDX_CredentialClaimsEntity_credentialLocaleBranding_locale"
35
+ ON "CredentialClaims" ("credentialLocaleBrandingId", "key")
36
+ `)
37
+ }
38
+
39
+ public async down(queryRunner: QueryRunner): Promise<void> {
40
+ // Migrate uuid back to varchar
41
+
42
+ // Create a new table reverting the column back to character varying
43
+ await queryRunner.query(`
44
+ CREATE TABLE "CredentialClaims_old"
45
+ (
46
+ "id" uuid NOT NULL DEFAULT (lower(hex(randomblob(16)))),
47
+ "key" character varying(255) NOT NULL,
48
+ "name" character varying(255) NOT NULL,
49
+ "credentialLocaleBrandingId" character varying,
50
+ CONSTRAINT "PK_CredentialClaims_id" PRIMARY KEY ("id")
51
+ )
52
+ `)
53
+
54
+ // Copy data from the current table
55
+ await queryRunner.query(`
56
+ INSERT INTO "CredentialClaims_old" ("id", "key", "name", "credentialLocaleBrandingId")
57
+ SELECT "id", "key", "name", "credentialLocaleBrandingId"
58
+ FROM "CredentialClaims"
59
+ `)
60
+
61
+ // Drop the current table
62
+ await queryRunner.query(`DROP TABLE "CredentialClaims"`)
63
+
64
+ // Rename the new table back to the original name
65
+ await queryRunner.query(`ALTER TABLE "CredentialClaims_old" RENAME TO "CredentialClaims"`)
66
+
67
+ // Recreate the unique index
68
+ await queryRunner.query(`
69
+ CREATE UNIQUE INDEX "IDX_CredentialClaimsEntity_credentialLocaleBranding_locale"
70
+ ON "CredentialClaims" ("credentialLocaleBrandingId", "key")
71
+ `)
72
+ }
73
+ }
@@ -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
 
@@ -1,8 +1,8 @@
1
- import { OrPromise } from '@sphereon/ssi-types'
1
+ import { OrPromise, StatusListType } from '@sphereon/ssi-types'
2
2
  import Debug from 'debug'
3
3
  import { DataSource, In, Repository } from 'typeorm'
4
- import { StatusListEntity } from '../entities/statusList2021/StatusList2021Entity'
5
- import { StatusListEntryEntity } from '../entities/statusList2021/StatusList2021EntryEntity'
4
+ import { OAuthStatusListEntity, StatusList2021Entity, StatusListEntity } from '../entities/statusList/StatusListEntities'
5
+ import { StatusListEntryEntity } from '../entities/statusList/StatusList2021EntryEntity'
6
6
  import {
7
7
  IAddStatusListArgs,
8
8
  IAddStatusListEntryArgs,
@@ -12,12 +12,13 @@ import {
12
12
  IGetStatusListEntryByIndexArgs,
13
13
  IGetStatusListsArgs,
14
14
  IRemoveStatusListArgs,
15
- IStatusListEntryAvailableArgs,
16
- IUpdateStatusListIndexArgs,
17
15
  IStatusListEntity,
16
+ IStatusListEntryAvailableArgs,
18
17
  IStatusListEntryEntity,
18
+ IUpdateStatusListIndexArgs,
19
19
  } from '../types'
20
20
  import { IStatusListStore } from './IStatusListStore'
21
+ import { statusListEntityFrom, statusListFrom } from '../utils/statusList/MappingUtils'
21
22
 
22
23
  const debug = Debug('sphereon:ssi-sdk:data-store:status-list')
23
24
 
@@ -57,7 +58,7 @@ export class StatusListStore implements IStatusListStore {
57
58
  }
58
59
 
59
60
  async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<IStatusListEntryEntity> {
60
- const statusListId = typeof args.statusList === 'string' ? args.statusList : args.statusList.id
61
+ const statusListId = args.statusListId ?? args.statusList?.id
61
62
  const result = await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: false })
62
63
  const updatedEntry: Partial<IStatusListEntryEntity> = {
63
64
  value: args.value,
@@ -66,56 +67,55 @@ export class StatusListStore implements IStatusListStore {
66
67
  credentialId: args.credentialId,
67
68
  }
68
69
 
70
+ const updStatusListId = result?.statusListId ?? statusListId
69
71
  const updateResult = await (
70
72
  await this.getStatusListEntryRepo()
71
73
  ).upsert(
72
- { ...(result ?? { statusList: args.statusList, statusListIndex: args.statusListIndex }), ...updatedEntry },
74
+ { ...(result ?? { statusListId: updStatusListId, statusListIndex: args.statusListIndex }), ...updatedEntry },
73
75
  { conflictPaths: ['statusList', 'statusListIndex'] },
74
76
  )
75
77
  console.log(updateResult)
76
- return (await this.getStatusListEntryByIndex({ ...args, statusListId, errorOnNotFound: true })) as IStatusListEntryEntity
78
+ return (await this.getStatusListEntryByIndex({
79
+ ...args,
80
+ statusListId: updStatusListId,
81
+ errorOnNotFound: true,
82
+ })) as IStatusListEntryEntity
77
83
  }
78
84
 
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`)
85
+ async getStatusListEntryByIndex({
86
+ statusListId,
87
+ statusListCorrelationId,
88
+ statusListIndex,
89
+ entryCorrelationId,
90
+ errorOnNotFound,
91
+ }: IGetStatusListEntryByIndexArgs): Promise<StatusListEntryEntity | undefined> {
92
+ if (!statusListId && !statusListCorrelationId) {
93
+ throw Error(`Cannot get statusList entry without either a statusList id or statusListCorrelationId`)
82
94
  }
95
+
96
+ if (!statusListIndex && !entryCorrelationId) {
97
+ throw Error(`Cannot get statusList entry without either a statusListIndex or entryCorrelationId`)
98
+ }
99
+
83
100
  const result = await (
84
101
  await this.getStatusListEntryRepo()
85
102
  ).findOne({
86
103
  where: {
87
- ...(args.statusListId && { statusList: args.statusListId }),
88
- ...(args.correlationId && { correlationId: args.correlationId }),
89
- statusListIndex: args.statusListIndex,
104
+ ...(statusListId && { statusListId }),
105
+ ...(!statusListId && statusListCorrelationId && { statusList: { correlationId: statusListCorrelationId } }),
106
+ ...(statusListIndex && { statusListIndex }),
107
+ ...(entryCorrelationId && { entryCorrelationId }),
108
+ },
109
+ relations: {
110
+ statusList: true,
90
111
  },
91
112
  })
92
113
 
93
- if (!result && args.errorOnNotFound) {
94
- throw Error(`Could not find status list index ${args.statusListIndex} for status list id ${args.statusListId}`)
114
+ if (!result && errorOnNotFound) {
115
+ throw Error(`Could not find status list entry with provided filters`)
95
116
  }
96
- return result ?? undefined
97
- }
98
117
 
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
118
+ return result ?? undefined
119
119
  }
120
120
 
121
121
  async getStatusListEntryByCredentialId(args: IGetStatusListEntryByCredentialIdArgs): Promise<StatusListEntryEntity | undefined> {
@@ -123,9 +123,12 @@ export class StatusListStore implements IStatusListStore {
123
123
  if (!credentialId) {
124
124
  throw Error('Can only get a credential by credentialId when a credentialId is supplied')
125
125
  }
126
- const statusList = await this.getStatusList({ id: args.statusListId, correlationId: args.statusListCorrelationId })
126
+ const statusList = await this.getStatusList({
127
+ id: args.statusListId,
128
+ correlationId: args.statusListCorrelationId,
129
+ })
127
130
  const where = {
128
- statusList: statusList.id,
131
+ statusList: { id: statusList.id },
129
132
  ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
130
133
  credentialId,
131
134
  }
@@ -158,11 +161,37 @@ export class StatusListStore implements IStatusListStore {
158
161
  return !error
159
162
  }
160
163
 
164
+ async removeStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<boolean> {
165
+ let error = false
166
+ try {
167
+ await this.getStatusListEntryByIndex(args)
168
+ } catch (error) {
169
+ error = true
170
+ }
171
+ if (error) {
172
+ console.log(`Could not delete statusList ${args.statusListId} entry by index ${args.statusListIndex}`)
173
+ } else {
174
+ const result = await (
175
+ await this.getStatusListEntryRepo()
176
+ ).delete({
177
+ ...(args.statusListId && { statusList: args.statusListId }),
178
+ ...(args.entryCorrelationId && { correlationId: args.entryCorrelationId }),
179
+ statusListIndex: args.statusListIndex,
180
+ })
181
+ error = !result.affected || result.affected !== 1
182
+ }
183
+ return !error
184
+ }
185
+
161
186
  async getStatusListEntries(args: IGetStatusListEntriesArgs): Promise<StatusListEntryEntity[]> {
162
187
  return (await this.getStatusListEntryRepo()).find({ where: { ...args?.filter, statusList: args.statusListId } })
163
188
  }
164
189
 
165
190
  async getStatusList(args: IGetStatusListArgs): Promise<IStatusListEntity> {
191
+ return statusListFrom(await this.getStatusListEntity(args))
192
+ }
193
+
194
+ private async getStatusListEntity(args: IGetStatusListArgs): Promise<StatusListEntity> {
166
195
  if (!args.id && !args.correlationId) {
167
196
  throw Error(`At least and 'id' or 'correlationId' needs to be provided to lookup a status list`)
168
197
  }
@@ -189,7 +218,8 @@ export class StatusListStore implements IStatusListStore {
189
218
  if (!result) {
190
219
  return []
191
220
  }
192
- return result
221
+
222
+ return result.map((entity) => statusListFrom(entity))
193
223
  }
194
224
 
195
225
  async addStatusList(args: IAddStatusListArgs): Promise<IStatusListEntity> {
@@ -205,29 +235,42 @@ export class StatusListStore implements IStatusListStore {
205
235
  }
206
236
 
207
237
  debug('Adding status list ', id)
208
- const createdResult = await (await this.getStatusListRepo()).save(args)
209
-
210
- return createdResult
238
+ const entity = statusListEntityFrom(args)
239
+ const createdResult = await (await this.getStatusListRepo(args.type)).save(entity)
240
+ return statusListFrom(createdResult)
211
241
  }
212
242
 
213
243
  async updateStatusList(args: IUpdateStatusListIndexArgs): Promise<IStatusListEntity> {
214
244
  const result = await this.getStatusList(args)
215
245
  debug('Updating status list', result)
216
- const updatedResult = await (await this.getStatusListRepo()).save(args, { transaction: true })
217
- return updatedResult
246
+ const entity = statusListEntityFrom(args)
247
+ const updatedResult = await (await this.getStatusListRepo(args.type)).save(entity, { transaction: true })
248
+ return statusListFrom(updatedResult)
218
249
  }
219
250
 
220
- async removeStatusList(args: IRemoveStatusListArgs): Promise<void> {
221
- const result = await this.getStatusList(args)
222
- await (await this.getStatusListRepo()).delete(result)
251
+ async removeStatusList(args: IRemoveStatusListArgs): Promise<boolean> {
252
+ const result = await this.getStatusListEntity(args)
253
+
254
+ await (await this.getStatusListEntryRepo()).delete({ statusListId: result.id })
255
+ const deletedEntity = await (await this.getStatusListRepo()).remove(result)
256
+
257
+ return Boolean(deletedEntity)
223
258
  }
224
259
 
225
260
  private async getDS(): Promise<DataSource> {
226
261
  return this._dbConnection
227
262
  }
228
263
 
229
- async getStatusListRepo(): Promise<Repository<StatusListEntity>> {
230
- return (await this.getDS()).getRepository(StatusListEntity)
264
+ async getStatusListRepo(type?: StatusListType): Promise<Repository<StatusListEntity>> {
265
+ const dataSource = await this.getDS()
266
+ switch (type) {
267
+ case StatusListType.StatusList2021:
268
+ return dataSource.getRepository(StatusList2021Entity)
269
+ case StatusListType.OAuthStatusList:
270
+ return dataSource.getRepository(OAuthStatusListEntity)
271
+ default:
272
+ return dataSource.getRepository(StatusListEntity)
273
+ }
231
274
  }
232
275
 
233
276
  async getStatusListEntryRepo(): Promise<Repository<StatusListEntryEntity>> {
@@ -1,5 +1,5 @@
1
1
  import { CredentialCorrelationType, CredentialRole, CredentialStateType, DigitalCredential, RegulationType } from './digitalCredential'
2
- import { Hasher } from '@sphereon/ssi-types'
2
+ import { HasherSync } from '@sphereon/ssi-types'
3
3
  import { FindOptionsOrder } from 'typeorm'
4
4
  import { DigitalCredentialEntity } from '../../entities/digitalCredential/DigitalCredentialEntity'
5
5
 
@@ -34,7 +34,7 @@ export type AddCredentialArgs = {
34
34
  state?: CredentialStateType
35
35
  verifiedAt?: Date
36
36
  revokedAt?: Date
37
- opts?: { maxTimeSkewInMS?: number; hasher?: Hasher }
37
+ opts?: { maxTimeSkewInMS?: number; hasher?: HasherSync }
38
38
  }
39
39
 
40
40
  export type UpdateCredentialStateArgs = GetCredentialArgs & { verifiedState: CredentialStateType; verifiedAt?: Date; revokedAt?: Date }