Skip to content

Decorators Example

Following from the validators example. I am going to create a decorator that attaches the number of tokens a user has left to create notes when they try to get a note.

Here is the decorator implementation stored on a file named get.note.decorator.ts in the decorators directory of my app:

typescript
import { UriBuilder, UriParser } from '@coderpunktech/vulcan-sdk-core'

export const GetNoteDecorator: DeferredFunction<
  RecordDecoratorArgs<Environment, Variables, Note>,
  RecordDecoratorResult<Note>
> = async (
  args: RecordDecoratorArgs<Environment, Variables, Note>,
): Promise<RecordDecoratorResult<Note>> => {
  // get the note record to decorate
  const record: Note = args.record


  // create the uri to locate the user's token record
  const tokenStoreUri = UriParser.parse(
    new UriBuilder()
      .with(Descriptor.C, URIContexts.S)
      // use the user account id as the context id
      .with(Descriptor.CI, context.get('jwtPayload')!.sub)
      .with(Descriptor.E, AppEntities.TOKEN)
      .with(Descriptor.EI, 'default')
      .with(Descriptor.P, [])
      .build(),
  )
  // create a service container
  const serviceContainer = new sdk.Services.RequestServiceContainerFactory().build({ context })
  // get the repository service instance
  const repoService: RepositoryService = serviceContainer.get<RepositoryService>(ServiceInjectorKeys.REPOSITORY_SERVICE)
  // find the user token store document
  const tokenStore = await repoService.findRecord<TokenStore | null>(tokenStoreUri)

  const decoratedNote: Note = {
    ...record,
    tokens: tokenStore ? tokenStore.tokens : 0,
  }

  return {
    decoratedNote,
    uri: args.uri,
  }
}

To wire this decorator to the Vulcan Core SDK, I would do the following:

typescript
import { GetNoteDecorator } from '@/decorators/get.note.decorator'

const sdk: SDK = Sdk({
  recordDecorators: {
    getRecord: {
      note: GetNoteDecorator,
    },
  },
})