@sphereon/ssi-sdk.data-store 0.34.1-feature.SSISDK.57.uni.client.206 → 0.34.1-feature.SSISDK.58.host.nonce.endpoint.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +174 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -32
- package/dist/index.d.ts +33 -32
- package/dist/index.js +174 -105
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/__tests__/pd-manager.entities.test.ts +69 -21
- package/src/__tests__/pd-manager.store.test.ts +194 -111
- package/src/entities/presentationDefinition/{DcqlQueryItemEntity.ts → PresentationDefinitionItemEntity.ts} +12 -8
- package/src/index.ts +3 -3
- package/src/migrations/generic/{13-CreateDcqlQueryItem.ts → 13-UpdatePresentationDefinitionItemNullable.ts} +8 -8
- package/src/migrations/generic/index.ts +5 -2
- package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +1 -1
- package/src/migrations/postgres/1756975509000-UpdatePresentationDefinitionItemNullable.ts +15 -0
- package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +1 -1
- package/src/migrations/sqlite/1756975340000-UpdatePresentationDefinitionItemNullable.ts +77 -0
- package/src/presentationDefinition/AbstractPDStore.ts +5 -5
- package/src/presentationDefinition/PDStore.ts +45 -40
- package/src/types/presentationDefinition/IAbstractPDStore.ts +5 -5
- package/src/types/presentationDefinition/presentationDefinition.ts +9 -8
- package/src/utils/presentationDefinition/MappingUtils.ts +41 -21
- package/src/migrations/postgres/1726588800000-CreateDcqlQueryItem.ts +0 -25
- package/src/migrations/sqlite/1726617600000-CreateDcqlQueryItem.ts +0 -24
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import Debug from 'debug'
|
|
2
2
|
import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { UpdatePresentationDefinitionItemNullablePG1741895824000 } from '../postgres/1756975509000-UpdatePresentationDefinitionItemNullable'
|
|
5
|
+
import { UpdatePresentationDefinitionItemNullableSqlite1756975340000 } from '../sqlite/1756975340000-UpdatePresentationDefinitionItemNullable'
|
|
6
6
|
|
|
7
7
|
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations')
|
|
8
8
|
|
|
9
|
-
export class
|
|
10
|
-
name = '
|
|
9
|
+
export class UpdatePresentationDefinitionItemNullable1741895824000 implements MigrationInterface {
|
|
10
|
+
name = 'UpdatePresentationDefinitionItemNullable1741895824000'
|
|
11
11
|
|
|
12
12
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
13
13
|
debug('migration: updating presentation definition item nullable fields')
|
|
@@ -16,7 +16,7 @@ export class CreateDcqlQueryItem1726617600000 implements MigrationInterface {
|
|
|
16
16
|
switch (dbType) {
|
|
17
17
|
case 'postgres': {
|
|
18
18
|
debug('using postgres migration file')
|
|
19
|
-
const mig:
|
|
19
|
+
const mig: UpdatePresentationDefinitionItemNullablePG1741895824000 = new UpdatePresentationDefinitionItemNullablePG1741895824000()
|
|
20
20
|
await mig.up(queryRunner)
|
|
21
21
|
debug('Migration statements executed')
|
|
22
22
|
return
|
|
@@ -25,7 +25,7 @@ export class CreateDcqlQueryItem1726617600000 implements MigrationInterface {
|
|
|
25
25
|
case 'expo':
|
|
26
26
|
case 'react-native': {
|
|
27
27
|
debug('using sqlite/react-native migration file')
|
|
28
|
-
const mig:
|
|
28
|
+
const mig: UpdatePresentationDefinitionItemNullableSqlite1756975340000 = new UpdatePresentationDefinitionItemNullableSqlite1756975340000()
|
|
29
29
|
await mig.up(queryRunner)
|
|
30
30
|
debug('Migration statements executed')
|
|
31
31
|
return
|
|
@@ -44,7 +44,7 @@ export class CreateDcqlQueryItem1726617600000 implements MigrationInterface {
|
|
|
44
44
|
switch (dbType) {
|
|
45
45
|
case 'postgres': {
|
|
46
46
|
debug('using postgres migration file')
|
|
47
|
-
const mig:
|
|
47
|
+
const mig: UpdatePresentationDefinitionItemNullablePG1741895824000 = new UpdatePresentationDefinitionItemNullablePG1741895824000()
|
|
48
48
|
await mig.down(queryRunner)
|
|
49
49
|
debug('Migration statements executed')
|
|
50
50
|
return
|
|
@@ -53,7 +53,7 @@ export class CreateDcqlQueryItem1726617600000 implements MigrationInterface {
|
|
|
53
53
|
case 'expo':
|
|
54
54
|
case 'react-native': {
|
|
55
55
|
debug('using sqlite/react-native migration file')
|
|
56
|
-
const mig:
|
|
56
|
+
const mig: UpdatePresentationDefinitionItemNullableSqlite1756975340000 = new UpdatePresentationDefinitionItemNullableSqlite1756975340000()
|
|
57
57
|
await mig.down(queryRunner)
|
|
58
58
|
debug('Migration statements executed')
|
|
59
59
|
return
|
|
@@ -2,7 +2,7 @@ import { CreateContacts1659463079429 } from './1-CreateContacts'
|
|
|
2
2
|
import { CreatePresentationDefinitions1716533767523 } from './10-CreatePresentationDefinitions'
|
|
3
3
|
import { FixCredentialClaimsReferencesUuid1741895822987 } from './11-FixCredentialClaimsReferenceUuid'
|
|
4
4
|
import { AddBitstringStatusListEnum1741895823000, CreateBitstringStatusList1741895823000 } from './12-CreateBitstringStatusList'
|
|
5
|
-
import {
|
|
5
|
+
import { UpdatePresentationDefinitionItemNullable1741895824000 } from './13-UpdatePresentationDefinitionItemNullable'
|
|
6
6
|
import { CreateIssuanceBranding1659463079429 } from './2-CreateIssuanceBranding'
|
|
7
7
|
import { CreateContacts1690925872318 } from './3-CreateContacts'
|
|
8
8
|
import { CreateStatusList1693866470000 } from './4-CreateStatusList'
|
|
@@ -36,7 +36,10 @@ export const DataStoreStatusListMigrations = [
|
|
|
36
36
|
export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330]
|
|
37
37
|
export const DataStoreDigitalCredentialMigrations = [CreateDigitalCredential1708525189000]
|
|
38
38
|
export const DataStoreMachineStateMigrations = [CreateMachineStateStore1708098041262]
|
|
39
|
-
export const DataStorePresentationDefinitionMigrations = [
|
|
39
|
+
export const DataStorePresentationDefinitionMigrations = [
|
|
40
|
+
CreatePresentationDefinitions1716533767523,
|
|
41
|
+
UpdatePresentationDefinitionItemNullable1741895824000,
|
|
42
|
+
]
|
|
40
43
|
|
|
41
44
|
// All migrations together
|
|
42
45
|
export const DataStoreMigrations = [
|
|
@@ -13,7 +13,7 @@ CREATE TABLE "PresentationDefinitionItem" (
|
|
|
13
13
|
"version" TEXT NOT NULL,
|
|
14
14
|
"purpose" TEXT,
|
|
15
15
|
"definition_payload" TEXT NOT NULL,
|
|
16
|
-
"
|
|
16
|
+
"dcql_payload" TEXT,
|
|
17
17
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
18
18
|
"last_updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
19
19
|
CONSTRAINT "PK_PresentationDefinitionItem_id" PRIMARY KEY ("id"))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
export class UpdatePresentationDefinitionItemNullablePG1741895824000 implements MigrationInterface {
|
|
4
|
+
name = 'UpdatePresentationDefinitionItemNullable1741895824000'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
// Make definition_payload nullable
|
|
8
|
+
await queryRunner.query(`ALTER TABLE "PresentationDefinitionItem" ALTER COLUMN "definition_payload" DROP NOT NULL`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
12
|
+
// Make definition_payload NOT NULL again
|
|
13
|
+
await queryRunner.query(`ALTER TABLE "PresentationDefinitionItem" ALTER COLUMN "definition_payload" SET NOT NULL`)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -13,7 +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
|
-
"
|
|
16
|
+
"dcql_payload" varchar,
|
|
17
17
|
"created_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
18
18
|
"last_updated_at" datetime NOT NULL DEFAULT (datetime('now')))`,
|
|
19
19
|
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
+
|
|
3
|
+
export class UpdatePresentationDefinitionItemNullableSqlite1756975340000 implements MigrationInterface {
|
|
4
|
+
name = 'UpdatePresentationDefinitionItemNullable1756975340000'
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
// Create temporary table with updated schema (definition_payload nullable)
|
|
8
|
+
await queryRunner.query(`
|
|
9
|
+
CREATE TABLE "temporary_PresentationDefinitionItem" (
|
|
10
|
+
"id" varchar PRIMARY KEY NOT NULL,
|
|
11
|
+
"definition_id" varchar(255) NOT NULL,
|
|
12
|
+
"version" varchar(255) NOT NULL,
|
|
13
|
+
"tenant_id" varchar(255),
|
|
14
|
+
"purpose" varchar(255),
|
|
15
|
+
"name" varchar(255),
|
|
16
|
+
"definition_payload" text,
|
|
17
|
+
"dcql_payload" text,
|
|
18
|
+
"created_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
19
|
+
"last_updated_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
20
|
+
CONSTRAINT "UQ_PresentationDefinitionItem_definition_id_version" UNIQUE ("definition_id", "version")
|
|
21
|
+
)
|
|
22
|
+
`)
|
|
23
|
+
|
|
24
|
+
// Copy data from old table
|
|
25
|
+
await queryRunner.query(`
|
|
26
|
+
INSERT INTO "temporary_PresentationDefinitionItem"(
|
|
27
|
+
"id", "definition_id", "version", "tenant_id", "purpose", "name",
|
|
28
|
+
"definition_payload", "dcql_payload", "created_at", "last_updated_at"
|
|
29
|
+
)
|
|
30
|
+
SELECT
|
|
31
|
+
"id", "definition_id", "version", "tenant_id", "purpose", "name",
|
|
32
|
+
"definition_payload", "dcql_payload", "created_at", "last_updated_at"
|
|
33
|
+
FROM "PresentationDefinitionItem"
|
|
34
|
+
`)
|
|
35
|
+
|
|
36
|
+
// Drop old table and rename
|
|
37
|
+
await queryRunner.query(`DROP TABLE "PresentationDefinitionItem"`)
|
|
38
|
+
await queryRunner.query(`ALTER TABLE "temporary_PresentationDefinitionItem" RENAME TO "PresentationDefinitionItem"`)
|
|
39
|
+
|
|
40
|
+
// Recreate index
|
|
41
|
+
await queryRunner.query(`CREATE INDEX "IDX_PresentationDefinitionItem_version" ON "PresentationDefinitionItem" ("version")`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
45
|
+
// Revert to original schema (definition_payload NOT NULL, dcql_payload nullable)
|
|
46
|
+
await queryRunner.query(`
|
|
47
|
+
CREATE TABLE "temporary_PresentationDefinitionItem" (
|
|
48
|
+
"id" varchar PRIMARY KEY NOT NULL,
|
|
49
|
+
"definition_id" varchar(255) NOT NULL,
|
|
50
|
+
"version" varchar(255) NOT NULL,
|
|
51
|
+
"tenant_id" varchar(255),
|
|
52
|
+
"purpose" varchar(255),
|
|
53
|
+
"name" varchar(255),
|
|
54
|
+
"definition_payload" text NOT NULL,
|
|
55
|
+
"dcql_payload" text,
|
|
56
|
+
"created_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
57
|
+
"last_updated_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
58
|
+
CONSTRAINT "UQ_PresentationDefinitionItem_definition_id_version" UNIQUE ("definition_id", "version")
|
|
59
|
+
)
|
|
60
|
+
`)
|
|
61
|
+
|
|
62
|
+
await queryRunner.query(`
|
|
63
|
+
INSERT INTO "temporary_PresentationDefinitionItem"(
|
|
64
|
+
"id", "definition_id", "version", "tenant_id", "purpose", "name",
|
|
65
|
+
"definition_payload", "dcql_payload", "created_at", "last_updated_at"
|
|
66
|
+
)
|
|
67
|
+
SELECT
|
|
68
|
+
"id", "definition_id", "version", "tenant_id", "purpose", "name",
|
|
69
|
+
"definition_payload", "dcql_payload", "created_at", "last_updated_at"
|
|
70
|
+
FROM "PresentationDefinitionItem"
|
|
71
|
+
`)
|
|
72
|
+
|
|
73
|
+
await queryRunner.query(`DROP TABLE "PresentationDefinitionItem"`)
|
|
74
|
+
await queryRunner.query(`ALTER TABLE "temporary_PresentationDefinitionItem" RENAME TO "PresentationDefinitionItem"`)
|
|
75
|
+
await queryRunner.query(`CREATE INDEX "IDX_PresentationDefinitionItem_version" ON "PresentationDefinitionItem" ("version")`)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
GetDefinitionArgs,
|
|
3
3
|
GetDefinitionsArgs,
|
|
4
4
|
DeleteDefinitionArgs,
|
|
5
|
-
|
|
5
|
+
PresentationDefinitionItem,
|
|
6
6
|
AddDefinitionArgs,
|
|
7
7
|
UpdateDefinitionArgs,
|
|
8
8
|
DeleteDefinitionsArgs,
|
|
@@ -11,10 +11,10 @@ import type {
|
|
|
11
11
|
export abstract class AbstractPDStore {
|
|
12
12
|
abstract hasDefinition(args: GetDefinitionArgs): Promise<boolean>
|
|
13
13
|
abstract hasDefinitions(args: GetDefinitionsArgs): Promise<boolean>
|
|
14
|
-
abstract getDefinition(args: GetDefinitionArgs): Promise<
|
|
15
|
-
abstract getDefinitions(args: GetDefinitionsArgs): Promise<Array<
|
|
16
|
-
abstract addDefinition(args: AddDefinitionArgs): Promise<
|
|
17
|
-
abstract updateDefinition(args: UpdateDefinitionArgs): Promise<
|
|
14
|
+
abstract getDefinition(args: GetDefinitionArgs): Promise<PresentationDefinitionItem>
|
|
15
|
+
abstract getDefinitions(args: GetDefinitionsArgs): Promise<Array<PresentationDefinitionItem>>
|
|
16
|
+
abstract addDefinition(args: AddDefinitionArgs): Promise<PresentationDefinitionItem>
|
|
17
|
+
abstract updateDefinition(args: UpdateDefinitionArgs): Promise<PresentationDefinitionItem>
|
|
18
18
|
abstract deleteDefinition(args: DeleteDefinitionArgs): Promise<void>
|
|
19
19
|
abstract deleteDefinitions(args: DeleteDefinitionsArgs): Promise<number>
|
|
20
20
|
}
|
|
@@ -9,12 +9,12 @@ import type {
|
|
|
9
9
|
GetDefinitionsArgs,
|
|
10
10
|
HasDefinitionArgs,
|
|
11
11
|
HasDefinitionsArgs,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
NonPersistedPresentationDefinitionItem,
|
|
13
|
+
PresentationDefinitionItem,
|
|
14
|
+
PresentationDefinitionItemFilter,
|
|
15
15
|
} from '../types'
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { PresentationDefinitionItemEntity } from '../entities/presentationDefinition/PresentationDefinitionItemEntity'
|
|
17
|
+
import { presentationDefinitionEntityItemFrom, presentationDefinitionItemFrom } from '../utils/presentationDefinition/MappingUtils'
|
|
18
18
|
|
|
19
19
|
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:pd-store')
|
|
20
20
|
|
|
@@ -26,22 +26,22 @@ export class PDStore extends AbstractPDStore {
|
|
|
26
26
|
this.dbConnection = dbConnection
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
getDefinition = async (args: GetDefinitionArgs): Promise<
|
|
29
|
+
getDefinition = async (args: GetDefinitionArgs): Promise<PresentationDefinitionItem> => {
|
|
30
30
|
const { itemId } = args ?? {}
|
|
31
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
32
|
-
const result:
|
|
31
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
32
|
+
const result: PresentationDefinitionItemEntity | null = await pdRepository.findOne({
|
|
33
33
|
where: { id: itemId },
|
|
34
34
|
})
|
|
35
35
|
if (!result) {
|
|
36
36
|
return Promise.reject(Error(`No presentation definition item found for id: ${itemId}`))
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
return
|
|
39
|
+
return presentationDefinitionItemFrom(result)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
hasDefinition = async (args: HasDefinitionArgs): Promise<boolean> => {
|
|
43
43
|
const { itemId } = args ?? {}
|
|
44
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
44
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
45
45
|
|
|
46
46
|
const resultCount: number = await pdRepository.count({
|
|
47
47
|
where: { id: itemId },
|
|
@@ -52,7 +52,7 @@ export class PDStore extends AbstractPDStore {
|
|
|
52
52
|
|
|
53
53
|
hasDefinitions = async (args: HasDefinitionsArgs): Promise<boolean> => {
|
|
54
54
|
const { filter } = args
|
|
55
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
55
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
56
56
|
|
|
57
57
|
const resultCount: number = await pdRepository.count({
|
|
58
58
|
...(filter && { where: cleanFilter(filter) }),
|
|
@@ -60,67 +60,72 @@ export class PDStore extends AbstractPDStore {
|
|
|
60
60
|
return resultCount > 0
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
getDefinitions = async (args: GetDefinitionsArgs): Promise<Array<
|
|
63
|
+
getDefinitions = async (args: GetDefinitionsArgs): Promise<Array<PresentationDefinitionItem>> => {
|
|
64
64
|
const { filter } = args
|
|
65
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
65
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
66
66
|
const initialResult = await this.findIds(pdRepository, filter)
|
|
67
|
-
const result: Array<
|
|
67
|
+
const result: Array<PresentationDefinitionItemEntity> = await pdRepository.find({
|
|
68
68
|
where: {
|
|
69
|
-
id: In(initialResult.map((entity:
|
|
69
|
+
id: In(initialResult.map((entity: PresentationDefinitionItemEntity) => entity.id)),
|
|
70
70
|
},
|
|
71
71
|
order: {
|
|
72
72
|
version: 'DESC',
|
|
73
73
|
},
|
|
74
74
|
})
|
|
75
75
|
|
|
76
|
-
return result.map((entity:
|
|
76
|
+
return result.map((entity: PresentationDefinitionItemEntity) => presentationDefinitionItemFrom(entity))
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
addDefinition = async (item:
|
|
80
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
79
|
+
addDefinition = async (item: NonPersistedPresentationDefinitionItem): Promise<PresentationDefinitionItem> => {
|
|
80
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
81
81
|
|
|
82
|
-
const entity:
|
|
82
|
+
const entity: PresentationDefinitionItemEntity = presentationDefinitionEntityItemFrom(item)
|
|
83
83
|
debug('Adding presentation definition entity', item)
|
|
84
|
-
const result:
|
|
84
|
+
const result: PresentationDefinitionItemEntity = await pdRepository.save(entity, {
|
|
85
85
|
transaction: true,
|
|
86
86
|
})
|
|
87
87
|
|
|
88
|
-
return
|
|
88
|
+
return presentationDefinitionItemFrom(result)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
updateDefinition = async (item:
|
|
92
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
91
|
+
updateDefinition = async (item: PresentationDefinitionItem): Promise<PresentationDefinitionItem> => {
|
|
92
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
93
93
|
|
|
94
|
-
const result:
|
|
94
|
+
const result: PresentationDefinitionItemEntity | null = await pdRepository.findOne({
|
|
95
95
|
where: { id: item.id },
|
|
96
96
|
})
|
|
97
97
|
if (!result) {
|
|
98
98
|
return Promise.reject(Error(`No presentation definition entity found for id: ${item.id}`))
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
const updatedEntity: Partial<
|
|
101
|
+
const updatedEntity: Partial<PresentationDefinitionItemEntity> = {
|
|
102
102
|
...result,
|
|
103
103
|
}
|
|
104
104
|
updatedEntity.tenantId = item.tenantId
|
|
105
|
-
updatedEntity.
|
|
105
|
+
updatedEntity.definitionId = item.definitionId!
|
|
106
106
|
updatedEntity.version = item.version
|
|
107
107
|
updatedEntity.name = item.name
|
|
108
108
|
updatedEntity.purpose = item.purpose
|
|
109
|
-
|
|
109
|
+
if (item.definitionPayload) {
|
|
110
|
+
updatedEntity.definitionPayload = JSON.stringify(item.definitionPayload!)
|
|
111
|
+
}
|
|
112
|
+
if (item.dcqlPayload) {
|
|
113
|
+
updatedEntity.dcqlPayload = JSON.stringify(item.dcqlPayload!.dcqlQuery)
|
|
114
|
+
}
|
|
110
115
|
|
|
111
116
|
debug('Updating presentation definition entity', updatedEntity)
|
|
112
|
-
const updateResult:
|
|
117
|
+
const updateResult: PresentationDefinitionItemEntity = await pdRepository.save(updatedEntity, {
|
|
113
118
|
transaction: true,
|
|
114
119
|
})
|
|
115
120
|
|
|
116
|
-
return
|
|
121
|
+
return presentationDefinitionItemFrom(updateResult)
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
deleteDefinition = async (args: DeleteDefinitionArgs): Promise<void> => {
|
|
120
125
|
const { itemId } = args
|
|
121
126
|
|
|
122
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
123
|
-
const entity:
|
|
127
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
128
|
+
const entity: PresentationDefinitionItemEntity | null = await pdRepository.findOne({
|
|
124
129
|
where: { id: itemId },
|
|
125
130
|
})
|
|
126
131
|
|
|
@@ -134,12 +139,12 @@ export class PDStore extends AbstractPDStore {
|
|
|
134
139
|
|
|
135
140
|
deleteDefinitions = async (args: DeleteDefinitionsArgs): Promise<number> => {
|
|
136
141
|
const { filter } = args
|
|
137
|
-
const pdRepository = (await this.dbConnection).getRepository(
|
|
142
|
+
const pdRepository = (await this.dbConnection).getRepository(PresentationDefinitionItemEntity)
|
|
138
143
|
const initialResult = await this.findIds(pdRepository, filter)
|
|
139
144
|
|
|
140
|
-
const result: Array<
|
|
145
|
+
const result: Array<PresentationDefinitionItemEntity> = await pdRepository.find({
|
|
141
146
|
where: {
|
|
142
|
-
id: In(initialResult.map((entity:
|
|
147
|
+
id: In(initialResult.map((entity: PresentationDefinitionItemEntity) => entity.id)),
|
|
143
148
|
},
|
|
144
149
|
})
|
|
145
150
|
|
|
@@ -151,9 +156,9 @@ export class PDStore extends AbstractPDStore {
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
findIds = async (
|
|
154
|
-
pdRepository: Repository<
|
|
155
|
-
filter: Array<
|
|
156
|
-
): Promise<Array<
|
|
159
|
+
pdRepository: Repository<PresentationDefinitionItemEntity>,
|
|
160
|
+
filter: Array<PresentationDefinitionItemFilter> | undefined,
|
|
161
|
+
): Promise<Array<PresentationDefinitionItemEntity>> => {
|
|
157
162
|
const idFilters = filter?.map((f) => f.id).filter((id) => id !== undefined && id !== null)
|
|
158
163
|
if (idFilters && idFilters.length > 0 && idFilters.length === filter?.length) {
|
|
159
164
|
return await pdRepository.find({
|
|
@@ -167,15 +172,15 @@ export class PDStore extends AbstractPDStore {
|
|
|
167
172
|
}
|
|
168
173
|
}
|
|
169
174
|
|
|
170
|
-
const cleanFilter = (filter: Array<
|
|
175
|
+
const cleanFilter = (filter: Array<PresentationDefinitionItemFilter> | undefined): Array<PresentationDefinitionItemFilter> | undefined => {
|
|
171
176
|
if (filter === undefined) {
|
|
172
177
|
return undefined
|
|
173
178
|
}
|
|
174
179
|
|
|
175
180
|
return filter.map((item) => {
|
|
176
|
-
const cleanedItem:
|
|
181
|
+
const cleanedItem: PresentationDefinitionItemFilter = {}
|
|
177
182
|
for (const key in item) {
|
|
178
|
-
const value = item[key as keyof
|
|
183
|
+
const value = item[key as keyof PresentationDefinitionItemFilter]
|
|
179
184
|
if (value !== undefined) {
|
|
180
185
|
;(cleanedItem as any)[key] = value
|
|
181
186
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NonPersistedPresentationDefinitionItem, PresentationDefinitionItem, PresentationDefinitionItemFilter } from './presentationDefinition'
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type FindDefinitionArgs = Array<PresentationDefinitionItemFilter>
|
|
4
4
|
|
|
5
5
|
export type GetDefinitionArgs = {
|
|
6
6
|
itemId: string
|
|
@@ -9,14 +9,14 @@ export type GetDefinitionArgs = {
|
|
|
9
9
|
export type HasDefinitionArgs = GetDefinitionArgs
|
|
10
10
|
|
|
11
11
|
export type GetDefinitionsArgs = {
|
|
12
|
-
filter?:
|
|
12
|
+
filter?: FindDefinitionArgs
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export type HasDefinitionsArgs = GetDefinitionsArgs
|
|
16
16
|
|
|
17
|
-
export type AddDefinitionArgs =
|
|
17
|
+
export type AddDefinitionArgs = NonPersistedPresentationDefinitionItem
|
|
18
18
|
|
|
19
|
-
export type UpdateDefinitionArgs =
|
|
19
|
+
export type UpdateDefinitionArgs = PresentationDefinitionItem
|
|
20
20
|
|
|
21
21
|
export type DeleteDefinitionArgs = {
|
|
22
22
|
itemId: string
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPresentationDefinition } from '@sphereon/pex'
|
|
2
|
+
import { DcqlQueryPayload } from '@sphereon/ssi-types'
|
|
2
3
|
|
|
3
|
-
export type
|
|
4
|
+
export type PresentationDefinitionItem = {
|
|
4
5
|
id: string
|
|
5
|
-
|
|
6
|
+
definitionId: string
|
|
6
7
|
tenantId?: string
|
|
7
8
|
version: string
|
|
8
9
|
name?: string
|
|
9
10
|
purpose?: string
|
|
10
|
-
|
|
11
|
+
definitionPayload?: IPresentationDefinition
|
|
12
|
+
dcqlPayload?: DcqlQueryPayload
|
|
11
13
|
createdAt: Date
|
|
12
14
|
lastUpdatedAt: Date
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
export type
|
|
16
|
-
export type
|
|
17
|
-
export type
|
|
18
|
-
export type DcqlQueryItemFilter = Partial<Omit<DcqlQueryItem, 'query'>>
|
|
17
|
+
export type NonPersistedPresentationDefinitionItem = Omit<PresentationDefinitionItem, 'id' | 'createdAt' | 'lastUpdatedAt'>
|
|
18
|
+
export type PartialPresentationDefinitionItem = Partial<PresentationDefinitionItem>
|
|
19
|
+
export type PresentationDefinitionItemFilter = Partial<Omit<PresentationDefinitionItem, 'definitionPayload' | 'dcqlPayload'>>
|
|
@@ -1,52 +1,64 @@
|
|
|
1
|
+
import { DcqlQueryPayload } from '@sphereon/ssi-types'
|
|
2
|
+
import { DcqlQuery } from 'dcql'
|
|
3
|
+
import { PresentationDefinitionItemEntity } from '../../entities/presentationDefinition/PresentationDefinitionItemEntity'
|
|
1
4
|
import type { IPresentationDefinition } from '@sphereon/pex'
|
|
5
|
+
import type { NonPersistedPresentationDefinitionItem, PartialPresentationDefinitionItem, PresentationDefinitionItem } from '../../types'
|
|
2
6
|
import * as blakepkg from 'blakejs'
|
|
3
|
-
import { DcqlQuery } from 'dcql'
|
|
4
|
-
import { DcqlQueryItemEntity } from '../../entities/presentationDefinition/DcqlQueryItemEntity'
|
|
5
|
-
import type { NonPersistedDcqlQueryItem, PartialDcqlQueryItem, DcqlQueryItem } from '../../types'
|
|
6
7
|
import { replaceNullWithUndefined } from '../FormattingUtils'
|
|
7
8
|
|
|
8
|
-
export const
|
|
9
|
-
const result:
|
|
9
|
+
export const presentationDefinitionItemFrom = (entity: PresentationDefinitionItemEntity): PresentationDefinitionItem => {
|
|
10
|
+
const result: PresentationDefinitionItem = {
|
|
10
11
|
id: entity.id,
|
|
11
12
|
tenantId: entity.tenantId,
|
|
12
|
-
|
|
13
|
+
definitionId: entity.definitionId,
|
|
13
14
|
version: entity.version,
|
|
14
15
|
name: entity.name,
|
|
15
16
|
purpose: entity.purpose,
|
|
16
|
-
|
|
17
|
+
definitionPayload: JSON.parse(entity.definitionPayload) as IPresentationDefinition,
|
|
18
|
+
...(entity.dcqlPayload && {
|
|
19
|
+
dcqlPayload: {
|
|
20
|
+
queryId: entity.definitionId,
|
|
21
|
+
name: entity.name,
|
|
22
|
+
defaultPurpose: entity.purpose,
|
|
23
|
+
dcqlQuery: DcqlQuery.parse(JSON.parse(entity.dcqlPayload)),
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
17
26
|
createdAt: entity.createdAt,
|
|
18
27
|
lastUpdatedAt: entity.lastUpdatedAt,
|
|
19
28
|
}
|
|
20
29
|
|
|
21
|
-
if (result.
|
|
22
|
-
DcqlQuery.validate(result.
|
|
30
|
+
if (result.dcqlPayload?.dcqlQuery) {
|
|
31
|
+
DcqlQuery.validate(result.dcqlPayload?.dcqlQuery)
|
|
23
32
|
}
|
|
24
33
|
return replaceNullWithUndefined(result)
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
export const
|
|
28
|
-
const entity = new
|
|
36
|
+
export const presentationDefinitionEntityItemFrom = (item: NonPersistedPresentationDefinitionItem): PresentationDefinitionItemEntity => {
|
|
37
|
+
const entity = new PresentationDefinitionItemEntity()
|
|
29
38
|
|
|
30
39
|
entity.tenantId = item.tenantId
|
|
31
|
-
entity.
|
|
40
|
+
entity.definitionId = item.definitionId!
|
|
32
41
|
entity.version = item.version
|
|
33
42
|
entity.name = item.name
|
|
34
43
|
entity.purpose = item.purpose
|
|
35
|
-
if (item.
|
|
36
|
-
|
|
44
|
+
if (item.definitionPayload) {
|
|
45
|
+
entity.definitionPayload = JSON.stringify(item.definitionPayload)
|
|
46
|
+
}
|
|
47
|
+
if (item.dcqlPayload) {
|
|
48
|
+
const dcqlQuery = DcqlQuery.parse(item.dcqlPayload.dcqlQuery)
|
|
37
49
|
DcqlQuery.validate(dcqlQuery)
|
|
38
|
-
entity.
|
|
50
|
+
entity.dcqlPayload = JSON.stringify(item.dcqlPayload.dcqlQuery)
|
|
39
51
|
}
|
|
40
52
|
return entity
|
|
41
53
|
}
|
|
42
54
|
|
|
43
|
-
function hashPayload(payload: IPresentationDefinition |
|
|
55
|
+
function hashPayload(payload: IPresentationDefinition | DcqlQueryPayload): string {
|
|
44
56
|
return blakepkg.blake2bHex(JSON.stringify(payload))
|
|
45
57
|
}
|
|
46
58
|
|
|
47
|
-
export function isPresentationDefinitionEqual(base:
|
|
59
|
+
export function isPresentationDefinitionEqual(base: PartialPresentationDefinitionItem, compare: PartialPresentationDefinitionItem): boolean {
|
|
48
60
|
if (
|
|
49
|
-
base.
|
|
61
|
+
base.definitionId !== compare.definitionId ||
|
|
50
62
|
base.tenantId !== compare.tenantId ||
|
|
51
63
|
base.version !== compare.version ||
|
|
52
64
|
base.name !== compare.name ||
|
|
@@ -55,11 +67,19 @@ export function isPresentationDefinitionEqual(base: PartialDcqlQueryItem, compar
|
|
|
55
67
|
return false
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
if (base.
|
|
59
|
-
if (hashPayload(base.
|
|
70
|
+
if (base.dcqlPayload && compare.dcqlPayload) {
|
|
71
|
+
if (hashPayload(base.dcqlPayload) !== hashPayload(compare.dcqlPayload)) {
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
74
|
+
} else if (base.dcqlPayload || compare.dcqlPayload) {
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (base.definitionPayload && compare.definitionPayload) {
|
|
79
|
+
if (hashPayload(base.definitionPayload) !== hashPayload(compare.definitionPayload)) {
|
|
60
80
|
return false
|
|
61
81
|
}
|
|
62
|
-
} else if (base.
|
|
82
|
+
} else if (base.definitionPayload || compare.definitionPayload) {
|
|
63
83
|
return false
|
|
64
84
|
}
|
|
65
85
|
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
-
|
|
3
|
-
export class CreateDcqlQueryItemPG1726588800000 implements MigrationInterface {
|
|
4
|
-
name = 'CreateDcqlQueryItemPG1726588800000'
|
|
5
|
-
|
|
6
|
-
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
-
await queryRunner.query(`
|
|
8
|
-
CREATE TABLE "DcqlQueryItem" (
|
|
9
|
-
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
|
10
|
-
"tenant_id" TEXT,
|
|
11
|
-
"query_id" TEXT NOT NULL,
|
|
12
|
-
"name" TEXT,
|
|
13
|
-
"version" TEXT NOT NULL,
|
|
14
|
-
"purpose" TEXT,
|
|
15
|
-
"query" TEXT NOT NULL,
|
|
16
|
-
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
17
|
-
"last_updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
|
18
|
-
CONSTRAINT "PK_DcqlQueryItem_id" PRIMARY KEY ("id"))
|
|
19
|
-
`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
23
|
-
await queryRunner.query(`DROP TABLE "DcqlQueryItem"`)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { MigrationInterface, QueryRunner } from 'typeorm'
|
|
2
|
-
|
|
3
|
-
export class CreateDcqlQueryItemSQlite1726617600000 implements MigrationInterface {
|
|
4
|
-
name = 'CreateDcqlQueryItemSQlite1726617600000'
|
|
5
|
-
|
|
6
|
-
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
-
await queryRunner.query(
|
|
8
|
-
`CREATE TABLE "DcqlQueryItem" (
|
|
9
|
-
"id" varchar PRIMARY KEY NOT NULL,
|
|
10
|
-
"tenant_id" varchar,
|
|
11
|
-
"query_id" varchar NOT NULL,
|
|
12
|
-
"name" varchar,
|
|
13
|
-
"version" varchar NOT NULL,
|
|
14
|
-
"purpose" varchar,
|
|
15
|
-
"query" varchar NOT NULL,
|
|
16
|
-
"created_at" datetime NOT NULL DEFAULT (datetime('now')),
|
|
17
|
-
"last_updated_at" datetime NOT NULL DEFAULT (datetime('now')))`,
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
22
|
-
await queryRunner.query(`DROP TABLE "DcqlQueryItem"`)
|
|
23
|
-
}
|
|
24
|
-
}
|