@veramo/data-store
Version:
Veramo data storage plugin based on TypeORM database drivers
230 lines (188 loc) • 5.33 kB
text/typescript
import {
BaseEntity,
BeforeInsert,
BeforeUpdate,
Column,
Entity,
JoinTable,
ManyToMany,
ManyToOne,
PrimaryColumn,
Relation,
} from 'typeorm'
import { IMessage } from '@veramo/core-types'
import { Identifier } from './identifier.js'
import { createPresentationEntity, Presentation } from './presentation.js'
import { createCredentialEntity, Credential } from './credential.js'
import { computeEntryHash } from '@veramo/utils'
import { v4 as uuidv4 } from 'uuid'
/**
* Represents message metadata as it is stored by {@link @veramo/data-store#DataStore | DataStore}.
*
* This metadata is most often used by {@link @veramo/message-handler#MessageHandler | MessageHandler} and
* {@link @veramo/core-types#IMessageHandler | IMessageHandler} implementations to decorate messages that are interpreted and
* decoded, but not returned as final, as they pass through the message handler chain.
*
* @beta - This API may change without a BREAKING CHANGE notice.
*/
export interface MetaData {
type: string
value?: string
}
/**
* Represents some common properties of an {@link @veramo/core-types#IMessage} that are stored in a TypeORM database for
* querying.
*
* @see {@link @veramo/core-types#IDataStoreORM.dataStoreORMGetMessages | dataStoreORMGetMessages}
* for the interface defining how this can be queried
*
* @see {@link @veramo/data-store#DataStoreORM | DataStoreORM} for the implementation of the query interface.
*
* @beta This API may change without a BREAKING CHANGE notice.
*/
('message')
export class Message extends BaseEntity {
()
setId() {
if (!this.id) {
this.id = computeEntryHash(this.raw || uuidv4())
}
}
()
// @ts-ignore
id: string
()
setSaveDate() {
this.saveDate = new Date()
this.updateDate = new Date()
}
()
setUpdateDate() {
this.updateDate = new Date()
}
({ select: false })
// @ts-ignore
saveDate: Date
({ select: false })
// @ts-ignore
updateDate: Date
({ nullable: true })
createdAt?: Date
({ nullable: true })
expiresAt?: Date
({ nullable: true })
threadId?: string
()
// @ts-ignore
type: string
({ nullable: true })
raw?: string
('simple-json', { nullable: true })
data?: object | null
// https://github.com/decentralized-identifier/didcomm-messaging/blob/41f35f992275dd71d459504d14eb8d70b4185533/jwm.md#jwm-profile
('simple-array', { nullable: true })
replyTo?: string[]
({ nullable: true })
replyUrl?: string
((type) => Identifier, (identifier) => identifier.sentMessages, {
nullable: true,
cascade: ['insert'],
eager: true,
onDelete: 'CASCADE',
})
from?: Relation<Identifier>
((type) => Identifier, (identifier) => identifier.receivedMessages, {
nullable: true,
cascade: ['insert'],
eager: true,
onDelete: 'CASCADE',
})
to?: Relation<Identifier>
('simple-json', { nullable: true })
metaData?: MetaData[] | null
((type) => Presentation, (presentation) => presentation.messages, {
cascade: true,
})
()
// @ts-ignore
presentations: Relation<Presentation[]>
((type) => Credential, (credential) => credential.messages, { cascade: true })
()
// @ts-ignore
credentials: Relation<Credential[]>
}
export const createMessageEntity = (args: IMessage): Message => {
const message = new Message()
message.id = args.id
message.threadId = args.threadId
message.type = args.type
message.raw = args.raw
message.data = args.data
message.metaData = args.metaData
if (args.replyTo) {
message.replyTo = args.replyTo
}
if (args.replyUrl) {
message.replyUrl = args.replyUrl
}
if (args.createdAt) {
message.createdAt = new Date(args.createdAt)
}
if (args.expiresAt) {
message.createdAt = new Date(args.expiresAt)
}
if (args.from) {
const from = new Identifier()
from.did = args.from
message.from = from
}
if (args.to) {
const to = new Identifier()
to.did = args.to
message.to = to
}
if (args.presentations) {
message.presentations = args.presentations.map(createPresentationEntity)
}
if (args.credentials) {
message.credentials = args.credentials.map(createCredentialEntity)
}
return message
}
export const createMessage = (args: Message): IMessage => {
const message: Partial<IMessage> = {
id: args.id,
type: args.type,
raw: args.raw,
data: args.data,
metaData: args.metaData,
}
if (args.threadId) {
message.threadId = args.threadId
}
if (args.replyTo) {
message.replyTo = args.replyTo
}
if (args.replyTo) {
message.replyUrl = args.replyUrl
}
if (args.createdAt) {
message.createdAt = args.createdAt.toISOString()
}
if (args.expiresAt) {
message.expiresAt = args.expiresAt.toISOString()
}
if (args.from) {
message.from = args.from.did
}
if (args.to) {
message.to = args.to.did
}
if (args.presentations) {
message.presentations = args.presentations.map((vp) => vp.raw)
}
if (args.credentials) {
message.credentials = args.credentials.map((vc) => vc.raw)
}
return message as IMessage
}