Skip to content

Commit

Permalink
fix(core)!: Improved typing on metadata api (#585)
Browse files Browse the repository at this point in the history
Signed-off-by: Berend Sliedrecht <[email protected]>

BREAKING CHANGE: removed the getAll() function.
  • Loading branch information
berendsliedrecht authored Dec 23, 2021
1 parent ef6b8bc commit 4ab8d73
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CredentialState } from '../CredentialState'
import { CredentialPreviewAttribute } from '../messages'
import { CredentialRecord } from '../repository/CredentialRecord'
import { CredentialMetadataKeys } from '../repository/credentialMetadataTypes'

describe('CredentialRecord', () => {
describe('getCredentialInfo()', () => {
Expand All @@ -17,7 +18,7 @@ describe('CredentialRecord', () => {
],
})

credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
credentialDefinitionId: 'Th7MpTaRZVRYnPiabds81Y:3:CL:17:TAG',
schemaId: 'TL1EaPFCZ8Si5aUrqScBDt:2:test-schema-1599055118161:1.0',
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
} from '../messages'
import { CredentialRecord } from '../repository/CredentialRecord'
import { CredentialRepository } from '../repository/CredentialRepository'
import { CredentialMetadataKeys } from '../repository/credentialMetadataTypes'
import { CredentialService } from '../services'

import { CredentialProblemReportMessage } from './../messages/CredentialProblemReportMessage'
Expand Down Expand Up @@ -126,17 +127,17 @@ const mockCredentialRecord = ({
})

if (metadata?.indyRequest) {
credentialRecord.metadata.set('_internal/indyRequest', { ...metadata.indyRequest })
credentialRecord.metadata.set(CredentialMetadataKeys.IndyRequest, { ...metadata.indyRequest })
}

if (metadata?.schemaId) {
credentialRecord.metadata.add('_internal/indyCredential', {
credentialRecord.metadata.add(CredentialMetadataKeys.IndyCredential, {
schemaId: metadata.schemaId,
})
}

if (metadata?.credentialDefinitionId) {
credentialRecord.metadata.add('_internal/indyCredential', {
credentialRecord.metadata.add(CredentialMetadataKeys.IndyCredential, {
credentialDefinitionId: metadata.credentialDefinitionId,
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { TagsBase } from '../../../storage/BaseRecord'
import type { AutoAcceptCredential } from '../CredentialAutoAcceptType'
import type { CredentialState } from '../CredentialState'
import type { CredentialMetadata } from './credentialMetadataTypes'

import { Type } from 'class-transformer'

Expand Down Expand Up @@ -44,7 +45,7 @@ export type DefaultCredentialTags = {
credentialId?: string
}

export class CredentialRecord extends BaseRecord<DefaultCredentialTags, CustomCredentialTags> {
export class CredentialRecord extends BaseRecord<DefaultCredentialTags, CustomCredentialTags, CredentialMetadata> {
public connectionId?: string
public threadId!: string
public credentialId?: string
Expand Down Expand Up @@ -118,7 +119,7 @@ export class CredentialRecord extends BaseRecord<DefaultCredentialTags, CustomCr
return new CredentialInfo({
claims,
attachments: this.linkedAttachments,
metadata: this.metadata.getAll(),
metadata: this.metadata.data,
})
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { CredReqMetadata } from 'indy-sdk'

export enum CredentialMetadataKeys {
IndyCredential = '_internal/indyCredential',
IndyRequest = '_internal/indyRequest',
}

export type CredentialMetadata = {
[CredentialMetadataKeys.IndyCredential]: {
schemaId?: string
credentialDefinitionId?: string
}
[CredentialMetadataKeys.IndyRequest]: CredReqMetadata
}
1 change: 1 addition & 0 deletions packages/core/src/modules/credentials/repository/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './CredentialRecord'
export * from './CredentialRepository'
export * from './credentialMetadataTypes'
32 changes: 16 additions & 16 deletions packages/core/src/modules/credentials/services/CredentialService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import type { ConnectionRecord } from '../../connections'
import type { AutoAcceptCredential } from '../CredentialAutoAcceptType'
import type { CredentialStateChangedEvent } from '../CredentialEvents'
import type { CredentialProblemReportMessage, ProposeCredentialMessageOptions } from '../messages'
import type { CredReqMetadata } from 'indy-sdk'

import { scoped, Lifecycle } from 'tsyringe'
import { Lifecycle, scoped } from 'tsyringe'

import { AgentConfig } from '../../../agent/AgentConfig'
import { EventEmitter } from '../../../agent/EventEmitter'
Expand All @@ -19,25 +18,26 @@ import { isLinkedAttachment } from '../../../utils/attachment'
import { uuid } from '../../../utils/uuid'
import { AckStatus } from '../../common'
import { ConnectionService } from '../../connections/services/ConnectionService'
import { IndyIssuerService, IndyHolderService } from '../../indy'
import { IndyHolderService, IndyIssuerService } from '../../indy'
import { IndyLedgerService } from '../../ledger/services/IndyLedgerService'
import { CredentialEventTypes } from '../CredentialEvents'
import { CredentialState } from '../CredentialState'
import { CredentialUtils } from '../CredentialUtils'
import { CredentialProblemReportError, CredentialProblemReportReason } from '../errors'
import {
CredentialAckMessage,
CredentialPreview,
INDY_CREDENTIAL_ATTACHMENT_ID,
INDY_CREDENTIAL_OFFER_ATTACHMENT_ID,
INDY_CREDENTIAL_REQUEST_ATTACHMENT_ID,
IssueCredentialMessage,
OfferCredentialMessage,
ProposeCredentialMessage,
CredentialPreview,
RequestCredentialMessage,
CredentialAckMessage,
INDY_CREDENTIAL_ATTACHMENT_ID,
} from '../messages'
import { CredentialRepository } from '../repository'
import { CredentialRecord } from '../repository/CredentialRecord'
import { CredentialMetadataKeys } from '../repository/credentialMetadataTypes'

@scoped(Lifecycle.ContainerScoped)
export class CredentialService {
Expand Down Expand Up @@ -109,9 +109,9 @@ export class CredentialService {
})

// Set the metadata
credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
schemaId: options.schemaId,
credentialDefinintionId: options.credentialDefinitionId,
credentialDefinitionId: options.credentialDefinitionId,
})

await this.credentialRepository.save(credentialRecord)
Expand Down Expand Up @@ -196,7 +196,7 @@ export class CredentialService {
state: CredentialState.ProposalReceived,
})

credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
schemaId: proposalMessage.schemaId,
credentialDefinitionId: proposalMessage.credentialDefinitionId,
})
Expand Down Expand Up @@ -257,7 +257,7 @@ export class CredentialService {

credentialRecord.offerMessage = credentialOfferMessage
credentialRecord.credentialAttributes = preview.attributes
credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
schemaId: credOffer.schema_id,
credentialDefinitionId: credOffer.cred_def_id,
})
Expand Down Expand Up @@ -321,7 +321,7 @@ export class CredentialService {
autoAcceptCredential: credentialTemplate.autoAcceptCredential,
})

credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
credentialDefinitionId: credOffer.cred_def_id,
schemaId: credOffer.schema_id,
})
Expand Down Expand Up @@ -376,7 +376,7 @@ export class CredentialService {
credentialRecord.offerMessage = credentialOfferMessage
credentialRecord.linkedAttachments = credentialOfferMessage.attachments?.filter(isLinkedAttachment)

credentialRecord.metadata.set('_internal/indyCredential', {
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
schemaId: indyCredentialOffer.schema_id,
credentialDefinitionId: indyCredentialOffer.cred_def_id,
})
Expand All @@ -392,9 +392,9 @@ export class CredentialService {
state: CredentialState.OfferReceived,
})

credentialRecord.metadata.set('_internal/indyCredential', {
credentialDefinitionId: indyCredentialOffer.cred_def_id,
credentialRecord.metadata.set(CredentialMetadataKeys.IndyCredential, {
schemaId: indyCredentialOffer.schema_id,
credentialDefinitionId: indyCredentialOffer.cred_def_id,
})

// Assert
Expand Down Expand Up @@ -461,7 +461,7 @@ export class CredentialService {
})
credentialRequest.setThread({ threadId: credentialRecord.threadId })

credentialRecord.metadata.set('_internal/indyRequest', credReqMetadata)
credentialRecord.metadata.set(CredentialMetadataKeys.IndyRequest, credReqMetadata)
credentialRecord.requestMessage = credentialRequest
credentialRecord.autoAcceptCredential = options?.autoAcceptCredential ?? credentialRecord.autoAcceptCredential

Expand Down Expand Up @@ -629,7 +629,7 @@ export class CredentialService {
previousSentMessage: credentialRecord.requestMessage,
})

const credentialRequestMetadata = credentialRecord.metadata.get<CredReqMetadata>('_internal/indyRequest')
const credentialRequestMetadata = credentialRecord.metadata.get(CredentialMetadataKeys.IndyRequest)

if (!credentialRequestMetadata) {
throw new CredentialProblemReportError(
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/storage/BaseRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export type Tags<DefaultTags extends TagsBase, CustomTags extends TagsBase> = Cu

export type RecordTags<Record extends BaseRecord> = ReturnType<Record['getTags']>

export abstract class BaseRecord<DefaultTags extends TagsBase = TagsBase, CustomTags extends TagsBase = TagsBase> {
export abstract class BaseRecord<
DefaultTags extends TagsBase = TagsBase,
CustomTags extends TagsBase = TagsBase,
MetadataValues = undefined
> {
protected _tags: CustomTags = {} as CustomTags

public id!: string
Expand All @@ -32,7 +36,7 @@ export abstract class BaseRecord<DefaultTags extends TagsBase = TagsBase, Custom

/** @inheritdoc {Metadata#Metadata} */
@MetadataTransformer()
public metadata: Metadata = new Metadata({})
public metadata: Metadata<MetadataValues> = new Metadata({})

/**
* Get all tags. This is includes custom and default tags
Expand Down
39 changes: 23 additions & 16 deletions packages/core/src/storage/Metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@ export type MetadataBase = {
}

/**
* Metadata access class to get, set (create and update) and delete
* metadata on any record.
* Metadata access class to get, set (create and update), add (append to a record) and delete metadata on any record.
*
* set will override the previous value if it already exists
*
* note: To add persistence to these records, you have to
* update the record in the correct repository
* note: To add persistence to these records, you have to update the record in the correct repository
*
* @example
*
* ```ts
* connectionRecord.metadata.set('foo', { bar: 'baz' })
* connectionRepository.update(connectionRecord)
* connectionRecord.metadata.set('foo', { bar: 'baz' }) connectionRepository.update(connectionRecord)
* ```
*/
export class Metadata {
export class Metadata<MetadataTypes> {
public readonly data: MetadataBase

public constructor(data: MetadataBase) {
Expand All @@ -28,22 +25,29 @@ export class Metadata {
/**
* Gets the value by key in the metadata
*
* Any extension of the `BaseRecord` can implement their own typed metadata
*
* @param key the key to retrieve the metadata by
* @returns the value saved in the key value pair
* @returns null when the key could not be found
*/
public get<T extends Record<string, unknown>>(key: string): T | null {
return (this.data[key] as T) ?? null
public get<Value extends Record<string, unknown>, Key extends string = string>(
key: Key
): (Key extends keyof MetadataTypes ? MetadataTypes[Key] : Value) | null {
return (this.data[key] as Key extends keyof MetadataTypes ? MetadataTypes[Key] : Value) ?? null
}

/**
* Will set, or override, a key value pair on the metadata
* Will set, or override, a key-value pair on the metadata
*
* @param key the key to set the metadata by
* @param value the value to set in the metadata
*/
public set(key: string, value: Record<string, unknown>): void {
this.data[key] = value
public set<Value extends Record<string, unknown>, Key extends string = string>(
key: Key,
value: Key extends keyof MetadataTypes ? MetadataTypes[Key] : Value
): void {
this.data[key] = value as Record<string, unknown>
}

/**
Expand All @@ -52,7 +56,10 @@ export class Metadata {
* @param key the key to add the metadata at
* @param value the value to add in the metadata
*/
public add(key: string, value: Record<string, unknown>): void {
public add<Value extends Record<string, unknown>, Key extends string = string>(
key: Key,
value: Partial<Key extends keyof MetadataTypes ? MetadataTypes[Key] : Value>
): void {
this.data[key] = {
...this.data[key],
...value,
Expand All @@ -64,16 +71,16 @@ export class Metadata {
*
* @returns all the metadata that exists on the record
*/
public getAll(): MetadataBase {
return this.data
public get keys(): string[] {
return Object.keys(this.data)
}

/**
* Will delete the key value pair in the metadata
*
* @param key the key to delete the data by
*/
public delete(key: string): void {
public delete<Key extends string = string>(key: Key): void {
delete this.data[key]
}
}
2 changes: 1 addition & 1 deletion packages/core/src/storage/Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { BaseRecordConstructor, Query, StorageService } from './StorageServ
import { RecordDuplicateError, RecordNotFoundError } from '../error'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class Repository<T extends BaseRecord<any, any>> {
export class Repository<T extends BaseRecord<any, any, any>> {
private storageService: StorageService<T>
private recordClass: BaseRecordConstructor<T>

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/storage/StorageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface BaseRecordConstructor<T> extends Constructor<T> {
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface StorageService<T extends BaseRecord<any, any>> {
export interface StorageService<T extends BaseRecord<any, any, any>> {
/**
* Save record in storage
*
Expand Down
Loading

0 comments on commit 4ab8d73

Please sign in to comment.