@sphereon/ssi-sdk.data-store 0.23.5-unstable.88 → 0.24.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.
- package/LICENSE +201 -201
- package/README.md +77 -77
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -15
- package/dist/index.js.map +1 -1
- package/dist/migrations/generic/index.d.ts +0 -2
- package/dist/migrations/generic/index.d.ts.map +1 -1
- package/dist/migrations/generic/index.js +1 -4
- package/dist/migrations/generic/index.js.map +1 -1
- package/dist/migrations/index.d.ts +1 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +1 -2
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/postgres/1690925872592-CreateContacts.js +1 -1
- package/dist/migrations/postgres/1690925872592-CreateContacts.js.map +1 -1
- package/dist/migrations/postgres/1708525189001-CreateDigitalCredential.js +22 -22
- package/dist/migrations/postgres/1708797018115-CreateMachineStateStore.js +16 -16
- package/dist/migrations/sqlite/1708525189002-CreateDigitalCredential.js +21 -21
- package/dist/migrations/sqlite/1708796002272-CreateMachineStateStore.js +15 -15
- package/dist/types/index.d.ts +0 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -2
- package/dist/types/index.js.map +1 -1
- package/package.json +4 -5
- package/src/__tests__/contact.entities.test.ts +2542 -2542
- package/src/__tests__/contact.store.test.ts +2471 -2471
- package/src/__tests__/digitalCredential.entities.test.ts +254 -254
- package/src/__tests__/digitalCredential.store.test.ts +294 -294
- package/src/__tests__/eventLogger.entities.test.ts +73 -73
- package/src/__tests__/eventLogger.store.test.ts +136 -136
- package/src/__tests__/issuanceBranding.entities.test.ts +844 -844
- package/src/__tests__/issuanceBranding.store.test.ts +1884 -1884
- package/src/__tests__/machineState.entities.test.ts +51 -51
- package/src/__tests__/machineState.store.test.ts +174 -174
- package/src/contact/AbstractContactStore.ts +71 -71
- package/src/contact/ContactStore.ts +723 -723
- package/src/digitalCredential/AbstractDigitalCredentialStore.ts +17 -17
- package/src/digitalCredential/DigitalCredentialStore.ts +127 -127
- package/src/entities/contact/BaseContactEntity.ts +39 -39
- package/src/entities/contact/ConnectionEntity.ts +29 -29
- package/src/entities/contact/CorrelationIdentifierEntity.ts +37 -37
- package/src/entities/contact/DidAuthConfigEntity.ts +14 -14
- package/src/entities/contact/ElectronicAddressEntity.ts +63 -63
- package/src/entities/contact/IdentityEntity.ts +97 -97
- package/src/entities/contact/IdentityMetadataItemEntity.ts +35 -35
- package/src/entities/contact/NaturalPersonEntity.ts +38 -38
- package/src/entities/contact/OpenIdConfigEntity.ts +26 -26
- package/src/entities/contact/OrganizationEntity.ts +34 -34
- package/src/entities/contact/PartyEntity.ts +110 -110
- package/src/entities/contact/PartyRelationshipEntity.ts +61 -61
- package/src/entities/contact/PartyTypeEntity.ts +62 -62
- package/src/entities/contact/PhysicalAddressEntity.ts +87 -87
- package/src/entities/digitalCredential/DigitalCredentialEntity.ts +64 -64
- package/src/entities/eventLogger/AuditEventEntity.ts +99 -99
- package/src/entities/issuanceBranding/CredentialBrandingEntity.ts +78 -78
- package/src/entities/issuanceBranding/ImageAttributesEntity.ts +57 -57
- package/src/entities/issuanceBranding/IssuerBrandingEntity.ts +72 -72
- package/src/entities/machineState/MachineStateInfoEntity.ts +58 -58
- package/src/entities/statusList2021/StatusList2021Entity.ts +96 -96
- package/src/eventLogger/AbstractEventLoggerStore.ts +7 -7
- package/src/eventLogger/EventLoggerStore.ts +62 -62
- package/src/index.ts +141 -154
- package/src/issuanceBranding/IssuanceBrandingStore.ts +559 -559
- package/src/machineState/IAbstractMachineStateStore.ts +65 -65
- package/src/machineState/MachineStateStore.ts +149 -149
- package/src/migrations/generic/1-CreateContacts.ts +66 -66
- package/src/migrations/generic/2-CreateIssuanceBranding.ts +64 -64
- package/src/migrations/generic/3-CreateContacts.ts +66 -66
- package/src/migrations/generic/4-CreateStatusList.ts +54 -54
- package/src/migrations/generic/5-CreateAuditEvents.ts +66 -66
- package/src/migrations/generic/6-CreateDigitalCredential.ts +66 -66
- package/src/migrations/generic/7-CreateMachineStateStore.ts +66 -66
- package/src/migrations/generic/index.ts +33 -36
- package/src/migrations/index.ts +9 -10
- package/src/migrations/postgres/1659463079428-CreateContacts.ts +63 -63
- package/src/migrations/postgres/1685628974232-CreateIssuanceBranding.ts +85 -85
- package/src/migrations/postgres/1690925872592-CreateContacts.ts +104 -104
- package/src/migrations/postgres/1693866470001-CreateStatusList.ts +24 -24
- package/src/migrations/postgres/1701634812183-CreateAuditEvents.ts +33 -33
- package/src/migrations/postgres/1708525189001-CreateDigitalCredential.ts +44 -44
- package/src/migrations/postgres/1708797018115-CreateMachineStateStore.ts +29 -29
- package/src/migrations/sqlite/1659463069549-CreateContacts.ts +110 -110
- package/src/migrations/sqlite/1685628973231-CreateIssuanceBranding.ts +119 -119
- package/src/migrations/sqlite/1690925872693-CreateContacts.ts +161 -161
- package/src/migrations/sqlite/1693866470000-CreateStatusList.ts +24 -24
- package/src/migrations/sqlite/1701634819487-CreateAuditEvents.ts +15 -15
- package/src/migrations/sqlite/1708525189002-CreateDigitalCredential.ts +34 -34
- package/src/migrations/sqlite/1708796002272-CreateMachineStateStore.ts +28 -28
- package/src/statusList/StatusListStore.ts +237 -237
- package/src/types/contact/IAbstractContactStore.ts +161 -161
- package/src/types/contact/contact.ts +237 -237
- package/src/types/digitalCredential/IAbstractDigitalCredentialStore.ts +37 -37
- package/src/types/digitalCredential/digitalCredential.ts +46 -46
- package/src/types/eventLogger/IAbstractEventLoggerStore.ts +12 -12
- package/src/types/eventLogger/eventLogger.ts +3 -3
- package/src/types/index.ts +10 -12
- package/src/types/machineState/IAbstractMachineStateStore.ts +68 -68
- package/src/utils/SortingUtils.ts +16 -16
- package/src/utils/contact/MappingUtils.ts +385 -385
- package/src/utils/digitalCredential/MappingUtils.ts +122 -122
- package/dist/entities/presentationDefinitions/PresentationDefinitionItemEntity.d.ts +0 -13
- package/dist/entities/presentationDefinitions/PresentationDefinitionItemEntity.d.ts.map +0 -1
- package/dist/entities/presentationDefinitions/PresentationDefinitionItemEntity.js +0 -71
- package/dist/entities/presentationDefinitions/PresentationDefinitionItemEntity.js.map +0 -1
- package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts +0 -7
- package/dist/migrations/generic/8-CreatePresentationDefinitions.d.ts.map +0 -1
- package/dist/migrations/generic/8-CreatePresentationDefinitions.js +0 -78
- package/dist/migrations/generic/8-CreatePresentationDefinitions.js.map +0 -1
- package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.d.ts +0 -7
- package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.d.ts.map +0 -1
- package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js +0 -40
- package/dist/migrations/postgres/1716475165345-CreatePresentationDefinitions.js.map +0 -1
- package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.d.ts +0 -7
- package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.d.ts.map +0 -1
- package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js +0 -37
- package/dist/migrations/sqlite/1716475165344-CreatePresentationDefinitions.js.map +0 -1
- package/dist/pd/AbstractPDStore.d.ts +0 -10
- package/dist/pd/AbstractPDStore.d.ts.map +0 -1
- package/dist/pd/AbstractPDStore.js +0 -7
- package/dist/pd/AbstractPDStore.js.map +0 -1
- package/dist/pd/PDStore.d.ts +0 -14
- package/dist/pd/PDStore.d.ts.map +0 -1
- package/dist/pd/PDStore.js +0 -90
- package/dist/pd/PDStore.js.map +0 -1
- package/dist/types/pd/IAbstractPDStore.d.ts +0 -14
- package/dist/types/pd/IAbstractPDStore.d.ts.map +0 -1
- package/dist/types/pd/IAbstractPDStore.js +0 -3
- package/dist/types/pd/IAbstractPDStore.js.map +0 -1
- package/dist/types/pd/pd.d.ts +0 -15
- package/dist/types/pd/pd.d.ts.map +0 -1
- package/dist/types/pd/pd.js +0 -3
- package/dist/types/pd/pd.js.map +0 -1
- package/dist/utils/presentationDefinitions/MappingUtils.d.ts +0 -6
- package/dist/utils/presentationDefinitions/MappingUtils.d.ts.map +0 -1
- package/dist/utils/presentationDefinitions/MappingUtils.js +0 -50
- package/dist/utils/presentationDefinitions/MappingUtils.js.map +0 -1
- package/src/entities/presentationDefinitions/PresentationDefinitionItemEntity.ts +0 -41
- package/src/migrations/generic/8-CreatePresentationDefinitions.ts +0 -66
- package/src/migrations/postgres/1716475165345-CreatePresentationDefinitions.ts +0 -24
- package/src/migrations/sqlite/1716475165344-CreatePresentationDefinitions.ts +0 -23
- package/src/pd/AbstractPDStore.ts +0 -10
- package/src/pd/PDStore.ts +0 -103
- package/src/types/pd/IAbstractPDStore.ts +0 -19
- package/src/types/pd/pd.ts +0 -16
- package/src/utils/presentationDefinitions/MappingUtils.ts +0 -54
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AddCredentialArgs,
|
|
3
|
-
GetCredentialArgs,
|
|
4
|
-
GetCredentialsArgs,
|
|
5
|
-
GetCredentialsResponse,
|
|
6
|
-
RemoveCredentialArgs,
|
|
7
|
-
UpdateCredentialStateArgs,
|
|
8
|
-
} from '../types/digitalCredential/IAbstractDigitalCredentialStore'
|
|
9
|
-
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
10
|
-
|
|
11
|
-
export abstract class AbstractDigitalCredentialStore {
|
|
12
|
-
abstract getCredential(args: GetCredentialArgs): Promise<DigitalCredentialEntity>
|
|
13
|
-
abstract getCredentials(args?: GetCredentialsArgs): Promise<GetCredentialsResponse>
|
|
14
|
-
abstract addCredential(args: AddCredentialArgs): Promise<DigitalCredentialEntity>
|
|
15
|
-
abstract updateCredentialState(args: UpdateCredentialStateArgs): Promise<DigitalCredentialEntity>
|
|
16
|
-
abstract removeCredential(args: RemoveCredentialArgs): Promise<boolean>
|
|
17
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
AddCredentialArgs,
|
|
3
|
+
GetCredentialArgs,
|
|
4
|
+
GetCredentialsArgs,
|
|
5
|
+
GetCredentialsResponse,
|
|
6
|
+
RemoveCredentialArgs,
|
|
7
|
+
UpdateCredentialStateArgs,
|
|
8
|
+
} from '../types/digitalCredential/IAbstractDigitalCredentialStore'
|
|
9
|
+
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
10
|
+
|
|
11
|
+
export abstract class AbstractDigitalCredentialStore {
|
|
12
|
+
abstract getCredential(args: GetCredentialArgs): Promise<DigitalCredentialEntity>
|
|
13
|
+
abstract getCredentials(args?: GetCredentialsArgs): Promise<GetCredentialsResponse>
|
|
14
|
+
abstract addCredential(args: AddCredentialArgs): Promise<DigitalCredentialEntity>
|
|
15
|
+
abstract updateCredentialState(args: UpdateCredentialStateArgs): Promise<DigitalCredentialEntity>
|
|
16
|
+
abstract removeCredential(args: RemoveCredentialArgs): Promise<boolean>
|
|
17
|
+
}
|
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
import { AbstractDigitalCredentialStore } from './AbstractDigitalCredentialStore'
|
|
2
|
-
import {
|
|
3
|
-
AddCredentialArgs,
|
|
4
|
-
GetCredentialArgs,
|
|
5
|
-
GetCredentialsArgs,
|
|
6
|
-
GetCredentialsResponse,
|
|
7
|
-
RemoveCredentialArgs,
|
|
8
|
-
UpdateCredentialStateArgs,
|
|
9
|
-
} from '../types/digitalCredential/IAbstractDigitalCredentialStore'
|
|
10
|
-
import { OrPromise } from '@sphereon/ssi-types'
|
|
11
|
-
import { DataSource, FindOptionsOrder, Repository } from 'typeorm'
|
|
12
|
-
import Debug from 'debug'
|
|
13
|
-
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
14
|
-
import { nonPersistedDigitalCredentialEntityFromAddArgs } from '../utils/digitalCredential/MappingUtils'
|
|
15
|
-
import { FindOptionsWhere } from 'typeorm/find-options/FindOptionsWhere'
|
|
16
|
-
import { CredentialStateType, DigitalCredential, NonPersistedDigitalCredential } from '../types/digitalCredential/digitalCredential'
|
|
17
|
-
import { parseAndValidateOrderOptions } from '../utils/SortingUtils'
|
|
18
|
-
|
|
19
|
-
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:credential-store')
|
|
20
|
-
|
|
21
|
-
export class DigitalCredentialStore extends AbstractDigitalCredentialStore {
|
|
22
|
-
private readonly dbConnection: OrPromise<DataSource>
|
|
23
|
-
|
|
24
|
-
constructor(dbConnection: OrPromise<DataSource>) {
|
|
25
|
-
super()
|
|
26
|
-
this.dbConnection = dbConnection
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
addCredential = async (args: AddCredentialArgs): Promise<DigitalCredentialEntity> => {
|
|
30
|
-
debug('Adding credential', args)
|
|
31
|
-
const digitalCredentialEntityRepository: Repository<DigitalCredentialEntity> = (await this.dbConnection).getRepository(DigitalCredentialEntity)
|
|
32
|
-
const credentialEntity: NonPersistedDigitalCredential = nonPersistedDigitalCredentialEntityFromAddArgs(args)
|
|
33
|
-
const createdResult: DigitalCredentialEntity = await digitalCredentialEntityRepository.save(credentialEntity)
|
|
34
|
-
return Promise.resolve(createdResult)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
getCredential = async (args: GetCredentialArgs): Promise<DigitalCredentialEntity> => {
|
|
38
|
-
const result: DigitalCredentialEntity | null = await (await this.dbConnection).getRepository(DigitalCredentialEntity).findOne({
|
|
39
|
-
where: args,
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
if (!result) {
|
|
43
|
-
return Promise.reject(Error(`No credential found for arg: ${args.toString()}`))
|
|
44
|
-
}
|
|
45
|
-
return result
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getCredentials = async (args?: GetCredentialsArgs): Promise<GetCredentialsResponse> => {
|
|
49
|
-
const { filter = {}, offset, limit, order = 'id.asc' } = args ?? {}
|
|
50
|
-
const sortOptions: FindOptionsOrder<DigitalCredentialEntity> =
|
|
51
|
-
order && typeof order === 'string'
|
|
52
|
-
? parseAndValidateOrderOptions<DigitalCredentialEntity>(order)
|
|
53
|
-
: <FindOptionsOrder<DigitalCredentialEntity>>order
|
|
54
|
-
const [result, total] = await (await this.dbConnection).getRepository(DigitalCredentialEntity).findAndCount({
|
|
55
|
-
where: filter,
|
|
56
|
-
skip: offset,
|
|
57
|
-
take: limit,
|
|
58
|
-
order: sortOptions,
|
|
59
|
-
})
|
|
60
|
-
return {
|
|
61
|
-
data: result,
|
|
62
|
-
total,
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
removeCredential = async (args: RemoveCredentialArgs): Promise<boolean> => {
|
|
67
|
-
if (!args) {
|
|
68
|
-
return false
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let query: FindOptionsWhere<DigitalCredentialEntity> = {}
|
|
72
|
-
|
|
73
|
-
if ('id' in args) {
|
|
74
|
-
query.id = args.id
|
|
75
|
-
} else if ('hash' in args) {
|
|
76
|
-
query.hash = args.hash
|
|
77
|
-
} else {
|
|
78
|
-
return false
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const connection = await this.dbConnection
|
|
82
|
-
const result = await connection.getRepository(DigitalCredentialEntity).delete(query)
|
|
83
|
-
return result.affected === 1
|
|
84
|
-
} catch (error) {
|
|
85
|
-
console.error('Error removing digital credential:', error)
|
|
86
|
-
return false
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
updateCredentialState = async (args: UpdateCredentialStateArgs): Promise<DigitalCredentialEntity> => {
|
|
91
|
-
const credentialRepository: Repository<DigitalCredentialEntity> = (await this.dbConnection).getRepository(DigitalCredentialEntity)
|
|
92
|
-
const whereClause: Record<string, any> = {}
|
|
93
|
-
if ('id' in args) {
|
|
94
|
-
whereClause.id = args.id
|
|
95
|
-
} else if ('hash' in args) {
|
|
96
|
-
whereClause.hash = args.hash
|
|
97
|
-
} else {
|
|
98
|
-
throw new Error('No id or hash param is provided.')
|
|
99
|
-
}
|
|
100
|
-
if (!args.verifiedState) {
|
|
101
|
-
throw new Error('No verifiedState param is provided.')
|
|
102
|
-
}
|
|
103
|
-
if (args.verifiedState === CredentialStateType.REVOKED && !args.revokedAt) {
|
|
104
|
-
throw new Error('No revokedAt param is provided.')
|
|
105
|
-
}
|
|
106
|
-
if (args.verifiedState !== CredentialStateType.REVOKED && !args.verifiedAt) {
|
|
107
|
-
throw new Error('No verifiedAt param is provided.')
|
|
108
|
-
}
|
|
109
|
-
const credential: DigitalCredentialEntity | null = await credentialRepository.findOne({
|
|
110
|
-
where: whereClause,
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
if (!credential) {
|
|
114
|
-
return Promise.reject(Error(`No credential found for args: ${whereClause}`))
|
|
115
|
-
}
|
|
116
|
-
const updatedCredential: DigitalCredential = {
|
|
117
|
-
...credential,
|
|
118
|
-
...(args.verifiedState !== CredentialStateType.REVOKED && { verifiedAt: args.verifiedAt }),
|
|
119
|
-
...(args.verifiedState === CredentialStateType.REVOKED && { revokedAt: args.revokedAt }),
|
|
120
|
-
lastUpdatedAt: new Date(),
|
|
121
|
-
verifiedState: args.verifiedState,
|
|
122
|
-
}
|
|
123
|
-
debug('Updating credential', credential)
|
|
124
|
-
const updatedResult: DigitalCredentialEntity = await credentialRepository.save(updatedCredential, { transaction: true })
|
|
125
|
-
return updatedResult
|
|
126
|
-
}
|
|
127
|
-
}
|
|
1
|
+
import { AbstractDigitalCredentialStore } from './AbstractDigitalCredentialStore'
|
|
2
|
+
import {
|
|
3
|
+
AddCredentialArgs,
|
|
4
|
+
GetCredentialArgs,
|
|
5
|
+
GetCredentialsArgs,
|
|
6
|
+
GetCredentialsResponse,
|
|
7
|
+
RemoveCredentialArgs,
|
|
8
|
+
UpdateCredentialStateArgs,
|
|
9
|
+
} from '../types/digitalCredential/IAbstractDigitalCredentialStore'
|
|
10
|
+
import { OrPromise } from '@sphereon/ssi-types'
|
|
11
|
+
import { DataSource, FindOptionsOrder, Repository } from 'typeorm'
|
|
12
|
+
import Debug from 'debug'
|
|
13
|
+
import { DigitalCredentialEntity } from '../entities/digitalCredential/DigitalCredentialEntity'
|
|
14
|
+
import { nonPersistedDigitalCredentialEntityFromAddArgs } from '../utils/digitalCredential/MappingUtils'
|
|
15
|
+
import { FindOptionsWhere } from 'typeorm/find-options/FindOptionsWhere'
|
|
16
|
+
import { CredentialStateType, DigitalCredential, NonPersistedDigitalCredential } from '../types/digitalCredential/digitalCredential'
|
|
17
|
+
import { parseAndValidateOrderOptions } from '../utils/SortingUtils'
|
|
18
|
+
|
|
19
|
+
const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:credential-store')
|
|
20
|
+
|
|
21
|
+
export class DigitalCredentialStore extends AbstractDigitalCredentialStore {
|
|
22
|
+
private readonly dbConnection: OrPromise<DataSource>
|
|
23
|
+
|
|
24
|
+
constructor(dbConnection: OrPromise<DataSource>) {
|
|
25
|
+
super()
|
|
26
|
+
this.dbConnection = dbConnection
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
addCredential = async (args: AddCredentialArgs): Promise<DigitalCredentialEntity> => {
|
|
30
|
+
debug('Adding credential', args)
|
|
31
|
+
const digitalCredentialEntityRepository: Repository<DigitalCredentialEntity> = (await this.dbConnection).getRepository(DigitalCredentialEntity)
|
|
32
|
+
const credentialEntity: NonPersistedDigitalCredential = nonPersistedDigitalCredentialEntityFromAddArgs(args)
|
|
33
|
+
const createdResult: DigitalCredentialEntity = await digitalCredentialEntityRepository.save(credentialEntity)
|
|
34
|
+
return Promise.resolve(createdResult)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getCredential = async (args: GetCredentialArgs): Promise<DigitalCredentialEntity> => {
|
|
38
|
+
const result: DigitalCredentialEntity | null = await (await this.dbConnection).getRepository(DigitalCredentialEntity).findOne({
|
|
39
|
+
where: args,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
if (!result) {
|
|
43
|
+
return Promise.reject(Error(`No credential found for arg: ${args.toString()}`))
|
|
44
|
+
}
|
|
45
|
+
return result
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getCredentials = async (args?: GetCredentialsArgs): Promise<GetCredentialsResponse> => {
|
|
49
|
+
const { filter = {}, offset, limit, order = 'id.asc' } = args ?? {}
|
|
50
|
+
const sortOptions: FindOptionsOrder<DigitalCredentialEntity> =
|
|
51
|
+
order && typeof order === 'string'
|
|
52
|
+
? parseAndValidateOrderOptions<DigitalCredentialEntity>(order)
|
|
53
|
+
: <FindOptionsOrder<DigitalCredentialEntity>>order
|
|
54
|
+
const [result, total] = await (await this.dbConnection).getRepository(DigitalCredentialEntity).findAndCount({
|
|
55
|
+
where: filter,
|
|
56
|
+
skip: offset,
|
|
57
|
+
take: limit,
|
|
58
|
+
order: sortOptions,
|
|
59
|
+
})
|
|
60
|
+
return {
|
|
61
|
+
data: result,
|
|
62
|
+
total,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
removeCredential = async (args: RemoveCredentialArgs): Promise<boolean> => {
|
|
67
|
+
if (!args) {
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let query: FindOptionsWhere<DigitalCredentialEntity> = {}
|
|
72
|
+
|
|
73
|
+
if ('id' in args) {
|
|
74
|
+
query.id = args.id
|
|
75
|
+
} else if ('hash' in args) {
|
|
76
|
+
query.hash = args.hash
|
|
77
|
+
} else {
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const connection = await this.dbConnection
|
|
82
|
+
const result = await connection.getRepository(DigitalCredentialEntity).delete(query)
|
|
83
|
+
return result.affected === 1
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('Error removing digital credential:', error)
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
updateCredentialState = async (args: UpdateCredentialStateArgs): Promise<DigitalCredentialEntity> => {
|
|
91
|
+
const credentialRepository: Repository<DigitalCredentialEntity> = (await this.dbConnection).getRepository(DigitalCredentialEntity)
|
|
92
|
+
const whereClause: Record<string, any> = {}
|
|
93
|
+
if ('id' in args) {
|
|
94
|
+
whereClause.id = args.id
|
|
95
|
+
} else if ('hash' in args) {
|
|
96
|
+
whereClause.hash = args.hash
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error('No id or hash param is provided.')
|
|
99
|
+
}
|
|
100
|
+
if (!args.verifiedState) {
|
|
101
|
+
throw new Error('No verifiedState param is provided.')
|
|
102
|
+
}
|
|
103
|
+
if (args.verifiedState === CredentialStateType.REVOKED && !args.revokedAt) {
|
|
104
|
+
throw new Error('No revokedAt param is provided.')
|
|
105
|
+
}
|
|
106
|
+
if (args.verifiedState !== CredentialStateType.REVOKED && !args.verifiedAt) {
|
|
107
|
+
throw new Error('No verifiedAt param is provided.')
|
|
108
|
+
}
|
|
109
|
+
const credential: DigitalCredentialEntity | null = await credentialRepository.findOne({
|
|
110
|
+
where: whereClause,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
if (!credential) {
|
|
114
|
+
return Promise.reject(Error(`No credential found for args: ${whereClause}`))
|
|
115
|
+
}
|
|
116
|
+
const updatedCredential: DigitalCredential = {
|
|
117
|
+
...credential,
|
|
118
|
+
...(args.verifiedState !== CredentialStateType.REVOKED && { verifiedAt: args.verifiedAt }),
|
|
119
|
+
...(args.verifiedState === CredentialStateType.REVOKED && { revokedAt: args.revokedAt }),
|
|
120
|
+
lastUpdatedAt: new Date(),
|
|
121
|
+
verifiedState: args.verifiedState,
|
|
122
|
+
}
|
|
123
|
+
debug('Updating credential', credential)
|
|
124
|
+
const updatedResult: DigitalCredentialEntity = await credentialRepository.save(updatedCredential, { transaction: true })
|
|
125
|
+
return updatedResult
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BaseEntity,
|
|
3
|
-
BeforeInsert,
|
|
4
|
-
BeforeUpdate,
|
|
5
|
-
CreateDateColumn,
|
|
6
|
-
Entity,
|
|
7
|
-
JoinColumn,
|
|
8
|
-
OneToOne,
|
|
9
|
-
PrimaryGeneratedColumn,
|
|
10
|
-
TableInheritance,
|
|
11
|
-
UpdateDateColumn,
|
|
12
|
-
} from 'typeorm'
|
|
13
|
-
import { PartyEntity } from './PartyEntity'
|
|
14
|
-
|
|
15
|
-
@Entity('BaseContact')
|
|
16
|
-
@TableInheritance({ column: { type: 'varchar', name: 'type' } })
|
|
17
|
-
export abstract class BaseContactEntity extends BaseEntity {
|
|
18
|
-
@PrimaryGeneratedColumn('uuid')
|
|
19
|
-
id!: string
|
|
20
|
-
|
|
21
|
-
@CreateDateColumn({ name: 'created_at', nullable: false })
|
|
22
|
-
createdAt!: Date
|
|
23
|
-
|
|
24
|
-
@UpdateDateColumn({ name: 'last_updated_at', nullable: false })
|
|
25
|
-
lastUpdatedAt!: Date
|
|
26
|
-
|
|
27
|
-
@OneToOne(() => PartyEntity, (party: PartyEntity) => party.contact, {
|
|
28
|
-
onDelete: 'CASCADE',
|
|
29
|
-
})
|
|
30
|
-
@JoinColumn({ name: 'party_id' })
|
|
31
|
-
party!: PartyEntity
|
|
32
|
-
|
|
33
|
-
// By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change.
|
|
34
|
-
@BeforeInsert()
|
|
35
|
-
@BeforeUpdate()
|
|
36
|
-
updateUpdatedDate(): void {
|
|
37
|
-
this.lastUpdatedAt = new Date()
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
BaseEntity,
|
|
3
|
+
BeforeInsert,
|
|
4
|
+
BeforeUpdate,
|
|
5
|
+
CreateDateColumn,
|
|
6
|
+
Entity,
|
|
7
|
+
JoinColumn,
|
|
8
|
+
OneToOne,
|
|
9
|
+
PrimaryGeneratedColumn,
|
|
10
|
+
TableInheritance,
|
|
11
|
+
UpdateDateColumn,
|
|
12
|
+
} from 'typeorm'
|
|
13
|
+
import { PartyEntity } from './PartyEntity'
|
|
14
|
+
|
|
15
|
+
@Entity('BaseContact')
|
|
16
|
+
@TableInheritance({ column: { type: 'varchar', name: 'type' } })
|
|
17
|
+
export abstract class BaseContactEntity extends BaseEntity {
|
|
18
|
+
@PrimaryGeneratedColumn('uuid')
|
|
19
|
+
id!: string
|
|
20
|
+
|
|
21
|
+
@CreateDateColumn({ name: 'created_at', nullable: false })
|
|
22
|
+
createdAt!: Date
|
|
23
|
+
|
|
24
|
+
@UpdateDateColumn({ name: 'last_updated_at', nullable: false })
|
|
25
|
+
lastUpdatedAt!: Date
|
|
26
|
+
|
|
27
|
+
@OneToOne(() => PartyEntity, (party: PartyEntity) => party.contact, {
|
|
28
|
+
onDelete: 'CASCADE',
|
|
29
|
+
})
|
|
30
|
+
@JoinColumn({ name: 'party_id' })
|
|
31
|
+
party!: PartyEntity
|
|
32
|
+
|
|
33
|
+
// By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change.
|
|
34
|
+
@BeforeInsert()
|
|
35
|
+
@BeforeUpdate()
|
|
36
|
+
updateUpdatedDate(): void {
|
|
37
|
+
this.lastUpdatedAt = new Date()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, BaseEntity } from 'typeorm'
|
|
2
|
-
import { BaseConfigEntity } from './BaseConfigEntity'
|
|
3
|
-
import { ConnectionType } from '../../types'
|
|
4
|
-
import { IdentityEntity } from './IdentityEntity'
|
|
5
|
-
import { OpenIdConfigEntity } from './OpenIdConfigEntity'
|
|
6
|
-
import { DidAuthConfigEntity } from './DidAuthConfigEntity'
|
|
7
|
-
|
|
8
|
-
@Entity('Connection')
|
|
9
|
-
export class ConnectionEntity extends BaseEntity {
|
|
10
|
-
@PrimaryGeneratedColumn('uuid')
|
|
11
|
-
id!: string
|
|
12
|
-
|
|
13
|
-
@Column('simple-enum', { name: 'type', enum: ConnectionType, nullable: false })
|
|
14
|
-
type!: ConnectionType
|
|
15
|
-
|
|
16
|
-
@OneToOne(() => BaseConfigEntity, (config: OpenIdConfigEntity | DidAuthConfigEntity) => config.connection, {
|
|
17
|
-
cascade: true,
|
|
18
|
-
onDelete: 'CASCADE',
|
|
19
|
-
eager: true,
|
|
20
|
-
nullable: false,
|
|
21
|
-
})
|
|
22
|
-
config!: BaseConfigEntity
|
|
23
|
-
|
|
24
|
-
@OneToOne(() => IdentityEntity, (identity: IdentityEntity) => identity.connection, {
|
|
25
|
-
onDelete: 'CASCADE',
|
|
26
|
-
})
|
|
27
|
-
@JoinColumn({ name: 'identity_id' })
|
|
28
|
-
identity!: IdentityEntity
|
|
29
|
-
}
|
|
1
|
+
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, BaseEntity } from 'typeorm'
|
|
2
|
+
import { BaseConfigEntity } from './BaseConfigEntity'
|
|
3
|
+
import { ConnectionType } from '../../types'
|
|
4
|
+
import { IdentityEntity } from './IdentityEntity'
|
|
5
|
+
import { OpenIdConfigEntity } from './OpenIdConfigEntity'
|
|
6
|
+
import { DidAuthConfigEntity } from './DidAuthConfigEntity'
|
|
7
|
+
|
|
8
|
+
@Entity('Connection')
|
|
9
|
+
export class ConnectionEntity extends BaseEntity {
|
|
10
|
+
@PrimaryGeneratedColumn('uuid')
|
|
11
|
+
id!: string
|
|
12
|
+
|
|
13
|
+
@Column('simple-enum', { name: 'type', enum: ConnectionType, nullable: false })
|
|
14
|
+
type!: ConnectionType
|
|
15
|
+
|
|
16
|
+
@OneToOne(() => BaseConfigEntity, (config: OpenIdConfigEntity | DidAuthConfigEntity) => config.connection, {
|
|
17
|
+
cascade: true,
|
|
18
|
+
onDelete: 'CASCADE',
|
|
19
|
+
eager: true,
|
|
20
|
+
nullable: false,
|
|
21
|
+
})
|
|
22
|
+
config!: BaseConfigEntity
|
|
23
|
+
|
|
24
|
+
@OneToOne(() => IdentityEntity, (identity: IdentityEntity) => identity.connection, {
|
|
25
|
+
onDelete: 'CASCADE',
|
|
26
|
+
})
|
|
27
|
+
@JoinColumn({ name: 'identity_id' })
|
|
28
|
+
identity!: IdentityEntity
|
|
29
|
+
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { Entity, Column, PrimaryGeneratedColumn, BaseEntity, OneToOne, JoinColumn, BeforeInsert, BeforeUpdate } from 'typeorm'
|
|
2
|
-
import { CorrelationIdentifierType, ValidationConstraint } from '../../types'
|
|
3
|
-
import { IdentityEntity } from './IdentityEntity'
|
|
4
|
-
import { IsNotEmpty, validate, ValidationError } from 'class-validator'
|
|
5
|
-
import { getConstraint } from '../../utils/ValidatorUtils'
|
|
6
|
-
|
|
7
|
-
@Entity('CorrelationIdentifier')
|
|
8
|
-
export class CorrelationIdentifierEntity extends BaseEntity {
|
|
9
|
-
@PrimaryGeneratedColumn('uuid')
|
|
10
|
-
id!: string
|
|
11
|
-
|
|
12
|
-
@Column('simple-enum', { name: 'type', enum: CorrelationIdentifierType, nullable: false })
|
|
13
|
-
type!: CorrelationIdentifierType
|
|
14
|
-
|
|
15
|
-
@Column('text', { name: 'correlation_id', nullable: false, unique: true })
|
|
16
|
-
@IsNotEmpty({ message: 'Blank correlation ids are not allowed' })
|
|
17
|
-
correlationId!: string
|
|
18
|
-
|
|
19
|
-
@OneToOne(() => IdentityEntity, (identity: IdentityEntity) => identity.identifier, {
|
|
20
|
-
onDelete: 'CASCADE',
|
|
21
|
-
})
|
|
22
|
-
@JoinColumn({ name: 'identity_id' })
|
|
23
|
-
identity!: IdentityEntity
|
|
24
|
-
|
|
25
|
-
@BeforeInsert()
|
|
26
|
-
@BeforeUpdate()
|
|
27
|
-
async validate(): Promise<void> {
|
|
28
|
-
const validation: Array<ValidationError> = await validate(this)
|
|
29
|
-
if (validation.length > 0) {
|
|
30
|
-
const constraint: ValidationConstraint | undefined = getConstraint(validation[0])
|
|
31
|
-
if (constraint) {
|
|
32
|
-
const message: string = Object.values(constraint!)[0]
|
|
33
|
-
return Promise.reject(Error(message))
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
1
|
+
import { Entity, Column, PrimaryGeneratedColumn, BaseEntity, OneToOne, JoinColumn, BeforeInsert, BeforeUpdate } from 'typeorm'
|
|
2
|
+
import { CorrelationIdentifierType, ValidationConstraint } from '../../types'
|
|
3
|
+
import { IdentityEntity } from './IdentityEntity'
|
|
4
|
+
import { IsNotEmpty, validate, ValidationError } from 'class-validator'
|
|
5
|
+
import { getConstraint } from '../../utils/ValidatorUtils'
|
|
6
|
+
|
|
7
|
+
@Entity('CorrelationIdentifier')
|
|
8
|
+
export class CorrelationIdentifierEntity extends BaseEntity {
|
|
9
|
+
@PrimaryGeneratedColumn('uuid')
|
|
10
|
+
id!: string
|
|
11
|
+
|
|
12
|
+
@Column('simple-enum', { name: 'type', enum: CorrelationIdentifierType, nullable: false })
|
|
13
|
+
type!: CorrelationIdentifierType
|
|
14
|
+
|
|
15
|
+
@Column('text', { name: 'correlation_id', nullable: false, unique: true })
|
|
16
|
+
@IsNotEmpty({ message: 'Blank correlation ids are not allowed' })
|
|
17
|
+
correlationId!: string
|
|
18
|
+
|
|
19
|
+
@OneToOne(() => IdentityEntity, (identity: IdentityEntity) => identity.identifier, {
|
|
20
|
+
onDelete: 'CASCADE',
|
|
21
|
+
})
|
|
22
|
+
@JoinColumn({ name: 'identity_id' })
|
|
23
|
+
identity!: IdentityEntity
|
|
24
|
+
|
|
25
|
+
@BeforeInsert()
|
|
26
|
+
@BeforeUpdate()
|
|
27
|
+
async validate(): Promise<void> {
|
|
28
|
+
const validation: Array<ValidationError> = await validate(this)
|
|
29
|
+
if (validation.length > 0) {
|
|
30
|
+
const constraint: ValidationConstraint | undefined = getConstraint(validation[0])
|
|
31
|
+
if (constraint) {
|
|
32
|
+
const message: string = Object.values(constraint!)[0]
|
|
33
|
+
return Promise.reject(Error(message))
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { ChildEntity, Column } from 'typeorm'
|
|
2
|
-
import { BaseConfigEntity } from './BaseConfigEntity'
|
|
3
|
-
|
|
4
|
-
@ChildEntity('DidAuthConfig')
|
|
5
|
-
export class DidAuthConfigEntity extends BaseConfigEntity {
|
|
6
|
-
@Column({ name: 'identifier', length: 255, nullable: false })
|
|
7
|
-
identifier!: string
|
|
8
|
-
|
|
9
|
-
@Column({ name: 'redirect_url', length: 255, nullable: false })
|
|
10
|
-
redirectUrl!: string
|
|
11
|
-
|
|
12
|
-
@Column({ name: 'session_id', length: 255, nullable: false })
|
|
13
|
-
sessionId!: string
|
|
14
|
-
}
|
|
1
|
+
import { ChildEntity, Column } from 'typeorm'
|
|
2
|
+
import { BaseConfigEntity } from './BaseConfigEntity'
|
|
3
|
+
|
|
4
|
+
@ChildEntity('DidAuthConfig')
|
|
5
|
+
export class DidAuthConfigEntity extends BaseConfigEntity {
|
|
6
|
+
@Column({ name: 'identifier', length: 255, nullable: false })
|
|
7
|
+
identifier!: string
|
|
8
|
+
|
|
9
|
+
@Column({ name: 'redirect_url', length: 255, nullable: false })
|
|
10
|
+
redirectUrl!: string
|
|
11
|
+
|
|
12
|
+
@Column({ name: 'session_id', length: 255, nullable: false })
|
|
13
|
+
sessionId!: string
|
|
14
|
+
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import { IsNotEmpty, validate, ValidationError } from 'class-validator'
|
|
2
|
-
import {
|
|
3
|
-
Entity,
|
|
4
|
-
Column,
|
|
5
|
-
PrimaryGeneratedColumn,
|
|
6
|
-
BaseEntity,
|
|
7
|
-
ManyToOne,
|
|
8
|
-
BeforeInsert,
|
|
9
|
-
BeforeUpdate,
|
|
10
|
-
CreateDateColumn,
|
|
11
|
-
UpdateDateColumn,
|
|
12
|
-
} from 'typeorm'
|
|
13
|
-
import { PartyEntity } from './PartyEntity'
|
|
14
|
-
import { getConstraint } from '../../utils/ValidatorUtils'
|
|
15
|
-
import { ElectronicAddressType, ValidationConstraint } from '../../types'
|
|
16
|
-
|
|
17
|
-
@Entity('ElectronicAddress')
|
|
18
|
-
export class ElectronicAddressEntity extends BaseEntity {
|
|
19
|
-
@PrimaryGeneratedColumn('uuid')
|
|
20
|
-
id!: string
|
|
21
|
-
|
|
22
|
-
@Column({ name: 'type', length: 255, nullable: false })
|
|
23
|
-
@IsNotEmpty({ message: 'Blank electronic address types are not allowed' })
|
|
24
|
-
type!: ElectronicAddressType
|
|
25
|
-
|
|
26
|
-
@Column({ name: 'electronic_address', length: 255, nullable: false })
|
|
27
|
-
@IsNotEmpty({ message: 'Blank electronic addresses are not allowed' })
|
|
28
|
-
electronicAddress!: string
|
|
29
|
-
|
|
30
|
-
@ManyToOne(() => PartyEntity, (party: PartyEntity) => party.electronicAddresses, {
|
|
31
|
-
onDelete: 'CASCADE',
|
|
32
|
-
})
|
|
33
|
-
party!: PartyEntity
|
|
34
|
-
|
|
35
|
-
@Column({ name: 'partyId', nullable: true })
|
|
36
|
-
partyId?: string
|
|
37
|
-
|
|
38
|
-
@CreateDateColumn({ name: 'created_at', nullable: false })
|
|
39
|
-
createdAt!: Date
|
|
40
|
-
|
|
41
|
-
@UpdateDateColumn({ name: 'last_updated_at', nullable: false })
|
|
42
|
-
lastUpdatedAt!: Date
|
|
43
|
-
|
|
44
|
-
// By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change.
|
|
45
|
-
@BeforeInsert()
|
|
46
|
-
@BeforeUpdate()
|
|
47
|
-
updateUpdatedDate(): void {
|
|
48
|
-
this.lastUpdatedAt = new Date()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@BeforeInsert()
|
|
52
|
-
@BeforeUpdate()
|
|
53
|
-
async validate(): Promise<void> {
|
|
54
|
-
const validation: Array<ValidationError> = await validate(this)
|
|
55
|
-
if (validation.length > 0) {
|
|
56
|
-
const constraint: ValidationConstraint | undefined = getConstraint(validation[0])
|
|
57
|
-
if (constraint) {
|
|
58
|
-
const message: string = Object.values(constraint!)[0]
|
|
59
|
-
return Promise.reject(Error(message))
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
import { IsNotEmpty, validate, ValidationError } from 'class-validator'
|
|
2
|
+
import {
|
|
3
|
+
Entity,
|
|
4
|
+
Column,
|
|
5
|
+
PrimaryGeneratedColumn,
|
|
6
|
+
BaseEntity,
|
|
7
|
+
ManyToOne,
|
|
8
|
+
BeforeInsert,
|
|
9
|
+
BeforeUpdate,
|
|
10
|
+
CreateDateColumn,
|
|
11
|
+
UpdateDateColumn,
|
|
12
|
+
} from 'typeorm'
|
|
13
|
+
import { PartyEntity } from './PartyEntity'
|
|
14
|
+
import { getConstraint } from '../../utils/ValidatorUtils'
|
|
15
|
+
import { ElectronicAddressType, ValidationConstraint } from '../../types'
|
|
16
|
+
|
|
17
|
+
@Entity('ElectronicAddress')
|
|
18
|
+
export class ElectronicAddressEntity extends BaseEntity {
|
|
19
|
+
@PrimaryGeneratedColumn('uuid')
|
|
20
|
+
id!: string
|
|
21
|
+
|
|
22
|
+
@Column({ name: 'type', length: 255, nullable: false })
|
|
23
|
+
@IsNotEmpty({ message: 'Blank electronic address types are not allowed' })
|
|
24
|
+
type!: ElectronicAddressType
|
|
25
|
+
|
|
26
|
+
@Column({ name: 'electronic_address', length: 255, nullable: false })
|
|
27
|
+
@IsNotEmpty({ message: 'Blank electronic addresses are not allowed' })
|
|
28
|
+
electronicAddress!: string
|
|
29
|
+
|
|
30
|
+
@ManyToOne(() => PartyEntity, (party: PartyEntity) => party.electronicAddresses, {
|
|
31
|
+
onDelete: 'CASCADE',
|
|
32
|
+
})
|
|
33
|
+
party!: PartyEntity
|
|
34
|
+
|
|
35
|
+
@Column({ name: 'partyId', nullable: true })
|
|
36
|
+
partyId?: string
|
|
37
|
+
|
|
38
|
+
@CreateDateColumn({ name: 'created_at', nullable: false })
|
|
39
|
+
createdAt!: Date
|
|
40
|
+
|
|
41
|
+
@UpdateDateColumn({ name: 'last_updated_at', nullable: false })
|
|
42
|
+
lastUpdatedAt!: Date
|
|
43
|
+
|
|
44
|
+
// By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change.
|
|
45
|
+
@BeforeInsert()
|
|
46
|
+
@BeforeUpdate()
|
|
47
|
+
updateUpdatedDate(): void {
|
|
48
|
+
this.lastUpdatedAt = new Date()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@BeforeInsert()
|
|
52
|
+
@BeforeUpdate()
|
|
53
|
+
async validate(): Promise<void> {
|
|
54
|
+
const validation: Array<ValidationError> = await validate(this)
|
|
55
|
+
if (validation.length > 0) {
|
|
56
|
+
const constraint: ValidationConstraint | undefined = getConstraint(validation[0])
|
|
57
|
+
if (constraint) {
|
|
58
|
+
const message: string = Object.values(constraint!)[0]
|
|
59
|
+
return Promise.reject(Error(message))
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|