import type { ChannelReference, CustomerReference, ProductReference, RequiredFieldError, Review, ReviewDraft, ReviewSetAuthorNameAction, ReviewSetCustomerAction, ReviewSetCustomFieldAction, ReviewSetCustomTypeAction, ReviewSetKeyAction, ReviewSetLocaleAction, ReviewSetRatingAction, ReviewSetTargetAction, ReviewSetTextAction, ReviewSetTitleAction, ReviewTransitionStateAction, ReviewUpdateAction, StateReference, } from "@commercetools/platform-sdk"; import type { Config } from "#src/config.ts"; import { CommercetoolsError } from "#src/exceptions.ts"; import { ReviewDraftSchema } from "#src/schemas/generated/review.ts"; import { getBaseResourceProperties } from "../helpers.ts"; import type { Writable } from "../types.ts"; import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts"; import { AbstractResourceRepository, AbstractUpdateHandler, } from "./abstract.ts"; import { createCustomFields, getReferenceFromResourceIdentifier, } from "./helpers.ts"; export class ReviewRepository extends AbstractResourceRepository<"review"> { constructor(config: Config) { super("review", config); this.actions = new ReviewUpdateHandler(config.storage); this.draftSchema = ReviewDraftSchema; } async create( context: RepositoryContext, draft: ReviewDraft, ): Promise { if (!draft.target) throw new CommercetoolsError( { code: "RequiredField", message: "Missing target", field: "target", }, 400, ); const resource: Review = { ...getBaseResourceProperties(context.clientId), key: draft.key, locale: draft.locale, authorName: draft.authorName, title: draft.title, text: draft.text, rating: draft.rating, uniquenessValue: draft.uniquenessValue, state: draft.state ? await getReferenceFromResourceIdentifier( draft.state, context.projectKey, this._storage, ) : undefined, target: draft.target ? await getReferenceFromResourceIdentifier< ProductReference | ChannelReference >(draft.target, context.projectKey, this._storage) : undefined, includedInStatistics: true, custom: await createCustomFields( draft.custom, context.projectKey, this._storage, ), }; return await this.saveNew(context, resource); } } class ReviewUpdateHandler extends AbstractUpdateHandler implements UpdateHandlerInterface { setAuthorName( context: RepositoryContext, resource: Writable, { authorName }: ReviewSetAuthorNameAction, ) { resource.authorName = authorName; } setCustomField( context: RepositoryContext, resource: Writable, { name, value }: ReviewSetCustomFieldAction, ) { this._setCustomFieldValues(resource, { name, value }); } async setCustomType( context: RepositoryContext, resource: Writable, { type, fields }: ReviewSetCustomTypeAction, ) { await this._setCustomType(context, resource, { type, fields }); } async setCustomer( context: RepositoryContext, resource: Writable, { customer }: ReviewSetCustomerAction, ) { resource.customer = customer ? await getReferenceFromResourceIdentifier( customer, context.projectKey, this._storage, ) : undefined; } setKey( context: RepositoryContext, resource: Writable, { key }: ReviewSetKeyAction, ) { resource.key = key; } setLocale( context: RepositoryContext, resource: Writable, { locale }: ReviewSetLocaleAction, ) { resource.locale = locale; } setRating( context: RepositoryContext, resource: Writable, { rating }: ReviewSetRatingAction, ) { resource.rating = rating; } async setTarget( context: RepositoryContext, resource: Writable, { target }: ReviewSetTargetAction, ) { resource.target = await getReferenceFromResourceIdentifier< ProductReference | ChannelReference >(target, context.projectKey, this._storage); } setText( context: RepositoryContext, resource: Writable, { text }: ReviewSetTextAction, ) { resource.text = text; } setTitle( context: RepositoryContext, resource: Writable, { title }: ReviewSetTitleAction, ) { resource.title = title; } async transitionState( context: RepositoryContext, resource: Writable, { state }: ReviewTransitionStateAction, ) { resource.state = await getReferenceFromResourceIdentifier( state, context.projectKey, this._storage, ); } }